1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "tracepoint.h"
25 #include "expression.h"
30 #include "gdb_string.h"
32 /* readline include files */
36 /* readline defines this. */
43 extern int info_verbose
;
44 extern void (*readline_begin_hook
) PARAMS ((char *, ...));
45 extern char * (*readline_hook
) PARAMS ((char *));
46 extern void (*readline_end_hook
) PARAMS ((void));
47 extern void x_command
PARAMS ((char *, int));
49 /* If this definition isn't overridden by the header files, assume
50 that isatty and fileno exist on this system. */
52 #define ISATTY(FP) (isatty (fileno (FP)))
58 This module defines the following debugger commands:
59 trace : set a tracepoint on a function, line, or address.
60 info trace : list all debugger-defined tracepoints.
61 delete trace : delete one or more tracepoints.
62 enable trace : enable one or more tracepoints.
63 disable trace : disable one or more tracepoints.
64 actions : specify actions to be taken at a tracepoint.
65 passcount : specify a pass count for a tracepoint.
66 tstart : start a trace experiment.
67 tstop : stop a trace experiment.
68 tstatus : query the status of a trace experiment.
69 tfind : find a trace frame in the trace buffer.
70 tdump : print everything collected at the current tracepoint.
71 save-tracepoints : write tracepoint setup into a file.
73 This module defines the following user-visible debugger variables:
74 $trace_frame : sequence number of trace frame currently being debugged.
75 $trace_line : source line of trace frame currently being debugged.
76 $trace_file : source file of trace frame currently being debugged.
77 $tracepoint : tracepoint number of trace frame currently being debugged.
81 /* ======= Important global variables: ======= */
83 /* Chain of all tracepoints defined. */
84 struct tracepoint
*tracepoint_chain
;
86 /* Number of last tracepoint made. */
87 static int tracepoint_count
;
89 /* Number of last traceframe collected. */
90 static int traceframe_number
;
92 /* Tracepoint for last traceframe collected. */
93 static int tracepoint_number
;
95 /* Symbol for function for last traceframe collected */
96 static struct symbol
*traceframe_fun
;
98 /* Symtab and line for last traceframe collected */
99 static struct symtab_and_line traceframe_sal
;
101 /* Tracing command lists */
102 static struct cmd_list_element
*tfindlist
;
104 /* ======= Important command functions: ======= */
105 static void trace_command
PARAMS ((char *, int));
106 static void tracepoints_info
PARAMS ((char *, int));
107 static void delete_trace_command
PARAMS ((char *, int));
108 static void enable_trace_command
PARAMS ((char *, int));
109 static void disable_trace_command
PARAMS ((char *, int));
110 static void trace_pass_command
PARAMS ((char *, int));
111 static void trace_actions_command
PARAMS ((char *, int));
112 static void trace_start_command
PARAMS ((char *, int));
113 static void trace_stop_command
PARAMS ((char *, int));
114 static void trace_status_command
PARAMS ((char *, int));
115 static void trace_find_command
PARAMS ((char *, int));
116 static void trace_find_pc_command
PARAMS ((char *, int));
117 static void trace_find_tracepoint_command
PARAMS ((char *, int));
118 static void trace_find_line_command
PARAMS ((char *, int));
119 static void trace_find_range_command
PARAMS ((char *, int));
120 static void trace_find_outside_command
PARAMS ((char *, int));
121 static void tracepoint_save_command
PARAMS ((char *, int));
122 static void trace_dump_command
PARAMS ((char *, int));
125 /* Utility: returns true if "target remote" */
129 if (current_target
.to_shortname
&&
130 strcmp (current_target
.to_shortname
, "remote") == 0)
136 /* Utility: generate error from an incoming stub packet. */
142 return; /* not an error msg */
145 case '1': /* malformed packet error */
146 if (*++buf
== '0') /* general case: */
147 error ("tracepoint.c: error in outgoing packet.");
149 error ("tracepoint.c: error in outgoing packet at field #%d.",
150 strtol (buf
, NULL
, 16));
152 error ("trace API error 0x%s.", ++buf
);
154 error ("Target returns error code '%s'.", buf
);
158 /* Utility: wait for reply from stub, while accepting "O" packets */
160 remote_get_noisy_reply (buf
)
163 do /* loop on reply from remote stub */
167 error ("Target does not support this command.");
168 else if (buf
[0] == 'E')
170 else if (buf
[0] == 'O' &&
172 remote_console_output (buf
+ 1); /* 'O' message from stub */
174 return buf
; /* here's the actual reply */
178 /* Set tracepoint count to NUM. */
180 set_tracepoint_count (num
)
183 tracepoint_count
= num
;
184 set_internalvar (lookup_internalvar ("tpnum"),
185 value_from_longest (builtin_type_int
, (LONGEST
) num
));
188 /* Set traceframe number to NUM. */
190 set_traceframe_num (num
)
193 traceframe_number
= num
;
194 set_internalvar (lookup_internalvar ("trace_frame"),
195 value_from_longest (builtin_type_int
, (LONGEST
) num
));
198 /* Set tracepoint number to NUM. */
200 set_tracepoint_num (num
)
203 tracepoint_number
= num
;
204 set_internalvar (lookup_internalvar ("tracepoint"),
205 value_from_longest (builtin_type_int
, (LONGEST
) num
));
208 /* Set externally visible debug variables for querying/printing
209 the traceframe context (line, function, file) */
212 set_traceframe_context (trace_pc
)
215 static struct type
*func_string
, *file_string
;
216 static struct type
*func_range
, *file_range
;
217 static value_ptr func_val
, file_val
;
218 static struct type
*charstar
;
221 if (charstar
== (struct type
*) NULL
)
222 charstar
= lookup_pointer_type (builtin_type_char
);
224 if (trace_pc
== -1) /* cease debugging any trace buffers */
227 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
228 traceframe_sal
.symtab
= NULL
;
229 set_internalvar (lookup_internalvar ("trace_func"),
230 value_from_longest (charstar
, (LONGEST
) 0));
231 set_internalvar (lookup_internalvar ("trace_file"),
232 value_from_longest (charstar
, (LONGEST
) 0));
233 set_internalvar (lookup_internalvar ("trace_line"),
234 value_from_longest (builtin_type_int
, (LONGEST
) -1));
238 /* save as globals for internal use */
239 traceframe_sal
= find_pc_line (trace_pc
, 0);
240 traceframe_fun
= find_pc_function (trace_pc
);
242 /* save linenumber as "$trace_line", a debugger variable visible to users */
243 set_internalvar (lookup_internalvar ("trace_line"),
244 value_from_longest (builtin_type_int
,
245 (LONGEST
) traceframe_sal
.line
));
247 /* save func name as "$trace_func", a debugger variable visible to users */
248 if (traceframe_fun
== NULL
||
249 SYMBOL_NAME (traceframe_fun
) == NULL
)
250 set_internalvar (lookup_internalvar ("trace_func"),
251 value_from_longest (charstar
, (LONGEST
) 0));
254 len
= strlen (SYMBOL_NAME (traceframe_fun
));
255 func_range
= create_range_type (func_range
,
256 builtin_type_int
, 0, len
- 1);
257 func_string
= create_array_type (func_string
,
258 builtin_type_char
, func_range
);
259 func_val
= allocate_value (func_string
);
260 VALUE_TYPE (func_val
) = func_string
;
261 memcpy (VALUE_CONTENTS_RAW (func_val
),
262 SYMBOL_NAME (traceframe_fun
),
264 func_val
->modifiable
= 0;
265 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
268 /* save file name as "$trace_file", a debugger variable visible to users */
269 if (traceframe_sal
.symtab
== NULL
||
270 traceframe_sal
.symtab
->filename
== NULL
)
271 set_internalvar (lookup_internalvar ("trace_file"),
272 value_from_longest (charstar
, (LONGEST
) 0));
275 len
= strlen (traceframe_sal
.symtab
->filename
);
276 file_range
= create_range_type (file_range
,
277 builtin_type_int
, 0, len
- 1);
278 file_string
= create_array_type (file_string
,
279 builtin_type_char
, file_range
);
280 file_val
= allocate_value (file_string
);
281 VALUE_TYPE (file_val
) = file_string
;
282 memcpy (VALUE_CONTENTS_RAW (file_val
),
283 traceframe_sal
.symtab
->filename
,
285 file_val
->modifiable
= 0;
286 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
290 /* Low level routine to set a tracepoint.
291 Returns the tracepoint object so caller can set other things.
292 Does not set the tracepoint number!
293 Does not print anything.
295 ==> This routine should not be called if there is a chance of later
296 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
297 your arguments BEFORE calling this routine! */
299 static struct tracepoint
*
300 set_raw_tracepoint (sal
)
301 struct symtab_and_line sal
;
303 register struct tracepoint
*t
, *tc
;
304 struct cleanup
*old_chain
;
306 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
307 old_chain
= make_cleanup (free
, t
);
308 memset (t
, 0, sizeof (*t
));
310 if (sal
.symtab
== NULL
)
311 t
->source_file
= NULL
;
316 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) +
317 strlen (sal
.symtab
->dirname
) + 2);
319 strcpy (t
->source_file
, sal
.symtab
->dirname
);
323 if (*(--p
) != '/') /* Will this work on Windows? */
324 strcat (t
->source_file
, "/");
325 strcat (t
->source_file
, sal
.symtab
->filename
);
328 t
->language
= current_language
->la_language
;
329 t
->input_radix
= input_radix
;
330 t
->line_number
= sal
.line
;
331 t
->enabled
= enabled
;
335 t
->addr_string
= NULL
;
337 /* Add this tracepoint to the end of the chain
338 so that a list of tracepoints will come out in order
339 of increasing numbers. */
341 tc
= tracepoint_chain
;
343 tracepoint_chain
= t
;
350 discard_cleanups (old_chain
);
354 /* Set a tracepoint according to ARG (function, linenum or *address) */
356 trace_command (arg
, from_tty
)
360 char **canonical
= (char **)NULL
;
361 struct symtabs_and_lines sals
;
362 struct symtab_and_line sal
;
363 struct tracepoint
*t
;
364 char *addr_start
= 0, *addr_end
= 0;
368 error ("trace command requires an argument");
370 if (from_tty
&& info_verbose
)
371 printf_filtered ("TRACE %s\n", arg
);
379 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
382 return; /* ??? Presumably decode_line_1 has already warned? */
384 /* Resolve all line numbers to PC's */
385 for (i
= 0; i
< sals
.nelts
; i
++)
386 resolve_sal_pc (&sals
.sals
[i
]);
388 /* Now set all the tracepoints. */
389 for (i
= 0; i
< sals
.nelts
; i
++)
393 t
= set_raw_tracepoint (sal
);
394 set_tracepoint_count (tracepoint_count
+ 1);
395 t
->number
= tracepoint_count
;
397 /* If a canonical line spec is needed use that instead of the
399 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
400 t
->addr_string
= canonical
[i
];
402 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
404 /* Let the UI know of any additions */
405 if (create_tracepoint_hook
)
406 create_tracepoint_hook (t
);
411 printf_filtered ("Multiple tracepoints were set.\n");
412 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
416 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
419 tracepoints_info (tpnum_exp
, from_tty
)
423 struct tracepoint
*t
;
424 struct action_line
*action
;
425 int found_a_tracepoint
= 0;
426 char wrap_indent
[80];
430 char *i1
= "\t", *i2
= "\t ";
431 char *indent
, *actionline
;;
435 tpnum
= parse_and_eval_address (tpnum_exp
);
438 if (tpnum
== -1 || tpnum
== t
->number
)
440 extern int addressprint
; /* print machine addresses? */
442 if (!found_a_tracepoint
++)
444 printf_filtered ("Num Enb ");
446 printf_filtered ("Address ");
447 printf_filtered ("PassC StepC What\n");
449 strcpy (wrap_indent
, " ");
451 strcat (wrap_indent
, " ");
453 printf_filtered ("%-3d %-3s ", t
->number
,
454 t
->enabled
== enabled
? "y" : "n");
456 printf_filtered ("%s ",
457 local_hex_string_custom ((unsigned long) t
->address
,
459 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
463 sym
= find_pc_function (t
->address
);
466 fputs_filtered ("in ", gdb_stdout
);
467 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
468 wrap_here (wrap_indent
);
469 fputs_filtered (" at ", gdb_stdout
);
471 fputs_filtered (t
->source_file
, gdb_stdout
);
472 printf_filtered (":%d", t
->line_number
);
475 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
477 printf_filtered ("\n");
480 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
482 for (action
= t
->actions
; action
; action
= action
->next
)
485 actionline
= action
->action
;
486 while (isspace(*actionline
))
489 printf_filtered ("%s%s\n", indent
, actionline
);
490 if (0 == strncasecmp (actionline
, "while-stepping", 14))
492 else if (0 == strncasecmp (actionline
, "end", 3))
495 printf_filtered ("\t%s\n", action
->action
);
500 if (!found_a_tracepoint
)
503 printf_filtered ("No tracepoints.\n");
505 printf_filtered ("No tracepoint number %d.\n", tpnum
);
509 /* Optimization: the code to parse an enable, disable, or delete TP command
510 is virtually identical except for whether it performs an enable, disable,
511 or delete. Therefore I've combined them into one function with an opcode.
513 enum tracepoint_opcode
520 /* This function implements enable, disable and delete. */
522 tracepoint_operation (t
, from_tty
, opcode
)
523 struct tracepoint
*t
;
525 enum tracepoint_opcode opcode
;
527 struct tracepoint
*t2
;
528 struct action_line
*action
, *next
;
532 t
->enabled
= enabled
;
535 t
->enabled
= disabled
;
538 if (tracepoint_chain
== t
)
539 tracepoint_chain
= t
->next
;
548 /* Let the UI know of any deletions */
549 if (delete_tracepoint_hook
)
550 delete_tracepoint_hook (t
);
553 free (t
->addr_string
);
555 free (t
->source_file
);
556 for (action
= t
->actions
; action
; action
= next
)
560 free (action
->action
);
568 /* Utility: parse a tracepoint number and look it up in the list. */
570 get_tracepoint_by_number (arg
)
573 struct tracepoint
*t
;
579 error ("Bad tracepoint argument");
581 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
582 tpnum
= tracepoint_count
;
583 else if (**arg
== '$') /* handle convenience variable */
585 /* Make a copy of the name, so we can null-terminate it
586 to pass to lookup_internalvar(). */
588 while (isalnum(*end
) || *end
== '_')
590 copy
= (char *) alloca (end
- *arg
);
591 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
592 copy
[end
- *arg
- 1] = '\0';
595 val
= value_of_internalvar (lookup_internalvar (copy
));
596 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
597 error ("Convenience variable must have integral type.");
598 tpnum
= (int) value_as_long (val
);
600 else /* handle tracepoint number */
602 tpnum
= strtol (*arg
, arg
, 10);
605 if (t
->number
== tpnum
)
609 warning ("No tracepoint number %d.\n", tpnum
);
613 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
615 map_args_over_tracepoints (args
, from_tty
, opcode
)
618 enum tracepoint_opcode opcode
;
620 struct tracepoint
*t
, *tmp
;
624 if (args
== 0 || *args
== 0) /* do them all */
625 ALL_TRACEPOINTS_SAFE (t
, tmp
)
626 tracepoint_operation (t
, from_tty
, opcode
);
630 if (t
= get_tracepoint_by_number (&args
))
631 tracepoint_operation (t
, from_tty
, opcode
);
632 while (*args
== ' ' || *args
== '\t')
637 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
639 enable_trace_command (args
, from_tty
)
644 map_args_over_tracepoints (args
, from_tty
, enable
);
647 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
649 disable_trace_command (args
, from_tty
)
654 map_args_over_tracepoints (args
, from_tty
, disable
);
657 /* Remove a tracepoint (or all if no argument) */
659 delete_trace_command (args
, from_tty
)
665 if (!query ("Delete all tracepoints? "))
668 map_args_over_tracepoints (args
, from_tty
, delete);
671 /* Set passcount for tracepoint.
673 First command argument is passcount, second is tracepoint number.
674 If tracepoint number omitted, apply to most recently defined.
675 Also accepts special argument "all". */
678 trace_pass_command (args
, from_tty
)
682 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
685 if (args
== 0 || *args
== 0)
686 error ("PASS command requires an argument (count + optional TP num)");
688 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
690 while (*args
&& isspace (*args
))
693 if (*args
&& strncasecmp (args
, "all", 3) == 0)
694 args
+= 3; /* skip special argument "all" */
696 t1
= get_tracepoint_by_number (&args
);
699 return; /* error, bad tracepoint number */
702 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
704 t2
->pass_count
= count
;
706 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
711 /* ACTIONS functions: */
713 /* Prototypes for action-parsing utility commands */
714 static void read_actions
PARAMS((struct tracepoint
*));
715 static void free_actions
PARAMS((struct tracepoint
*));
716 static char *parse_and_eval_memrange
PARAMS ((char *,
722 /* The three functions:
723 collect_pseudocommand,
724 while_stepping_pseudocommand, and
725 end_actions_pseudocommand
726 are placeholders for "commands" that are actually ONLY to be used
727 within a tracepoint action list. If the actual function is ever called,
728 it means that somebody issued the "command" at the top level,
729 which is always an error. */
732 end_actions_pseudocommand (args
, from_tty
)
736 error ("This command cannot be used at the top level.");
740 while_stepping_pseudocommand (args
, from_tty
)
744 error ("This command can only be used in a tracepoint actions list.");
748 collect_pseudocommand (args
, from_tty
)
752 error ("This command can only be used in a tracepoint actions list.");
755 /* Enter a list of actions for a tracepoint. */
757 trace_actions_command (args
, from_tty
)
761 struct tracepoint
*t
;
764 char *end_msg
= "End with a line saying just \"end\".";
766 if (t
= get_tracepoint_by_number (&args
))
768 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
773 if (readline_begin_hook
)
774 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
775 else if (input_from_terminal_p ())
776 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
782 if (readline_end_hook
)
783 (*readline_end_hook
) ();
785 /* tracepoints_changed () */
787 /* else error, just return; */
798 static enum actionline_type validate_actionline
PARAMS((char *,
799 struct tracepoint
*));
801 /* worker function */
804 struct tracepoint
*t
;
807 char *prompt1
= "> ", *prompt2
= " > ";
808 char *prompt
= prompt1
;
809 enum actionline_type linetype
;
810 extern FILE *instream
;
811 struct action_line
*next
= NULL
, *temp
;
812 struct cleanup
*old_chain
;
814 /* Control-C quits instantly if typed while in this loop
815 since it should not wait until the user types a newline. */
819 signal (STOP_SIGNAL
, stop_sig
);
821 old_chain
= make_cleanup (free_actions
, (void *) t
);
824 /* Make sure that all output has been output. Some machines may let
825 you get away with leaving out some of the gdb_flush, but not all. */
827 gdb_flush (gdb_stdout
);
828 gdb_flush (gdb_stderr
);
830 if (readline_hook
&& instream
== NULL
)
831 line
= (*readline_hook
) (prompt
);
832 else if (instream
== stdin
&& ISATTY (instream
))
834 line
= readline (prompt
);
835 if (line
&& *line
) /* add it to command history */
839 line
= gdb_readline (0);
841 linetype
= validate_actionline (line
, t
);
842 if (linetype
== BADLINE
)
843 continue; /* already warned -- collect another line */
845 temp
= xmalloc (sizeof (struct action_line
));
849 if (next
== NULL
) /* first action for this tracepoint? */
850 t
->actions
= next
= temp
;
857 if (linetype
== STEPPING
) /* begin "while-stepping" */
858 if (prompt
== prompt2
)
860 warning ("Already processing 'while-stepping'");
864 prompt
= prompt2
; /* change prompt for stepping actions */
865 else if (linetype
== END
)
866 if (prompt
== prompt2
)
867 prompt
= prompt1
; /* end of single-stepping actions */
869 break; /* end of actions */
873 signal (STOP_SIGNAL
, SIG_DFL
);
876 discard_cleanups (old_chain
);
879 /* worker function */
880 static enum actionline_type
881 validate_actionline (line
, t
)
883 struct tracepoint
*t
;
885 struct cmd_list_element
*c
;
886 struct expression
*exp
;
887 value_ptr temp
, temp2
;
890 for (p
= line
; isspace (*p
); )
893 /* symbol lookup etc. */
894 if (*p
== '\0') /* empty line: just prompt for another line. */
897 if (*p
== '#') /* comment line */
900 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
903 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
907 if (c
->function
.cfunc
== collect_pseudocommand
)
909 do { /* repeat over a comma-separated list */
913 if (*p
== '$') /* look for special pseudo-symbols */
916 bfd_signed_vma offset
;
918 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
919 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
920 (0 == strncasecmp ("loc", p
+ 1, 3)))
923 else if (p
[1] == '(') /* literal memrange */
924 p
= parse_and_eval_memrange (p
, t
->address
,
925 &typecode
, &offset
, &size
);
929 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
931 if (exp
->elts
[0].opcode
!= OP_VAR_VALUE
&&
932 /*exp->elts[0].opcode != OP_LONG && */
933 /*exp->elts[0].opcode != UNOP_CAST && */
934 exp
->elts
[0].opcode
!= OP_REGISTER
)
936 warning ("collect requires a variable or register name.\n");
939 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
940 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
942 warning ("%s is constant (value %d): will not be collected.",
943 SYMBOL_NAME (exp
->elts
[2].symbol
),
944 SYMBOL_VALUE (exp
->elts
[2].symbol
));
947 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
949 warning ("%s is optimized away and cannot be collected.",
950 SYMBOL_NAME (exp
->elts
[2].symbol
));
954 } while (p
&& *p
++ == ',');
957 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
959 char *steparg
; /* in case warning is necessary */
967 t
->step_count
= strtol (p
, &p
, 0);
968 if (t
->step_count
== 0)
970 warning ("'%s' evaluates to zero -- command ignored.");
978 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
982 warning ("'%s' is not a supported tracepoint action.", line
);
987 /* worker function */
990 struct tracepoint
*t
;
992 struct action_line
*line
, *next
;
994 for (line
= t
->actions
; line
; line
= next
)
1003 int type
; /* 0 for absolute memory range, else basereg number */
1004 bfd_signed_vma start
;
1008 struct collection_list
{
1009 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1012 struct memrange
*list
;
1013 } tracepoint_list
, stepping_list
;
1015 /* MEMRANGE functions: */
1017 /* parse a memrange spec from command input */
1019 parse_and_eval_memrange (arg
, addr
, typecode
, offset
, size
)
1022 long *typecode
, *size
;
1023 bfd_signed_vma
*offset
;
1026 struct expression
*exp
;
1028 if (*arg
++ != '$' || *arg
++ != '(')
1029 error ("Internal: bad argument to validate_memrange: %s", start
);
1031 if (*arg
== '$') /* register for relative memrange? */
1033 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1034 if (exp
->elts
[0].opcode
!= OP_REGISTER
)
1035 error ("Bad register operand for memrange: %s", start
);
1037 error ("missing comma for memrange: %s", start
);
1038 *typecode
= exp
->elts
[1].longconst
;
1044 /* While attractive, this fails for a number of reasons:
1045 1) parse_and_eval_address does not deal with trailing commas,
1047 2) There is no safeguard against the user trying to use
1048 an out-of-scope variable in an address expression (for instance).
1049 2.5) If you are going to allow semi-arbitrary expressions, you
1050 would need to explain which expressions are allowed, and
1051 which are not (which would provoke endless questions).
1052 3) If you are going to allow semi-arbitrary expressions in the
1053 offset and size fields, then the leading "$" of a register
1054 name no longer disambiguates the typecode field.
1057 *offset
= parse_and_eval_address (arg
);
1058 if ((arg
= strchr (arg
, ',')) == NULL
)
1059 error ("missing comma for memrange: %s", start
);
1063 *size
= parse_and_eval_address (arg
);
1064 if ((arg
= strchr (arg
, ')')) == NULL
)
1065 error ("missing close-parenthesis for memrange: %s", start
);
1070 /* This, on the other hand, doesn't work because "-1" is an
1071 expression, not an OP_LONG! Fall back to using strtol for now. */
1073 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1074 if (exp
->elts
[0].opcode
!= OP_LONG
)
1075 error ("Bad offset operand for memrange: %s", start
);
1076 *offset
= exp
->elts
[2].longconst
;
1079 error ("missing comma for memrange: %s", start
);
1081 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1082 if (exp
->elts
[0].opcode
!= OP_LONG
)
1083 error ("Bad size operand for memrange: %s", start
);
1084 *size
= exp
->elts
[2].longconst
;
1087 error ("invalid size in memrange: %s", start
);
1090 error ("missing close-parenthesis for memrange: %s", start
);
1092 *offset
= strtol (arg
, &arg
, 0);
1094 error ("missing comma for memrange: %s", start
);
1095 *size
= strtol (arg
, &arg
, 0);
1097 error ("invalid size in memrange: %s", start
);
1099 error ("missing close-parenthesis for memrange: %s", start
);
1103 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1104 *typecode
, *offset
, *size
);
1109 /* compare memranges for qsort */
1112 struct memrange
*a
, *b
;
1114 if (a
->type
< b
->type
) return -1;
1115 if (a
->type
> b
->type
) return 1;
1118 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1119 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1123 if (a
->start
< b
->start
) return -1;
1124 if (a
->start
> b
->start
) return 1;
1129 /* Sort the memrange list using qsort, and merge adjacent memranges */
1131 memrange_sortmerge (memranges
)
1132 struct collection_list
*memranges
;
1136 qsort (memranges
->list
, memranges
->next_memrange
,
1137 sizeof (struct memrange
), memrange_cmp
);
1138 if (memranges
->next_memrange
> 0)
1140 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1142 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1143 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1144 MAX_REGISTER_VIRTUAL_SIZE
)
1146 /* memrange b starts before memrange a ends; merge them. */
1147 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1148 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1149 continue; /* next b, same a */
1153 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1154 sizeof (struct memrange
));
1156 memranges
->next_memrange
= a
+ 1;
1160 /* Add a register to a collection list */
1162 add_register (collection
, regno
)
1163 struct collection_list
*collection
;
1164 unsigned long regno
;
1167 printf_filtered ("collect register %d\n", regno
);
1168 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1169 error ("Internal: register number %d too large for tracepoint",
1171 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1174 /* Add a memrange to a collection list */
1176 add_memrange (memranges
, type
, base
, len
)
1177 struct collection_list
*memranges
;
1179 bfd_signed_vma base
;
1183 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1184 /* type: 0 == memory, n == basereg */
1185 memranges
->list
[memranges
->next_memrange
].type
= type
;
1186 /* base: addr if memory, offset if reg relative. */
1187 memranges
->list
[memranges
->next_memrange
].start
= base
;
1188 /* len: we actually save end (base + len) for convenience */
1189 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1190 memranges
->next_memrange
++;
1191 if (memranges
->next_memrange
>= memranges
->listsize
)
1193 memranges
->listsize
*= 2;
1194 memranges
->list
= xrealloc (memranges
->list
,
1195 memranges
->listsize
);
1198 if (type
!= 0) /* better collect the base register! */
1199 add_register (memranges
, type
);
1202 /* Add a symbol to a collection list */
1204 collect_symbol (collect
, sym
)
1205 struct collection_list
*collect
;
1210 bfd_signed_vma offset
;
1212 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1213 switch (SYMBOL_CLASS (sym
)) {
1215 printf_filtered ("%s: don't know symbol class %d\n",
1216 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1219 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1220 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1223 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1225 printf_filtered ("LOC_STATIC %s: collect %d bytes "
1227 SYMBOL_NAME (sym
), len
, offset
);
1228 add_memrange (collect
, 0, offset
, len
); /* 0 == memory */
1232 reg
= SYMBOL_VALUE (sym
);
1234 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1235 add_register (collect
, reg
);
1239 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1240 printf_filtered (" (will not collect %s)\n",
1243 case LOC_REGPARM_ADDR
:
1244 reg
= SYMBOL_VALUE (sym
);
1248 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1249 SYMBOL_NAME (sym
), len
, offset
, reg
);
1251 add_memrange (collect
, reg
, offset
, len
);
1255 offset
= SYMBOL_VALUE (sym
);
1259 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1260 SYMBOL_NAME (sym
), len
, offset
, reg
);
1262 add_memrange (collect
, reg
, offset
, len
);
1265 case LOC_BASEREG_ARG
:
1266 reg
= SYMBOL_BASEREG (sym
);
1267 offset
= SYMBOL_VALUE (sym
);
1270 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1271 SYMBOL_NAME (sym
), len
, offset
, reg
);
1273 add_memrange (collect
, reg
, offset
, len
);
1275 case LOC_UNRESOLVED
:
1276 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1278 case LOC_OPTIMIZED_OUT
:
1279 printf_filtered ("%s has been optimized out of existance.\n",
1285 /* Add all locals (or args) symbols to collection list */
1287 add_local_symbols (collect
, pc
, type
)
1288 struct collection_list
*collect
;
1293 struct block
*block
;
1294 int i
, nsyms
, count
= 0;
1296 block
= block_for_pc (pc
);
1299 nsyms
= BLOCK_NSYMS (block
);
1300 for (i
= 0; i
< nsyms
; i
++)
1302 sym
= BLOCK_SYM (block
, i
);
1303 switch (SYMBOL_CLASS (sym
)) {
1308 if (type
== 'L') /* collecting Locals */
1311 collect_symbol (collect
, sym
);
1318 case LOC_REGPARM_ADDR
:
1319 case LOC_BASEREG_ARG
:
1320 if (type
== 'A') /* collecting Arguments */
1323 collect_symbol (collect
, sym
);
1327 if (BLOCK_FUNCTION (block
))
1330 block
= BLOCK_SUPERBLOCK (block
);
1333 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1336 /* worker function */
1338 clear_collection_list (list
)
1339 struct collection_list
*list
;
1341 list
->next_memrange
= 0;
1342 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1345 /* reduce a collection list to string form (for gdb protocol) */
1347 stringify_collection_list (list
, string
)
1348 struct collection_list
*list
;
1354 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1355 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1357 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1360 printf_filtered ("\nCollecting registers (mask): 0x");
1365 printf_filtered ("%02X", list
->regs_mask
[i
]);
1366 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1371 printf_filtered ("\n");
1372 if (list
->next_memrange
> 0 && info_verbose
)
1373 printf_filtered ("Collecting memranges: \n");
1374 for (i
= 0; i
< list
->next_memrange
; i
++)
1377 printf_filtered ("(%d, 0x%x, %d)\n",
1379 list
->list
[i
].start
,
1380 list
->list
[i
].end
- list
->list
[i
].start
);
1381 sprintf (end
, "M%X,%X,%X",
1383 list
->list
[i
].start
,
1384 list
->list
[i
].end
- list
->list
[i
].start
);
1385 end
+= strlen (end
);
1393 /* render all actions into gdb protocol */
1395 encode_actions (t
, tdp_actions
, step_count
, stepping_actions
)
1396 struct tracepoint
*t
;
1398 unsigned long *step_count
;
1399 char **stepping_actions
;
1401 static char tdp_buff
[2048], step_buff
[2048];
1403 struct expression
*exp
;
1404 struct action_line
*action
;
1405 bfd_signed_vma offset
;
1407 struct collection_list
*collect
;
1408 struct cmd_list_element
*cmd
;
1410 clear_collection_list (&tracepoint_list
);
1411 clear_collection_list (&stepping_list
);
1412 collect
= &tracepoint_list
;
1414 *tdp_actions
= NULL
;
1415 *stepping_actions
= NULL
;
1417 for (action
= t
->actions
; action
; action
= action
->next
)
1419 action_exp
= action
->action
;
1420 while (isspace (*action_exp
))
1423 if (*action_exp
== '#') /* comment line */
1426 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1428 error ("Bad action list item: %s", action_exp
);
1430 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1432 do { /* repeat over a comma-separated list */
1433 while (isspace (*action_exp
))
1436 if (0 == strncasecmp ("$reg", action_exp
, 4))
1438 for (i
= 0; i
< NUM_REGS
; i
++)
1439 add_register (collect
, i
);
1440 action_exp
= strchr (action_exp
, ','); /* more? */
1442 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1444 add_local_symbols (collect
, t
->address
, 'A');
1445 action_exp
= strchr (action_exp
, ','); /* more? */
1447 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1449 add_local_symbols (collect
, t
->address
, 'L');
1450 action_exp
= strchr (action_exp
, ','); /* more? */
1452 else if (action_exp
[0] == '$' &&
1453 action_exp
[1] == '(') /* literal memrange */
1455 long typecode
, size
;
1456 bfd_signed_vma offset
;
1458 action_exp
= parse_and_eval_memrange (action_exp
,
1463 add_memrange (collect
, typecode
, offset
, size
);
1467 unsigned long addr
, len
;
1469 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1470 switch (exp
->elts
[0].opcode
) {
1472 i
= exp
->elts
[1].longconst
;
1474 printf_filtered ("OP_REGISTER: ");
1475 add_register (collect
, i
);
1478 collect_symbol (collect
, exp
->elts
[2].symbol
);
1482 addr
= exp
->elts
[2].longconst
;
1483 if (*action_exp
== ':')
1485 exp
= parse_exp_1 (&action_exp
,
1486 block_for_pc (t
->address
),
1488 if (exp
->elts
[0].opcode
== OP_LONG
)
1489 len
= exp
->elts
[2].longconst
;
1491 error ("length field requires a literal long const");
1496 add_memrange (collect
, 0, addr
, len
);
1501 } while (action_exp
&& *action_exp
++ == ',');
1503 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1505 collect
= &stepping_list
;
1507 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1509 if (collect
== &stepping_list
) /* end stepping actions */
1510 collect
= &tracepoint_list
;
1512 break; /* end tracepoint actions */
1515 memrange_sortmerge (&tracepoint_list
);
1516 memrange_sortmerge (&stepping_list
);
1518 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1519 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1522 static char target_buf
[2048];
1526 Tell target to lear any previous trace experiment.
1527 Walk the list of tracepoints, and send them (and their actions)
1528 to the target. If no errors,
1529 Tell target to start a new trace experiment. */
1532 trace_start_command (args
, from_tty
)
1535 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1536 struct tracepoint
*t
;
1539 char *stepping_actions
;
1540 unsigned long step_count
;
1542 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1544 if (target_is_remote ())
1547 remote_get_noisy_reply (target_buf
);
1548 if (strcmp (target_buf
, "OK"))
1549 error ("Target does not support this command.");
1553 int ss_count
; /* if actions include singlestepping */
1554 int disable_mask
; /* ??? */
1555 int enable_mask
; /* ??? */
1557 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1558 t
->enabled
== enabled
? 'E' : 'D',
1559 t
->step_count
, t
->pass_count
);
1562 encode_actions (t
, &tdp_actions
, &step_count
, &stepping_actions
);
1563 /* do_single_steps (t); */
1566 if (strlen (buf
) + strlen (tdp_actions
) >= sizeof (buf
))
1567 error ("Actions for tracepoint %d too complex; "
1568 "please simplify.", t
->number
);
1569 strcat (buf
, tdp_actions
);
1571 if (stepping_actions
)
1574 if (strlen (buf
) + strlen (stepping_actions
) >= sizeof (buf
))
1575 error ("Actions for tracepoint %d too complex; "
1576 "please simplify.", t
->number
);
1577 strcat (buf
, stepping_actions
);
1581 remote_get_noisy_reply (target_buf
);
1582 if (strcmp (target_buf
, "OK"))
1583 error ("Target does not support tracepoints.");
1586 remote_get_noisy_reply (target_buf
);
1587 if (strcmp (target_buf
, "OK"))
1588 error ("Bogus reply from target: %s", target_buf
);
1589 set_traceframe_num (-1); /* all old traceframes invalidated */
1590 set_tracepoint_num (-1);
1591 set_traceframe_context(-1);
1594 printf_filtered ("Trace can only be run on remote targets.\n");
1599 trace_stop_command (args
, from_tty
)
1602 { /* STUB_COMM IS_IMPLEMENTED */
1603 if (target_is_remote ())
1606 remote_get_noisy_reply (target_buf
);
1607 if (strcmp (target_buf
, "OK"))
1608 error ("Bogus reply from target: %s", target_buf
);
1611 error ("Trace can only be run on remote targets.");
1614 /* tstatus command */
1616 trace_status_command (args
, from_tty
)
1619 { /* STUB_COMM IS_IMPLEMENTED */
1620 if (target_is_remote ())
1622 putpkt ("qTStatus");
1623 remote_get_noisy_reply (target_buf
);
1624 if (strcmp (target_buf
, "OK"))
1625 error ("Bogus reply from target: %s", target_buf
);
1628 error ("Trace can only be run on remote targets.");
1631 /* Worker function for the various flavors of the tfind command */
1633 finish_tfind_command (msg
, from_tty
)
1637 int target_frameno
= -1, target_tracept
= -1;
1638 CORE_ADDR old_frame_addr
;
1639 struct symbol
*old_func
;
1642 old_frame_addr
= FRAME_FP (get_current_frame ());
1643 old_func
= find_pc_function (read_pc ());
1646 reply
= remote_get_noisy_reply (msg
);
1648 while (reply
&& *reply
)
1651 if ((target_frameno
= strtol (++reply
, &reply
, 16)) == -1)
1653 /* A request for a non-existant trace frame has failed.
1654 Our response will be different, depending on FROM_TTY:
1656 If FROM_TTY is true, meaning that this command was
1657 typed interactively by the user, then give an error
1658 and DO NOT change the state of traceframe_number etc.
1660 However if FROM_TTY is false, meaning that we're either
1661 in a script, a loop, or a user-defined command, then
1662 DON'T give an error, but DO change the state of
1663 traceframe_number etc. to invalid.
1665 The rationalle is that if you typed the command, you
1666 might just have committed a typo or something, and you'd
1667 like to NOT lose your current debugging state. However
1668 if you're in a user-defined command or especially in a
1669 loop, then you need a way to detect that the command
1670 failed WITHOUT aborting. This allows you to write
1671 scripts that search thru the trace buffer until the end,
1672 and then continue on to do something else. */
1675 error ("Target failed to find requested trace frame.");
1679 printf_filtered ("End of trace buffer.\n");
1680 /* The following will not recurse, since it's special-cased */
1681 trace_find_command ("-1", from_tty
);
1682 reply
= NULL
; /* break out of loop,
1683 (avoid recursive nonsense) */
1688 if ((target_tracept
= strtol (++reply
, &reply
, 16)) == -1)
1689 error ("Target failed to find requested trace frame.");
1691 case 'O': /* "OK"? */
1692 if (reply
[1] == 'K' && reply
[2] == '\0')
1695 error ("Bogus reply from target: %s", reply
);
1698 error ("Bogus reply from target: %s", reply
);
1701 flush_cached_frames ();
1702 registers_changed ();
1703 select_frame (get_current_frame (), 0);
1704 set_traceframe_num (target_frameno
);
1705 set_tracepoint_num (target_tracept
);
1706 if (target_frameno
== -1)
1707 set_traceframe_context (-1);
1709 set_traceframe_context (read_pc ());
1715 /* NOTE: in immitation of the step command, try to determine
1716 whether we have made a transition from one function to another.
1717 If so, we'll print the "stack frame" (ie. the new function and
1718 it's arguments) -- otherwise we'll just show the new source line.
1720 This determination is made by checking (1) whether the current
1721 function has changed, and (2) whether the current FP has changed.
1722 Hack: if the FP wasn't collected, either at the current or the
1723 previous frame, assume that the FP has NOT changed. */
1725 if (old_func
== find_pc_function (read_pc ()) &&
1726 (old_frame_addr
== 0 ||
1727 FRAME_FP (get_current_frame ()) == 0 ||
1728 old_frame_addr
== FRAME_FP (get_current_frame ())))
1733 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1738 /* trace_find_command takes a trace frame number n,
1739 sends "QTFrame:<n>" to the target,
1740 and accepts a reply that may contain several optional pieces
1741 of information: a frame number, a tracepoint number, and an
1742 indication of whether this is a trap frame or a stepping frame.
1744 The minimal response is just "OK" (which indicates that the
1745 target does not give us a frame number or a tracepoint number).
1746 Instead of that, the target may send us a string containing
1748 F<hexnum> (gives the selected frame number)
1749 T<hexnum> (gives the selected tracepoint number)
1754 trace_find_command (args
, from_tty
)
1757 { /* STUB_COMM PART_IMPLEMENTED */
1758 /* this should only be called with a numeric argument */
1760 int target_frameno
= -1, target_tracept
= -1, target_stepfrm
= 0;
1763 if (target_is_remote ())
1765 if (args
== 0 || *args
== 0)
1766 { /* TFIND with no args means find NEXT trace frame. */
1767 if (traceframe_number
== -1)
1768 frameno
= 0; /* "next" is first one */
1770 frameno
= traceframe_number
+ 1;
1772 else if (0 == strcmp (args
, "-"))
1774 if (traceframe_number
== -1)
1775 error ("not debugging trace buffer");
1776 else if (from_tty
&& traceframe_number
== 0)
1777 error ("already at start of trace buffer");
1779 frameno
= traceframe_number
- 1;
1782 frameno
= parse_and_eval_address (args
);
1784 sprintf (target_buf
, "QTFrame:%x", frameno
);
1786 putpkt (target_buf
);
1787 tmp
= remote_get_noisy_reply (target_buf
);
1789 if (frameno
== -1) /* end trace debugging */
1790 { /* hopefully the stub has complied! */
1791 if (0 != strcmp (tmp
, "OK"))
1792 error ("Bogus response from target: %s", tmp
);
1794 finish_tfind_command (NULL
, from_tty
);
1797 finish_tfind_command (tmp
, from_tty
);
1799 finish_tfind_command (target_buf
, from_tty
);
1803 error ("Trace can only be run on remote targets.");
1808 trace_find_end_command (args
, from_tty
)
1812 trace_find_command ("-1", from_tty
);
1817 trace_find_none_command (args
, from_tty
)
1821 trace_find_command ("-1", from_tty
);
1826 trace_find_start_command (args
, from_tty
)
1830 trace_find_command ("0", from_tty
);
1833 /* tfind pc command */
1835 trace_find_pc_command (args
, from_tty
)
1838 { /* STUB_COMM PART_IMPLEMENTED */
1843 if (target_is_remote ())
1845 if (args
== 0 || *args
== 0)
1846 pc
= read_pc (); /* default is current pc */
1848 pc
= parse_and_eval_address (args
);
1850 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
1852 putpkt (target_buf
);
1853 tmp
= remote_get_noisy_reply (target_buf
);
1855 finish_tfind_command (tmp
, from_tty
);
1857 finish_tfind_command (target_buf
, from_tty
);
1861 error ("Trace can only be run on remote targets.");
1864 /* tfind tracepoint command */
1866 trace_find_tracepoint_command (args
, from_tty
)
1869 { /* STUB_COMM PART_IMPLEMENTED */
1870 int target_frameno
, tdp
;
1873 if (target_is_remote ())
1875 if (args
== 0 || *args
== 0)
1876 if (tracepoint_number
== -1)
1877 error ("No current tracepoint -- please supply an argument.");
1879 tdp
= tracepoint_number
; /* default is current TDP */
1881 tdp
= parse_and_eval_address (args
);
1883 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
1885 putpkt (target_buf
);
1886 tmp
= remote_get_noisy_reply (target_buf
);
1888 finish_tfind_command (tmp
, from_tty
);
1890 finish_tfind_command (target_buf
, from_tty
);
1894 error ("Trace can only be run on remote targets.");
1897 /* TFIND LINE command:
1899 This command will take a sourceline for argument, just like BREAK
1900 or TRACE (ie. anything that "decode_line_1" can handle).
1902 With no argument, this command will find the next trace frame
1903 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1906 trace_find_line_command (args
, from_tty
)
1909 { /* STUB_COMM PART_IMPLEMENTED */
1910 static CORE_ADDR start_pc
, end_pc
;
1911 struct symtabs_and_lines sals
;
1912 struct symtab_and_line sal
;
1915 struct cleanup
*old_chain
;
1917 if (target_is_remote ())
1919 if (args
== 0 || *args
== 0)
1921 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
1923 sals
.sals
= (struct symtab_and_line
*)
1924 xmalloc (sizeof (struct symtab_and_line
));
1929 sals
= decode_line_spec (args
, 1);
1933 old_chain
= make_cleanup (free
, sals
.sals
);
1934 if (sal
.symtab
== 0)
1936 printf_filtered ("TFIND: No line number information available");
1939 /* This is useful for "info line *0x7f34". If we can't tell the
1940 user about a source line, at least let them have the symbolic
1942 printf_filtered (" for address ");
1944 print_address (sal
.pc
, gdb_stdout
);
1945 printf_filtered (";\n -- will attempt to find by PC. \n");
1949 printf_filtered (".\n");
1950 return; /* no line, no PC; what can we do? */
1953 else if (sal
.line
> 0
1954 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
1956 if (start_pc
== end_pc
)
1958 printf_filtered ("Line %d of \"%s\"",
1959 sal
.line
, sal
.symtab
->filename
);
1961 printf_filtered (" is at address ");
1962 print_address (start_pc
, gdb_stdout
);
1964 printf_filtered (" but contains no code.\n");
1965 sal
= find_pc_line (start_pc
, 0);
1967 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
1969 printf_filtered ("Attempting to find line %d instead.\n",
1972 error ("Cannot find a good line.");
1976 /* Is there any case in which we get here, and have an address
1977 which the user would want to see? If we have debugging symbols
1978 and no line numbers? */
1979 error ("Line number %d is out of range for \"%s\".\n",
1980 sal
.line
, sal
.symtab
->filename
);
1982 if (args
&& *args
) /* find within range of stated line */
1983 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
1984 else /* find OUTSIDE OF range of CURRENT line */
1985 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
1987 putpkt (target_buf
);
1988 tmp
= remote_get_noisy_reply (target_buf
);
1990 finish_tfind_command (tmp
, from_tty
);
1992 finish_tfind_command (target_buf
, from_tty
);
1994 do_cleanups (old_chain
);
1997 error ("Trace can only be run on remote targets.");
2000 /* tfind range command */
2002 trace_find_range_command (args
, from_tty
)
2005 { /* STUB_COMM PART_IMPLEMENTED */
2006 static CORE_ADDR start
, stop
;
2010 if (target_is_remote ())
2012 if (args
== 0 || *args
== 0)
2013 { /* XXX FIXME: what should default behavior be? */
2014 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2018 if (0 != (tmp
= strchr (args
, ',' )))
2020 *tmp
++ = '\0'; /* terminate start address */
2021 while (isspace (*tmp
))
2023 start
= parse_and_eval_address (args
);
2024 stop
= parse_and_eval_address (tmp
);
2027 { /* no explicit end address? */
2028 start
= parse_and_eval_address (args
);
2029 stop
= start
+ 1; /* ??? */
2032 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2034 putpkt (target_buf
);
2035 tmp
= remote_get_noisy_reply (target_buf
);
2037 finish_tfind_command (tmp
, from_tty
);
2039 finish_tfind_command (target_buf
, from_tty
);
2043 error ("Trace can only be run on remote targets.");
2046 /* tfind outside command */
2048 trace_find_outside_command (args
, from_tty
)
2051 { /* STUB_COMM PART_IMPLEMENTED */
2052 CORE_ADDR start
, stop
;
2056 if (target_is_remote ())
2058 if (args
== 0 || *args
== 0)
2059 { /* XXX FIXME: what should default behavior be? */
2060 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2064 if (0 != (tmp
= strchr (args
, ',' )))
2066 *tmp
++ = '\0'; /* terminate start address */
2067 while (isspace (*tmp
))
2069 start
= parse_and_eval_address (args
);
2070 stop
= parse_and_eval_address (tmp
);
2073 { /* no explicit end address? */
2074 start
= parse_and_eval_address (args
);
2075 stop
= start
+ 1; /* ??? */
2078 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2080 putpkt (target_buf
);
2081 tmp
= remote_get_noisy_reply (target_buf
);
2083 finish_tfind_command (tmp
, from_tty
);
2085 finish_tfind_command (target_buf
, from_tty
);
2089 error ("Trace can only be run on remote targets.");
2092 /* save-tracepoints command */
2094 tracepoint_save_command (args
, from_tty
)
2098 struct tracepoint
*tp
;
2099 struct action_line
*line
;
2101 char *i1
= " ", *i2
= " ";
2102 char *indent
, *actionline
;
2104 if (args
== 0 || *args
== 0)
2105 error ("Argument required (file name in which to save tracepoints");
2107 if (tracepoint_chain
== 0)
2109 warning ("save-tracepoints: no tracepoints to save.\n");
2113 if (!(fp
= fopen (args
, "w")))
2114 error ("Unable to open file '%s' for saving tracepoints");
2116 ALL_TRACEPOINTS (tp
)
2118 if (tp
->addr_string
)
2119 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2121 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2124 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2128 fprintf (fp
, " actions\n");
2130 for (line
= tp
->actions
; line
; line
= line
->next
)
2132 struct cmd_list_element
*cmd
;
2134 actionline
= line
->action
;
2135 while (isspace(*actionline
))
2138 fprintf (fp
, "%s%s\n", indent
, actionline
);
2139 if (*actionline
!= '#') /* skip for comment lines */
2141 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2143 error ("Bad action list item: %s", actionline
);
2144 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2146 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2154 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2158 /* info scope command: list the locals for a scope. */
2160 scope_info (args
, from_tty
)
2164 struct symtab_and_line sal
;
2165 struct symtabs_and_lines sals
;
2167 struct minimal_symbol
*msym
;
2168 struct block
*block
;
2169 char **canonical
, *symname
, *save_args
= args
;
2170 int i
, nsyms
, count
= 0;
2172 if (args
== 0 || *args
== 0)
2173 error ("requires an argument (function, line or *addr) to define a scope");
2175 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2176 if (sals
.nelts
== 0)
2177 return; /* presumably decode_line_1 has already warned */
2179 /* Resolve line numbers to PC */
2180 resolve_sal_pc (&sals
.sals
[0]);
2181 block
= block_for_pc (sals
.sals
[0].pc
);
2185 nsyms
= BLOCK_NSYMS (block
);
2186 for (i
= 0; i
< nsyms
; i
++)
2189 printf_filtered ("Scope for %s:\n", save_args
);
2191 sym
= BLOCK_SYM (block
, i
);
2192 symname
= SYMBOL_NAME (sym
);
2193 if (symname
== NULL
|| *symname
== '\0')
2194 continue; /* probably botched, certainly useless */
2196 printf_filtered ("Symbol %s is ", symname
);
2197 switch (SYMBOL_CLASS (sym
)) {
2199 case LOC_UNDEF
: /* messed up symbol? */
2200 printf_filtered ("a bogus symbol, class %d.\n",
2201 SYMBOL_CLASS (sym
));
2202 count
--; /* don't count this one */
2205 printf_filtered ("a constant with value %d (0x%x)",
2206 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2208 case LOC_CONST_BYTES
:
2209 printf_filtered ("constant bytes: ");
2210 if (SYMBOL_TYPE (sym
))
2211 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2212 fprintf_filtered (gdb_stdout
, " %02x",
2213 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2216 printf_filtered ("in static storage at address ");
2217 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2220 printf_filtered ("a local variable in register $%s",
2221 reg_names
[SYMBOL_VALUE (sym
)]);
2225 printf_filtered ("an argument at stack/frame offset %ld",
2226 SYMBOL_VALUE (sym
));
2229 printf_filtered ("a local variable at frame offset %ld",
2230 SYMBOL_VALUE (sym
));
2233 printf_filtered ("a reference argument at offset %ld",
2234 SYMBOL_VALUE (sym
));
2237 printf_filtered ("an argument in register $%s",
2238 reg_names
[SYMBOL_VALUE (sym
)]);
2240 case LOC_REGPARM_ADDR
:
2241 printf_filtered ("the address of an argument, in register $%s",
2242 reg_names
[SYMBOL_VALUE (sym
)]);
2245 printf_filtered ("a typedef.\n");
2248 printf_filtered ("a label at address ");
2249 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2252 printf_filtered ("a function at address ");
2253 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2257 printf_filtered ("a variable at offset %d from register $%s",
2259 reg_names
[SYMBOL_BASEREG (sym
)]);
2261 case LOC_BASEREG_ARG
:
2262 printf_filtered ("an argument at offset %d from register $%s",
2264 reg_names
[SYMBOL_BASEREG (sym
)]);
2266 case LOC_UNRESOLVED
:
2267 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2269 printf_filtered ("Unresolved Static");
2272 printf_filtered ("static storage at address ");
2273 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2277 case LOC_OPTIMIZED_OUT
:
2278 printf_filtered ("optimized out.\n");
2281 if (SYMBOL_TYPE (sym
))
2282 printf_filtered (", length %d.\n",
2283 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2285 if (BLOCK_FUNCTION (block
))
2288 block
= BLOCK_SUPERBLOCK (block
);
2291 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2295 /* worker function (cleanup) */
2297 replace_comma (comma
)
2305 trace_dump_command (args
, from_tty
)
2309 struct tracepoint
*t
;
2310 struct action_line
*action
;
2311 char *action_exp
, *next_comma
;
2312 struct cleanup
*old_cleanups
;
2313 int stepping_actions
= 0;
2314 int stepping_frame
= 0;
2316 if (tracepoint_number
== -1)
2318 warning ("No current trace frame.");
2323 if (t
->number
== tracepoint_number
)
2327 error ("No known tracepoint matches 'current' tracepoint #%d.",
2330 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2332 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2333 tracepoint_number
, traceframe_number
);
2335 /* The current frame is a trap frame if the frame PC is equal
2336 to the tracepoint PC. If not, then the current frame was
2337 collected during single-stepping. */
2339 stepping_frame
= (t
->address
!= read_pc());
2341 for (action
= t
->actions
; action
; action
= action
->next
)
2343 struct cmd_list_element
*cmd
;
2345 action_exp
= action
->action
;
2346 while (isspace (*action_exp
))
2349 /* The collection actions to be done while stepping are
2350 bracketed by the commands "while-stepping" and "end". */
2352 if (*action_exp
== '#') /* comment line */
2355 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2357 error ("Bad action list item: %s", action_exp
);
2359 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2360 stepping_actions
= 1;
2361 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2362 stepping_actions
= 0;
2363 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2365 /* Display the collected data.
2366 For the trap frame, display only what was collected at the trap.
2367 Likewise for stepping frames, display only what was collected
2368 while stepping. This means that the two boolean variables,
2369 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2370 if (stepping_frame
== stepping_actions
)
2372 do { /* repeat over a comma-separated list */
2374 if (*action_exp
== ',')
2376 while (isspace (*action_exp
))
2379 next_comma
= strchr (action_exp
, ',');
2381 if (0 == strncasecmp (action_exp
, "$reg", 4))
2382 registers_info (NULL
, from_tty
);
2383 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2384 locals_info (NULL
, from_tty
);
2385 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2386 args_info (NULL
, from_tty
);
2387 else if (action_exp
[0] == '$' && action_exp
[1] == '(')
2389 long typecode
, size
;
2390 bfd_signed_vma offset
;
2393 action_exp
= parse_and_eval_memrange (action_exp
,
2398 if (typecode
!= 0 && typecode
!= -1)
2399 offset
+= read_register (typecode
);
2400 sprintf (fmt
, "/%dxb 0x%x", size
, offset
);
2401 x_command (fmt
, from_tty
);
2402 next_comma
= strchr (action_exp
, ',');
2408 make_cleanup (replace_comma
, next_comma
);
2411 printf_filtered ("%s = ", action_exp
);
2412 output_command (action_exp
, from_tty
);
2413 printf_filtered ("\n");
2417 action_exp
= next_comma
;
2418 } while (action_exp
&& *action_exp
== ',');
2422 discard_cleanups (old_cleanups
);
2425 /* module initialization */
2427 _initialize_tracepoint ()
2429 tracepoint_chain
= 0;
2430 tracepoint_count
= 0;
2431 traceframe_number
= -1;
2432 tracepoint_number
= -1;
2434 set_internalvar (lookup_internalvar ("tpnum"),
2435 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2436 set_internalvar (lookup_internalvar ("trace_frame"),
2437 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2439 if (tracepoint_list
.list
== NULL
)
2441 tracepoint_list
.listsize
= 128;
2442 tracepoint_list
.list
= xmalloc
2443 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2445 if (stepping_list
.list
== NULL
)
2447 stepping_list
.listsize
= 128;
2448 stepping_list
.list
= xmalloc
2449 (stepping_list
.listsize
* sizeof (struct memrange
));
2452 add_info ("scope", scope_info
,
2453 "List the variables local to a scope");
2455 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2456 "Tracing of program execution without stopping the program.",
2459 add_info ("tracepoints", tracepoints_info
,
2460 "Status of tracepoints, or tracepoint number NUMBER.\n\
2461 Convenience variable \"$tpnum\" contains the number of the\n\
2462 last tracepoint set.");
2464 add_info_alias ("tp", "tracepoints", 1);
2466 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2467 "Save current tracepoint definitions as a script.\n\
2468 Use the 'source' command in another debug session to restore them.");
2470 add_com ("tdump", class_trace
, trace_dump_command
,
2471 "Print everything collected at the current tracepoint.");
2473 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2474 "Select a trace frame;\n\
2475 No argument means forward by one frame; '-' meand backward by one frame.",
2476 &tfindlist
, "tfind ", 1, &cmdlist
);
2478 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2479 "Select a trace frame whose PC is outside the given \
2480 range.\nUsage: tfind outside addr1, addr2",
2483 add_cmd ("range", class_trace
, trace_find_range_command
,
2484 "Select a trace frame whose PC is in the given range.\n\
2485 Usage: tfind range addr1,addr2",
2488 add_cmd ("line", class_trace
, trace_find_line_command
,
2489 "Select a trace frame by source line.\n\
2490 Argument can be a line number (with optional source file), \n\
2491 a function name, or '*' followed by an address.\n\
2492 Default argument is 'the next source line that was traced'.",
2495 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2496 "Select a trace frame by tracepoint number.\n\
2497 Default is the tracepoint for the current trace frame.",
2500 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2501 "Select a trace frame by PC.\n\
2502 Default is the current PC, or the PC of the current trace frame.",
2505 add_cmd ("end", class_trace
, trace_find_end_command
,
2506 "Synonym for 'none'.\n\
2507 De-select any trace frame and resume 'live' debugging.",
2510 add_cmd ("none", class_trace
, trace_find_none_command
,
2511 "De-select any trace frame and resume 'live' debugging.",
2514 add_cmd ("start", class_trace
, trace_find_start_command
,
2515 "Select the first trace frame in the trace buffer.",
2518 add_com ("tstatus", class_trace
, trace_status_command
,
2519 "Display the status of the current trace data collection.");
2521 add_com ("tstop", class_trace
, trace_stop_command
,
2522 "Stop trace data collection.");
2524 add_com ("tstart", class_trace
, trace_start_command
,
2525 "Start trace data collection.");
2527 add_com ("passcount", class_trace
, trace_pass_command
,
2528 "Set the passcount for a tracepoint.\n\
2529 The trace will end when the tracepoint has been passed 'count' times.\n\
2530 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2531 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2533 add_com ("end", class_trace
, end_actions_pseudocommand
,
2534 "Ends a list of commands or actions.\n\
2535 Several GDB commands allow you to enter a list of commands or actions.\n\
2536 Entering \"end\" on a line by itself is the normal way to terminate\n\
2538 Note: the \"end\" command cannot be used at the gdb prompt.");
2540 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2541 "Specify single-stepping behavior at a tracepoint.\n\
2542 Argument is number of instructions to trace in single-step mode\n\
2543 following the tracepoint. This command is normally followed by\n\
2544 one or more \"collect\" commands, to specify what to collect\n\
2545 while single-stepping.\n\n\
2546 Note: this command can only be used in a tracepoint \"actions\" list.");
2548 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2549 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2551 add_com ("collect", class_trace
, collect_pseudocommand
,
2552 "Specify one or more data items to be collected at a tracepoint.\n\
2553 Accepts a comma-separated list of (one or more) arguments.\n\
2554 Things that may be collected include registers, variables, plus\n\
2555 the following special arguments:\n\
2556 $regs -- all registers.\n\
2557 $args -- all function arguments.\n\
2558 $locals -- all variables local to the block/function scope.\n\
2559 $(addr,len) -- a literal memory range.\n\
2560 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2561 Note: this command can only be used in a tracepoint \"actions\" list.");
2563 add_com ("actions", class_trace
, trace_actions_command
,
2564 "Specify the actions to be taken at a tracepoint.\n\
2565 Tracepoint actions may include collecting of specified data, \n\
2566 single-stepping, or enabling/disabling other tracepoints, \n\
2567 depending on target's capabilities.");
2569 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2570 "Delete specified tracepoints.\n\
2571 Arguments are tracepoint numbers, separated by spaces.\n\
2572 No argument means delete all tracepoints.",
2575 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2576 "Disable specified tracepoints.\n\
2577 Arguments are tracepoint numbers, separated by spaces.\n\
2578 No argument means disable all tracepoints.",
2581 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2582 "Enable specified tracepoints.\n\
2583 Arguments are tracepoint numbers, separated by spaces.\n\
2584 No argument means enable all tracepoints.",
2587 add_com ("trace", class_trace
, trace_command
,
2588 "Set a tracepoint at a specified line or function or address.\n\
2589 Argument may be a line number, function name, or '*' plus an address.\n\
2590 For a line number or function, trace at the start of its code.\n\
2591 If an address is specified, trace at that exact address.\n\n\
2592 Do \"help tracepoints\" for info on other tracepoint commands.");
2594 add_com_alias ("tp", "trace", class_alias
, 0);
2595 add_com_alias ("tr", "trace", class_alias
, 1);
2596 add_com_alias ("tra", "trace", class_alias
, 1);
2597 add_com_alias ("trac", "trace", class_alias
, 1);