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"
35 /* readline include files */
39 /* readline defines this. */
46 /* maximum length of an agent aexpression.
47 this accounts for the fact that packets are limited to 400 bytes
48 (which includes everything -- including the checksum), and assumes
49 the worst case of maximum length for each of the pieces of a
52 NOTE: expressions get mem2hex'ed otherwise this would be twice as
53 large. (400 - 31)/2 == 184 */
54 #define MAX_AGENT_EXPR_LEN 184
57 extern int info_verbose
;
58 extern void (*readline_begin_hook
) PARAMS ((char *, ...));
59 extern char * (*readline_hook
) PARAMS ((char *));
60 extern void (*readline_end_hook
) PARAMS ((void));
61 extern void x_command
PARAMS ((char *, int));
62 extern int addressprint
; /* Print machine addresses? */
64 /* If this definition isn't overridden by the header files, assume
65 that isatty and fileno exist on this system. */
67 #define ISATTY(FP) (isatty (fileno (FP)))
73 This module defines the following debugger commands:
74 trace : set a tracepoint on a function, line, or address.
75 info trace : list all debugger-defined tracepoints.
76 delete trace : delete one or more tracepoints.
77 enable trace : enable one or more tracepoints.
78 disable trace : disable one or more tracepoints.
79 actions : specify actions to be taken at a tracepoint.
80 passcount : specify a pass count for a tracepoint.
81 tstart : start a trace experiment.
82 tstop : stop a trace experiment.
83 tstatus : query the status of a trace experiment.
84 tfind : find a trace frame in the trace buffer.
85 tdump : print everything collected at the current tracepoint.
86 save-tracepoints : write tracepoint setup into a file.
88 This module defines the following user-visible debugger variables:
89 $trace_frame : sequence number of trace frame currently being debugged.
90 $trace_line : source line of trace frame currently being debugged.
91 $trace_file : source file of trace frame currently being debugged.
92 $tracepoint : tracepoint number of trace frame currently being debugged.
96 /* ======= Important global variables: ======= */
98 /* Chain of all tracepoints defined. */
99 struct tracepoint
*tracepoint_chain
;
101 /* Number of last tracepoint made. */
102 static int tracepoint_count
;
104 /* Number of last traceframe collected. */
105 static int traceframe_number
;
107 /* Tracepoint for last traceframe collected. */
108 static int tracepoint_number
;
110 /* Symbol for function for last traceframe collected */
111 static struct symbol
*traceframe_fun
;
113 /* Symtab and line for last traceframe collected */
114 static struct symtab_and_line traceframe_sal
;
116 /* Tracing command lists */
117 static struct cmd_list_element
*tfindlist
;
119 /* ======= Important command functions: ======= */
120 static void trace_command
PARAMS ((char *, int));
121 static void tracepoints_info
PARAMS ((char *, int));
122 static void delete_trace_command
PARAMS ((char *, int));
123 static void enable_trace_command
PARAMS ((char *, int));
124 static void disable_trace_command
PARAMS ((char *, int));
125 static void trace_pass_command
PARAMS ((char *, int));
126 static void trace_actions_command
PARAMS ((char *, int));
127 static void trace_start_command
PARAMS ((char *, int));
128 static void trace_stop_command
PARAMS ((char *, int));
129 static void trace_status_command
PARAMS ((char *, int));
130 static void trace_find_command
PARAMS ((char *, int));
131 static void trace_find_pc_command
PARAMS ((char *, int));
132 static void trace_find_tracepoint_command
PARAMS ((char *, int));
133 static void trace_find_line_command
PARAMS ((char *, int));
134 static void trace_find_range_command
PARAMS ((char *, int));
135 static void trace_find_outside_command
PARAMS ((char *, int));
136 static void tracepoint_save_command
PARAMS ((char *, int));
137 static void trace_dump_command
PARAMS ((char *, int));
139 /* support routines */
140 static void trace_mention
PARAMS ((struct tracepoint
*));
142 struct collection_list
;
143 static void add_aexpr
PARAMS ((struct collection_list
*, struct agent_expr
*));
144 static unsigned char *mem2hex(unsigned char *, unsigned char *, int);
146 /* Utility: returns true if "target remote" */
150 if (current_target
.to_shortname
&&
151 strcmp (current_target
.to_shortname
, "remote") == 0)
157 /* Utility: generate error from an incoming stub packet. */
163 return; /* not an error msg */
166 case '1': /* malformed packet error */
167 if (*++buf
== '0') /* general case: */
168 error ("tracepoint.c: error in outgoing packet.");
170 error ("tracepoint.c: error in outgoing packet at field #%d.",
171 strtol (buf
, NULL
, 16));
173 error ("trace API error 0x%s.", ++buf
);
175 error ("Target returns error code '%s'.", buf
);
179 /* Utility: wait for reply from stub, while accepting "O" packets */
181 remote_get_noisy_reply (buf
)
184 do /* loop on reply from remote stub */
186 QUIT
; /* allow user to bail out with ^C */
189 error ("Target does not support this command.");
190 else if (buf
[0] == 'E')
192 else if (buf
[0] == 'O' &&
194 remote_console_output (buf
+ 1); /* 'O' message from stub */
196 return buf
; /* here's the actual reply */
200 /* Set tracepoint count to NUM. */
202 set_tracepoint_count (num
)
205 tracepoint_count
= num
;
206 set_internalvar (lookup_internalvar ("tpnum"),
207 value_from_longest (builtin_type_int
, (LONGEST
) num
));
210 /* Set traceframe number to NUM. */
212 set_traceframe_num (num
)
215 traceframe_number
= num
;
216 set_internalvar (lookup_internalvar ("trace_frame"),
217 value_from_longest (builtin_type_int
, (LONGEST
) num
));
220 /* Set tracepoint number to NUM. */
222 set_tracepoint_num (num
)
225 tracepoint_number
= num
;
226 set_internalvar (lookup_internalvar ("tracepoint"),
227 value_from_longest (builtin_type_int
, (LONGEST
) num
));
230 /* Set externally visible debug variables for querying/printing
231 the traceframe context (line, function, file) */
234 set_traceframe_context (trace_pc
)
237 static struct type
*func_string
, *file_string
;
238 static struct type
*func_range
, *file_range
;
239 static value_ptr func_val
, file_val
;
240 static struct type
*charstar
;
243 if (charstar
== (struct type
*) NULL
)
244 charstar
= lookup_pointer_type (builtin_type_char
);
246 if (trace_pc
== -1) /* cease debugging any trace buffers */
249 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
250 traceframe_sal
.symtab
= NULL
;
251 set_internalvar (lookup_internalvar ("trace_func"),
252 value_from_longest (charstar
, (LONGEST
) 0));
253 set_internalvar (lookup_internalvar ("trace_file"),
254 value_from_longest (charstar
, (LONGEST
) 0));
255 set_internalvar (lookup_internalvar ("trace_line"),
256 value_from_longest (builtin_type_int
, (LONGEST
) -1));
260 /* save as globals for internal use */
261 traceframe_sal
= find_pc_line (trace_pc
, 0);
262 traceframe_fun
= find_pc_function (trace_pc
);
264 /* save linenumber as "$trace_line", a debugger variable visible to users */
265 set_internalvar (lookup_internalvar ("trace_line"),
266 value_from_longest (builtin_type_int
,
267 (LONGEST
) traceframe_sal
.line
));
269 /* save func name as "$trace_func", a debugger variable visible to users */
270 if (traceframe_fun
== NULL
||
271 SYMBOL_NAME (traceframe_fun
) == NULL
)
272 set_internalvar (lookup_internalvar ("trace_func"),
273 value_from_longest (charstar
, (LONGEST
) 0));
276 len
= strlen (SYMBOL_NAME (traceframe_fun
));
277 func_range
= create_range_type (func_range
,
278 builtin_type_int
, 0, len
- 1);
279 func_string
= create_array_type (func_string
,
280 builtin_type_char
, func_range
);
281 func_val
= allocate_value (func_string
);
282 VALUE_TYPE (func_val
) = func_string
;
283 memcpy (VALUE_CONTENTS_RAW (func_val
),
284 SYMBOL_NAME (traceframe_fun
),
286 func_val
->modifiable
= 0;
287 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
290 /* save file name as "$trace_file", a debugger variable visible to users */
291 if (traceframe_sal
.symtab
== NULL
||
292 traceframe_sal
.symtab
->filename
== NULL
)
293 set_internalvar (lookup_internalvar ("trace_file"),
294 value_from_longest (charstar
, (LONGEST
) 0));
297 len
= strlen (traceframe_sal
.symtab
->filename
);
298 file_range
= create_range_type (file_range
,
299 builtin_type_int
, 0, len
- 1);
300 file_string
= create_array_type (file_string
,
301 builtin_type_char
, file_range
);
302 file_val
= allocate_value (file_string
);
303 VALUE_TYPE (file_val
) = file_string
;
304 memcpy (VALUE_CONTENTS_RAW (file_val
),
305 traceframe_sal
.symtab
->filename
,
307 file_val
->modifiable
= 0;
308 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
312 /* Low level routine to set a tracepoint.
313 Returns the tracepoint object so caller can set other things.
314 Does not set the tracepoint number!
315 Does not print anything.
317 ==> This routine should not be called if there is a chance of later
318 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
319 your arguments BEFORE calling this routine! */
321 static struct tracepoint
*
322 set_raw_tracepoint (sal
)
323 struct symtab_and_line sal
;
325 register struct tracepoint
*t
, *tc
;
326 struct cleanup
*old_chain
;
328 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
329 old_chain
= make_cleanup (free
, t
);
330 memset (t
, 0, sizeof (*t
));
332 if (sal
.symtab
== NULL
)
333 t
->source_file
= NULL
;
336 if (sal
.symtab
->dirname
== NULL
)
338 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) + 1);
339 strcpy (t
->source_file
, sal
.symtab
->filename
);
345 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) +
346 strlen (sal
.symtab
->dirname
) + 2);
348 strcpy (t
->source_file
, sal
.symtab
->dirname
);
352 if (*(--p
) != '/') /* Will this work on Windows? */
353 strcat (t
->source_file
, "/");
354 strcat (t
->source_file
, sal
.symtab
->filename
);
358 t
->language
= current_language
->la_language
;
359 t
->input_radix
= input_radix
;
360 t
->line_number
= sal
.line
;
361 t
->enabled
= enabled
;
365 t
->addr_string
= NULL
;
367 /* Add this tracepoint to the end of the chain
368 so that a list of tracepoints will come out in order
369 of increasing numbers. */
371 tc
= tracepoint_chain
;
373 tracepoint_chain
= t
;
380 discard_cleanups (old_chain
);
384 /* Set a tracepoint according to ARG (function, linenum or *address) */
386 trace_command (arg
, from_tty
)
390 char **canonical
= (char **)NULL
;
391 struct symtabs_and_lines sals
;
392 struct symtab_and_line sal
;
393 struct tracepoint
*t
;
394 char *addr_start
= 0, *addr_end
= 0;
398 error ("trace command requires an argument");
400 if (from_tty
&& info_verbose
)
401 printf_filtered ("TRACE %s\n", arg
);
404 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
407 return; /* ??? Presumably decode_line_1 has already warned? */
409 /* Resolve all line numbers to PC's */
410 for (i
= 0; i
< sals
.nelts
; i
++)
411 resolve_sal_pc (&sals
.sals
[i
]);
413 /* Now set all the tracepoints. */
414 for (i
= 0; i
< sals
.nelts
; i
++)
418 t
= set_raw_tracepoint (sal
);
419 set_tracepoint_count (tracepoint_count
+ 1);
420 t
->number
= tracepoint_count
;
422 /* If a canonical line spec is needed use that instead of the
424 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
425 t
->addr_string
= canonical
[i
];
427 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
431 /* Let the UI know of any additions */
432 if (create_tracepoint_hook
)
433 create_tracepoint_hook (t
);
438 printf_filtered ("Multiple tracepoints were set.\n");
439 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
443 /* Tell the user we have just set a tracepoint TP. */
447 struct tracepoint
*tp
;
449 printf_filtered ("Tracepoint %d", tp
->number
);
451 if (addressprint
|| (tp
->source_file
== NULL
))
453 printf_filtered (" at ");
454 print_address_numeric (tp
->address
, 1, gdb_stdout
);
457 printf_filtered (": file %s, line %d.",
458 tp
->source_file
, tp
->line_number
);
460 printf_filtered ("\n");
463 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
466 tracepoints_info (tpnum_exp
, from_tty
)
470 struct tracepoint
*t
;
471 struct action_line
*action
;
472 int found_a_tracepoint
= 0;
473 char wrap_indent
[80];
478 tpnum
= parse_and_eval_address (tpnum_exp
);
481 if (tpnum
== -1 || tpnum
== t
->number
)
483 extern int addressprint
; /* print machine addresses? */
485 if (!found_a_tracepoint
++)
487 printf_filtered ("Num Enb ");
489 printf_filtered ("Address ");
490 printf_filtered ("PassC StepC What\n");
492 strcpy (wrap_indent
, " ");
494 strcat (wrap_indent
, " ");
496 printf_filtered ("%-3d %-3s ", t
->number
,
497 t
->enabled
== enabled
? "y" : "n");
499 printf_filtered ("%s ",
500 local_hex_string_custom ((unsigned long) t
->address
,
502 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
506 sym
= find_pc_function (t
->address
);
509 fputs_filtered ("in ", gdb_stdout
);
510 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
511 wrap_here (wrap_indent
);
512 fputs_filtered (" at ", gdb_stdout
);
514 fputs_filtered (t
->source_file
, gdb_stdout
);
515 printf_filtered (":%d", t
->line_number
);
518 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
520 printf_filtered ("\n");
523 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
524 for (action
= t
->actions
; action
; action
= action
->next
)
526 printf_filtered ("\t%s\n", action
->action
);
530 if (!found_a_tracepoint
)
533 printf_filtered ("No tracepoints.\n");
535 printf_filtered ("No tracepoint number %d.\n", tpnum
);
539 /* Optimization: the code to parse an enable, disable, or delete TP command
540 is virtually identical except for whether it performs an enable, disable,
541 or delete. Therefore I've combined them into one function with an opcode.
543 enum tracepoint_opcode
550 /* This function implements enable, disable and delete. */
552 tracepoint_operation (t
, from_tty
, opcode
)
553 struct tracepoint
*t
;
555 enum tracepoint_opcode opcode
;
557 struct tracepoint
*t2
;
561 t
->enabled
= enabled
;
562 if (modify_tracepoint_hook
)
563 modify_tracepoint_hook (t
);
566 t
->enabled
= disabled
;
567 if (modify_tracepoint_hook
)
568 modify_tracepoint_hook (t
);
571 if (tracepoint_chain
== t
)
572 tracepoint_chain
= t
->next
;
581 /* Let the UI know of any deletions */
582 if (delete_tracepoint_hook
)
583 delete_tracepoint_hook (t
);
586 free (t
->addr_string
);
588 free (t
->source_file
);
597 /* Utility: parse a tracepoint number and look it up in the list. */
599 get_tracepoint_by_number (arg
)
602 struct tracepoint
*t
;
608 error ("Bad tracepoint argument");
610 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
611 tpnum
= tracepoint_count
;
612 else if (**arg
== '$') /* handle convenience variable */
614 /* Make a copy of the name, so we can null-terminate it
615 to pass to lookup_internalvar(). */
617 while (isalnum(*end
) || *end
== '_')
619 copy
= (char *) alloca (end
- *arg
);
620 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
621 copy
[end
- *arg
- 1] = '\0';
624 val
= value_of_internalvar (lookup_internalvar (copy
));
625 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
626 error ("Convenience variable must have integral type.");
627 tpnum
= (int) value_as_long (val
);
629 else /* handle tracepoint number */
631 tpnum
= strtol (*arg
, arg
, 0);
632 if (tpnum
== 0) /* possible strtol failure */
633 while (**arg
&& !isspace (**arg
))
634 (*arg
)++; /* advance to next white space, if any */
637 if (t
->number
== tpnum
)
641 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
645 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
647 map_args_over_tracepoints (args
, from_tty
, opcode
)
650 enum tracepoint_opcode opcode
;
652 struct tracepoint
*t
, *tmp
;
656 if (args
== 0 || *args
== 0) /* do them all */
657 ALL_TRACEPOINTS_SAFE (t
, tmp
)
658 tracepoint_operation (t
, from_tty
, opcode
);
662 QUIT
; /* give user option to bail out with ^C */
663 if (t
= get_tracepoint_by_number (&args
))
664 tracepoint_operation (t
, from_tty
, opcode
);
665 while (*args
== ' ' || *args
== '\t')
670 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
672 enable_trace_command (args
, from_tty
)
677 map_args_over_tracepoints (args
, from_tty
, enable
);
680 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
682 disable_trace_command (args
, from_tty
)
687 map_args_over_tracepoints (args
, from_tty
, disable
);
690 /* Remove a tracepoint (or all if no argument) */
692 delete_trace_command (args
, from_tty
)
697 if (!args
|| !*args
) /* No args implies all tracepoints; */
698 if (from_tty
) /* confirm only if from_tty... */
699 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
700 if (!query ("Delete all tracepoints? "))
703 map_args_over_tracepoints (args
, from_tty
, delete);
706 /* Set passcount for tracepoint.
708 First command argument is passcount, second is tracepoint number.
709 If tracepoint number omitted, apply to most recently defined.
710 Also accepts special argument "all". */
713 trace_pass_command (args
, from_tty
)
717 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
720 if (args
== 0 || *args
== 0)
721 error ("PASS command requires an argument (count + optional TP num)");
723 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
725 while (*args
&& isspace (*args
))
728 if (*args
&& strncasecmp (args
, "all", 3) == 0)
729 args
+= 3; /* skip special argument "all" */
731 t1
= get_tracepoint_by_number (&args
);
734 error ("Junk at end of arguments.");
737 return; /* error, bad tracepoint number */
740 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
742 t2
->pass_count
= count
;
743 if (modify_tracepoint_hook
)
744 modify_tracepoint_hook (t2
);
746 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
751 /* ACTIONS functions: */
753 /* Prototypes for action-parsing utility commands */
754 static void read_actions
PARAMS((struct tracepoint
*));
755 static char *parse_and_eval_memrange
PARAMS ((char *,
761 /* The three functions:
762 collect_pseudocommand,
763 while_stepping_pseudocommand, and
764 end_actions_pseudocommand
765 are placeholders for "commands" that are actually ONLY to be used
766 within a tracepoint action list. If the actual function is ever called,
767 it means that somebody issued the "command" at the top level,
768 which is always an error. */
771 end_actions_pseudocommand (args
, from_tty
)
775 error ("This command cannot be used at the top level.");
779 while_stepping_pseudocommand (args
, from_tty
)
783 error ("This command can only be used in a tracepoint actions list.");
787 collect_pseudocommand (args
, from_tty
)
791 error ("This command can only be used in a tracepoint actions list.");
794 /* Enter a list of actions for a tracepoint. */
796 trace_actions_command (args
, from_tty
)
800 struct tracepoint
*t
;
803 char *end_msg
= "End with a line saying just \"end\".";
805 if (t
= get_tracepoint_by_number (&args
))
807 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
812 if (readline_begin_hook
)
813 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
814 else if (input_from_terminal_p ())
815 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
819 t
->step_count
= 0; /* read_actions may set this */
822 if (readline_end_hook
)
823 (*readline_end_hook
) ();
825 /* tracepoints_changed () */
827 /* else error, just return; */
830 /* worker function */
833 struct tracepoint
*t
;
836 char *prompt1
= "> ", *prompt2
= " > ";
837 char *prompt
= prompt1
;
838 enum actionline_type linetype
;
839 extern FILE *instream
;
840 struct action_line
*next
= NULL
, *temp
;
841 struct cleanup
*old_chain
;
843 /* Control-C quits instantly if typed while in this loop
844 since it should not wait until the user types a newline. */
848 signal (STOP_SIGNAL
, stop_sig
);
850 old_chain
= make_cleanup (free_actions
, (void *) t
);
853 /* Make sure that all output has been output. Some machines may let
854 you get away with leaving out some of the gdb_flush, but not all. */
856 gdb_flush (gdb_stdout
);
857 gdb_flush (gdb_stderr
);
859 if (readline_hook
&& instream
== NULL
)
860 line
= (*readline_hook
) (prompt
);
861 else if (instream
== stdin
&& ISATTY (instream
))
863 line
= readline (prompt
);
864 if (line
&& *line
) /* add it to command history */
868 line
= gdb_readline (0);
870 linetype
= validate_actionline (&line
, t
);
871 if (linetype
== BADLINE
)
872 continue; /* already warned -- collect another line */
874 temp
= xmalloc (sizeof (struct action_line
));
878 if (next
== NULL
) /* first action for this tracepoint? */
879 t
->actions
= next
= temp
;
886 if (linetype
== STEPPING
) /* begin "while-stepping" */
887 if (prompt
== prompt2
)
889 warning ("Already processing 'while-stepping'");
893 prompt
= prompt2
; /* change prompt for stepping actions */
894 else if (linetype
== END
)
895 if (prompt
== prompt2
)
897 prompt
= prompt1
; /* end of single-stepping actions */
900 { /* end of actions */
901 if (t
->actions
->next
== NULL
)
903 /* an "end" all by itself with no other actions means
904 this tracepoint has no actions. Discard empty list. */
912 signal (STOP_SIGNAL
, SIG_DFL
);
915 discard_cleanups (old_chain
);
918 /* worker function */
920 validate_actionline (line
, t
)
922 struct tracepoint
*t
;
924 struct cmd_list_element
*c
;
925 struct expression
*exp
= NULL
;
926 value_ptr temp
, temp2
;
927 struct cleanup
*old_chain
= NULL
;
930 for (p
= *line
; isspace (*p
); )
933 /* symbol lookup etc. */
934 if (*p
== '\0') /* empty line: just prompt for another line. */
937 if (*p
== '#') /* comment line */
940 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
943 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
947 if (c
->function
.cfunc
== collect_pseudocommand
)
949 struct agent_expr
*aexpr
;
950 struct agent_reqs areqs
;
952 do { /* repeat over a comma-separated list */
953 QUIT
; /* allow user to bail out with ^C */
957 if (*p
== '$') /* look for special pseudo-symbols */
960 bfd_signed_vma offset
;
962 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
963 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
964 (0 == strncasecmp ("loc", p
+ 1, 3)))
969 /* else fall thru, treat p as an expression and parse it! */
971 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
972 old_chain
= make_cleanup (free_current_contents
, &exp
);
974 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
975 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
977 warning ("%s is constant (value %d): will not be collected.",
978 SYMBOL_NAME (exp
->elts
[2].symbol
),
979 SYMBOL_VALUE (exp
->elts
[2].symbol
));
982 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
984 warning ("%s is optimized away and cannot be collected.",
985 SYMBOL_NAME (exp
->elts
[2].symbol
));
989 /* we have something to collect, make sure that the expr to
990 bytecode translator can handle it and that it's not too long */
991 aexpr
= gen_trace_for_expr(exp
);
992 (void) make_cleanup (free_agent_expr
, aexpr
);
994 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
995 error ("expression too complicated, try simplifying");
997 ax_reqs(aexpr
, &areqs
);
998 (void) make_cleanup (free
, areqs
.reg_mask
);
1000 if (areqs
.flaw
!= agent_flaw_none
)
1001 error ("malformed expression");
1003 if (areqs
.min_height
< 0)
1004 error ("gdb: Internal error: expression has min height < 0");
1006 if (areqs
.max_height
> 20)
1007 error ("expression too complicated, try simplifying");
1009 do_cleanups (old_chain
);
1010 } while (p
&& *p
++ == ',');
1013 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
1015 char *steparg
; /* in case warning is necessary */
1017 while (isspace (*p
))
1022 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1024 warning ("bad step-count: command ignored.", *line
);
1029 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1033 warning ("'%s' is not a supported tracepoint action.", *line
);
1038 /* worker function */
1041 struct tracepoint
*t
;
1043 struct action_line
*line
, *next
;
1045 for (line
= t
->actions
; line
; line
= next
)
1049 free (line
->action
);
1056 int type
; /* 0 for absolute memory range, else basereg number */
1057 bfd_signed_vma start
;
1061 struct collection_list
{
1062 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1065 struct memrange
*list
;
1066 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1067 long next_aexpr_elt
;
1068 struct agent_expr
**aexpr_list
;
1070 } tracepoint_list
, stepping_list
;
1072 /* MEMRANGE functions: */
1074 static int memrange_cmp
PARAMS ((const void *, const void *));
1076 /* compare memranges for qsort */
1078 memrange_cmp (va
, vb
)
1082 const struct memrange
*a
= va
, *b
= vb
;
1084 if (a
->type
< b
->type
)
1086 if (a
->type
> b
->type
)
1090 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1091 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1095 if (a
->start
< b
->start
)
1097 if (a
->start
> b
->start
)
1103 /* Sort the memrange list using qsort, and merge adjacent memranges */
1105 memrange_sortmerge (memranges
)
1106 struct collection_list
*memranges
;
1110 qsort (memranges
->list
, memranges
->next_memrange
,
1111 sizeof (struct memrange
), memrange_cmp
);
1112 if (memranges
->next_memrange
> 0)
1114 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1116 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1117 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1118 MAX_REGISTER_VIRTUAL_SIZE
)
1120 /* memrange b starts before memrange a ends; merge them. */
1121 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1122 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1123 continue; /* next b, same a */
1127 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1128 sizeof (struct memrange
));
1130 memranges
->next_memrange
= a
+ 1;
1134 /* Add a register to a collection list */
1136 add_register (collection
, regno
)
1137 struct collection_list
*collection
;
1138 unsigned long regno
;
1141 printf_filtered ("collect register %d\n", regno
);
1142 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1143 error ("Internal: register number %d too large for tracepoint",
1145 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1148 /* Add a memrange to a collection list */
1150 add_memrange (memranges
, type
, base
, len
)
1151 struct collection_list
*memranges
;
1153 bfd_signed_vma base
;
1157 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1158 /* type: 0 == memory, n == basereg */
1159 memranges
->list
[memranges
->next_memrange
].type
= type
;
1160 /* base: addr if memory, offset if reg relative. */
1161 memranges
->list
[memranges
->next_memrange
].start
= base
;
1162 /* len: we actually save end (base + len) for convenience */
1163 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1164 memranges
->next_memrange
++;
1165 if (memranges
->next_memrange
>= memranges
->listsize
)
1167 memranges
->listsize
*= 2;
1168 memranges
->list
= xrealloc (memranges
->list
,
1169 memranges
->listsize
);
1172 if (type
!= -1) /* better collect the base register! */
1173 add_register (memranges
, type
);
1176 /* Add a symbol to a collection list */
1178 collect_symbol (collect
, sym
)
1179 struct collection_list
*collect
;
1184 bfd_signed_vma offset
;
1186 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1187 switch (SYMBOL_CLASS (sym
)) {
1189 printf_filtered ("%s: don't know symbol class %d\n",
1190 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1193 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1194 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1197 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1199 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1200 SYMBOL_NAME (sym
), len
, offset
);
1201 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1205 reg
= SYMBOL_VALUE (sym
);
1207 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1208 add_register (collect
, reg
);
1211 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1212 printf_filtered (" (will not collect %s)\n",
1216 offset
= SYMBOL_VALUE (sym
);
1220 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1221 SYMBOL_NAME (sym
), len
);
1222 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1224 add_memrange (collect
, reg
, offset
, len
);
1226 case LOC_REGPARM_ADDR
:
1227 reg
= SYMBOL_VALUE (sym
);
1231 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
1232 SYMBOL_NAME (sym
), len
);
1233 printf_filtered (" %d from reg %d\n", offset
, reg
);
1235 add_memrange (collect
, reg
, offset
, len
);
1239 offset
= SYMBOL_VALUE (sym
);
1243 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1244 SYMBOL_NAME (sym
), len
);
1245 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1247 add_memrange (collect
, reg
, offset
, len
);
1250 case LOC_BASEREG_ARG
:
1251 reg
= SYMBOL_BASEREG (sym
);
1252 offset
= SYMBOL_VALUE (sym
);
1255 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1256 SYMBOL_NAME (sym
), len
, offset
, reg
);
1258 add_memrange (collect
, reg
, offset
, len
);
1260 case LOC_UNRESOLVED
:
1261 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1263 case LOC_OPTIMIZED_OUT
:
1264 printf_filtered ("%s has been optimized out of existance.\n",
1270 /* Add all locals (or args) symbols to collection list */
1272 add_local_symbols (collect
, pc
, type
)
1273 struct collection_list
*collect
;
1278 struct block
*block
;
1279 int i
, nsyms
, count
= 0;
1281 block
= block_for_pc (pc
);
1284 QUIT
; /* allow user to bail out with ^C */
1285 nsyms
= BLOCK_NSYMS (block
);
1286 for (i
= 0; i
< nsyms
; i
++)
1288 sym
= BLOCK_SYM (block
, i
);
1289 switch (SYMBOL_CLASS (sym
)) {
1294 if (type
== 'L') /* collecting Locals */
1297 collect_symbol (collect
, sym
);
1304 case LOC_REGPARM_ADDR
:
1305 case LOC_BASEREG_ARG
:
1306 if (type
== 'A') /* collecting Arguments */
1309 collect_symbol (collect
, sym
);
1313 if (BLOCK_FUNCTION (block
))
1316 block
= BLOCK_SUPERBLOCK (block
);
1319 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1322 /* worker function */
1324 clear_collection_list (list
)
1325 struct collection_list
*list
;
1329 list
->next_memrange
= 0;
1330 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1332 free_agent_expr(list
->aexpr_list
[ndx
]);
1333 list
->aexpr_list
[ndx
] = NULL
;
1335 list
->next_aexpr_elt
= 0;
1336 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1339 /* reduce a collection list to string form (for gdb protocol) */
1341 stringify_collection_list (list
, string
)
1342 struct collection_list
*list
;
1345 char temp_buf
[2048];
1348 char *(*str_list
)[];
1352 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1353 str_list
= (char *(*)[])xmalloc(count
* sizeof (char *));
1355 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1356 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1358 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1361 printf_filtered ("\nCollecting registers (mask): 0x");
1366 QUIT
; /* allow user to bail out with ^C */
1368 printf_filtered ("%02X", list
->regs_mask
[i
]);
1369 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1372 (*str_list
)[ndx
] = savestring(temp_buf
, end
- temp_buf
);
1376 printf_filtered ("\n");
1377 if (list
->next_memrange
> 0 && info_verbose
)
1378 printf_filtered ("Collecting memranges: \n");
1379 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1381 QUIT
; /* allow user to bail out with ^C */
1383 printf_filtered ("(%d, 0x%x, %d)\n",
1385 list
->list
[i
].start
,
1386 list
->list
[i
].end
- list
->list
[i
].start
);
1387 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1389 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1394 sprintf (end
, "M%X,%X,%X",
1396 list
->list
[i
].start
,
1397 list
->list
[i
].end
- list
->list
[i
].start
);
1398 count
+= strlen (end
);
1399 end
+= strlen (end
);
1402 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1404 QUIT
; /* allow user to bail out with ^C */
1405 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1407 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1412 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1413 end
+= 10; /* 'X' + 8 hex digits + ',' */
1416 end
= mem2hex(list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1417 count
+= 2 * list
->aexpr_list
[i
]->len
;
1422 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1427 (*str_list
)[ndx
] = NULL
;
1436 free_actions_list(actions_list
)
1437 char **actions_list
;
1441 if (actions_list
== 0)
1444 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1445 free(actions_list
[ndx
]);
1450 /* render all actions into gdb protocol */
1452 encode_actions (t
, tdp_actions
, stepping_actions
)
1453 struct tracepoint
*t
;
1454 char ***tdp_actions
;
1455 char ***stepping_actions
;
1457 static char tdp_buff
[2048], step_buff
[2048];
1459 struct expression
*exp
= NULL
;
1460 struct action_line
*action
;
1461 bfd_signed_vma offset
;
1464 struct collection_list
*collect
;
1465 struct cmd_list_element
*cmd
;
1466 struct agent_expr
*aexpr
;
1468 clear_collection_list (&tracepoint_list
);
1469 clear_collection_list (&stepping_list
);
1470 collect
= &tracepoint_list
;
1472 *tdp_actions
= NULL
;
1473 *stepping_actions
= NULL
;
1475 for (action
= t
->actions
; action
; action
= action
->next
)
1477 QUIT
; /* allow user to bail out with ^C */
1478 action_exp
= action
->action
;
1479 while (isspace (*action_exp
))
1482 if (*action_exp
== '#') /* comment line */
1485 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1487 error ("Bad action list item: %s", action_exp
);
1489 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1491 do { /* repeat over a comma-separated list */
1492 QUIT
; /* allow user to bail out with ^C */
1493 while (isspace (*action_exp
))
1496 if (0 == strncasecmp ("$reg", action_exp
, 4))
1498 for (i
= 0; i
< NUM_REGS
; i
++)
1499 add_register (collect
, i
);
1500 action_exp
= strchr (action_exp
, ','); /* more? */
1502 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1504 add_local_symbols (collect
, t
->address
, 'A');
1505 action_exp
= strchr (action_exp
, ','); /* more? */
1507 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1509 add_local_symbols (collect
, t
->address
, 'L');
1510 action_exp
= strchr (action_exp
, ','); /* more? */
1514 unsigned long addr
, len
;
1515 struct cleanup
*old_chain
= NULL
;
1516 struct cleanup
*old_chain1
= NULL
;
1517 struct agent_reqs areqs
;
1519 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1520 old_chain
= make_cleanup (free_current_contents
, &exp
);
1522 switch (exp
->elts
[0].opcode
) {
1524 i
= exp
->elts
[1].longconst
;
1526 printf_filtered ("OP_REGISTER: ");
1527 add_register (collect
, i
);
1531 /* safe because we know it's a simple expression */
1532 tempval
= evaluate_expression (exp
);
1533 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1534 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1535 add_memrange (collect
, -1, addr
, len
);
1539 collect_symbol (collect
, exp
->elts
[2].symbol
);
1542 default: /* full-fledged expression */
1543 aexpr
= gen_trace_for_expr (exp
);
1545 old_chain1
= make_cleanup (free_agent_expr
, aexpr
);
1547 ax_reqs (aexpr
, &areqs
);
1548 if (areqs
.flaw
!= agent_flaw_none
)
1549 error ("malformed expression");
1551 if (areqs
.min_height
< 0)
1552 error ("gdb: Internal error: expression has min height < 0");
1553 if (areqs
.max_height
> 20)
1554 error ("expression too complicated, try simplifying");
1556 discard_cleanups (old_chain1
);
1557 add_aexpr (collect
, aexpr
);
1559 /* take care of the registers */
1560 if (areqs
.reg_mask_len
> 0)
1565 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1567 QUIT
; /* allow user to bail out with ^C */
1568 if (areqs
.reg_mask
[ndx1
] != 0)
1570 /* assume chars have 8 bits */
1571 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1572 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1573 /* it's used -- record it */
1574 add_register (collect
, ndx1
* 8 + ndx2
);
1580 do_cleanups (old_chain
);
1582 } while (action_exp
&& *action_exp
++ == ',');
1584 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1586 collect
= &stepping_list
;
1588 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1590 if (collect
== &stepping_list
) /* end stepping actions */
1591 collect
= &tracepoint_list
;
1593 break; /* end tracepoint actions */
1596 memrange_sortmerge (&tracepoint_list
);
1597 memrange_sortmerge (&stepping_list
);
1599 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1600 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1604 add_aexpr(collect
, aexpr
)
1605 struct collection_list
*collect
;
1606 struct agent_expr
*aexpr
;
1608 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1610 collect
->aexpr_list
=
1611 xrealloc (collect
->aexpr_list
,
1612 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1613 collect
->aexpr_listsize
*= 2;
1615 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1616 collect
->next_aexpr_elt
++;
1620 static char target_buf
[2048];
1624 Tell target to clear any previous trace experiment.
1625 Walk the list of tracepoints, and send them (and their actions)
1626 to the target. If no errors,
1627 Tell target to start a new trace experiment. */
1630 trace_start_command (args
, from_tty
)
1633 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1634 struct tracepoint
*t
;
1637 char **stepping_actions
;
1639 struct cleanup
*old_chain
= NULL
;
1641 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1643 if (target_is_remote ())
1646 remote_get_noisy_reply (target_buf
);
1647 if (strcmp (target_buf
, "OK"))
1648 error ("Target does not support this command.");
1652 int ss_count
; /* if actions include singlestepping */
1653 int disable_mask
; /* ??? */
1654 int enable_mask
; /* ??? */
1656 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1657 t
->enabled
== enabled
? 'E' : 'D',
1658 t
->step_count
, t
->pass_count
);
1663 remote_get_noisy_reply (target_buf
);
1664 if (strcmp (target_buf
, "OK"))
1665 error ("Target does not support tracepoints.");
1669 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1670 old_chain
= make_cleanup (free_actions_list
, tdp_actions
);
1671 (void) make_cleanup (free_actions_list
, stepping_actions
);
1673 /* do_single_steps (t); */
1676 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1678 QUIT
; /* allow user to bail out with ^C */
1679 sprintf (buf
, "QTDP:-%x:%x:%s%c",
1680 t
->number
, t
->address
,
1682 ((tdp_actions
[ndx
+1] || stepping_actions
)
1685 remote_get_noisy_reply (target_buf
);
1686 if (strcmp (target_buf
, "OK"))
1687 error ("Error on target while setting tracepoints.");
1690 if (stepping_actions
)
1692 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1694 QUIT
; /* allow user to bail out with ^C */
1695 sprintf (buf
, "QTDP:-%x:%x:%s%s%s",
1696 t
->number
, t
->address
,
1697 ((ndx
== 0) ? "S" : ""),
1698 stepping_actions
[ndx
],
1699 (stepping_actions
[ndx
+1] ? "-" : ""));
1701 remote_get_noisy_reply (target_buf
);
1702 if (strcmp (target_buf
, "OK"))
1703 error ("Error on target while setting tracepoints.");
1707 do_cleanups (old_chain
);
1711 remote_get_noisy_reply (target_buf
);
1712 if (strcmp (target_buf
, "OK"))
1713 error ("Bogus reply from target: %s", target_buf
);
1714 set_traceframe_num (-1); /* all old traceframes invalidated */
1715 set_tracepoint_num (-1);
1716 set_traceframe_context(-1);
1717 trace_running_p
= 1;
1720 error ("Trace can only be run on remote targets.");
1725 trace_stop_command (args
, from_tty
)
1728 { /* STUB_COMM IS_IMPLEMENTED */
1729 if (target_is_remote ())
1732 remote_get_noisy_reply (target_buf
);
1733 if (strcmp (target_buf
, "OK"))
1734 error ("Bogus reply from target: %s", target_buf
);
1735 trace_running_p
= 0;
1738 error ("Trace can only be run on remote targets.");
1741 unsigned long trace_running_p
;
1743 /* tstatus command */
1745 trace_status_command (args
, from_tty
)
1748 { /* STUB_COMM IS_IMPLEMENTED */
1749 if (target_is_remote ())
1751 putpkt ("qTStatus");
1752 remote_get_noisy_reply (target_buf
);
1754 if (target_buf
[0] != 'T' ||
1755 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1756 error ("Bogus reply from target: %s", target_buf
);
1758 /* exported for use by the GUI */
1759 trace_running_p
= (target_buf
[1] == '1');
1762 error ("Trace can only be run on remote targets.");
1765 /* Worker function for the various flavors of the tfind command */
1767 finish_tfind_command (msg
, from_tty
)
1771 int target_frameno
= -1, target_tracept
= -1;
1772 CORE_ADDR old_frame_addr
;
1773 struct symbol
*old_func
;
1776 old_frame_addr
= FRAME_FP (get_current_frame ());
1777 old_func
= find_pc_function (read_pc ());
1780 reply
= remote_get_noisy_reply (msg
);
1782 while (reply
&& *reply
)
1785 if ((target_frameno
= strtol (++reply
, &reply
, 16)) == -1)
1787 /* A request for a non-existant trace frame has failed.
1788 Our response will be different, depending on FROM_TTY:
1790 If FROM_TTY is true, meaning that this command was
1791 typed interactively by the user, then give an error
1792 and DO NOT change the state of traceframe_number etc.
1794 However if FROM_TTY is false, meaning that we're either
1795 in a script, a loop, or a user-defined command, then
1796 DON'T give an error, but DO change the state of
1797 traceframe_number etc. to invalid.
1799 The rationalle is that if you typed the command, you
1800 might just have committed a typo or something, and you'd
1801 like to NOT lose your current debugging state. However
1802 if you're in a user-defined command or especially in a
1803 loop, then you need a way to detect that the command
1804 failed WITHOUT aborting. This allows you to write
1805 scripts that search thru the trace buffer until the end,
1806 and then continue on to do something else. */
1809 error ("Target failed to find requested trace frame.");
1813 printf_filtered ("End of trace buffer.\n");
1814 /* The following will not recurse, since it's special-cased */
1815 trace_find_command ("-1", from_tty
);
1816 reply
= NULL
; /* break out of loop,
1817 (avoid recursive nonsense) */
1822 if ((target_tracept
= strtol (++reply
, &reply
, 16)) == -1)
1823 error ("Target failed to find requested trace frame.");
1825 case 'O': /* "OK"? */
1826 if (reply
[1] == 'K' && reply
[2] == '\0')
1829 error ("Bogus reply from target: %s", reply
);
1832 error ("Bogus reply from target: %s", reply
);
1835 flush_cached_frames ();
1836 registers_changed ();
1837 select_frame (get_current_frame (), 0);
1838 set_traceframe_num (target_frameno
);
1839 set_tracepoint_num (target_tracept
);
1840 if (target_frameno
== -1)
1841 set_traceframe_context (-1);
1843 set_traceframe_context (read_pc ());
1849 /* NOTE: in immitation of the step command, try to determine
1850 whether we have made a transition from one function to another.
1851 If so, we'll print the "stack frame" (ie. the new function and
1852 it's arguments) -- otherwise we'll just show the new source line.
1854 This determination is made by checking (1) whether the current
1855 function has changed, and (2) whether the current FP has changed.
1856 Hack: if the FP wasn't collected, either at the current or the
1857 previous frame, assume that the FP has NOT changed. */
1859 if (old_func
== find_pc_function (read_pc ()) &&
1860 (old_frame_addr
== 0 ||
1861 FRAME_FP (get_current_frame ()) == 0 ||
1862 old_frame_addr
== FRAME_FP (get_current_frame ())))
1867 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1872 /* trace_find_command takes a trace frame number n,
1873 sends "QTFrame:<n>" to the target,
1874 and accepts a reply that may contain several optional pieces
1875 of information: a frame number, a tracepoint number, and an
1876 indication of whether this is a trap frame or a stepping frame.
1878 The minimal response is just "OK" (which indicates that the
1879 target does not give us a frame number or a tracepoint number).
1880 Instead of that, the target may send us a string containing
1882 F<hexnum> (gives the selected frame number)
1883 T<hexnum> (gives the selected tracepoint number)
1888 trace_find_command (args
, from_tty
)
1891 { /* STUB_COMM PART_IMPLEMENTED */
1892 /* this should only be called with a numeric argument */
1894 int target_frameno
= -1, target_tracept
= -1, target_stepfrm
= 0;
1897 if (target_is_remote ())
1899 if (args
== 0 || *args
== 0)
1900 { /* TFIND with no args means find NEXT trace frame. */
1901 if (traceframe_number
== -1)
1902 frameno
= 0; /* "next" is first one */
1904 frameno
= traceframe_number
+ 1;
1906 else if (0 == strcmp (args
, "-"))
1908 if (traceframe_number
== -1)
1909 error ("not debugging trace buffer");
1910 else if (from_tty
&& traceframe_number
== 0)
1911 error ("already at start of trace buffer");
1913 frameno
= traceframe_number
- 1;
1916 frameno
= parse_and_eval_address (args
);
1919 error ("invalid input (%d is less than zero)", frameno
);
1921 sprintf (target_buf
, "QTFrame:%x", frameno
);
1922 finish_tfind_command (target_buf
, from_tty
);
1925 error ("Trace can only be run on remote targets.");
1930 trace_find_end_command (args
, from_tty
)
1934 trace_find_command ("-1", from_tty
);
1939 trace_find_none_command (args
, from_tty
)
1943 trace_find_command ("-1", from_tty
);
1948 trace_find_start_command (args
, from_tty
)
1952 trace_find_command ("0", from_tty
);
1955 /* tfind pc command */
1957 trace_find_pc_command (args
, from_tty
)
1960 { /* STUB_COMM PART_IMPLEMENTED */
1965 if (target_is_remote ())
1967 if (args
== 0 || *args
== 0)
1968 pc
= read_pc (); /* default is current pc */
1970 pc
= parse_and_eval_address (args
);
1972 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
1973 finish_tfind_command (target_buf
, from_tty
);
1976 error ("Trace can only be run on remote targets.");
1979 /* tfind tracepoint command */
1981 trace_find_tracepoint_command (args
, from_tty
)
1984 { /* STUB_COMM PART_IMPLEMENTED */
1985 int target_frameno
, tdp
;
1988 if (target_is_remote ())
1990 if (args
== 0 || *args
== 0)
1991 if (tracepoint_number
== -1)
1992 error ("No current tracepoint -- please supply an argument.");
1994 tdp
= tracepoint_number
; /* default is current TDP */
1996 tdp
= parse_and_eval_address (args
);
1998 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
1999 finish_tfind_command (target_buf
, from_tty
);
2002 error ("Trace can only be run on remote targets.");
2005 /* TFIND LINE command:
2007 This command will take a sourceline for argument, just like BREAK
2008 or TRACE (ie. anything that "decode_line_1" can handle).
2010 With no argument, this command will find the next trace frame
2011 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2014 trace_find_line_command (args
, from_tty
)
2017 { /* STUB_COMM PART_IMPLEMENTED */
2018 static CORE_ADDR start_pc
, end_pc
;
2019 struct symtabs_and_lines sals
;
2020 struct symtab_and_line sal
;
2023 struct cleanup
*old_chain
;
2025 if (target_is_remote ())
2027 if (args
== 0 || *args
== 0)
2029 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2031 sals
.sals
= (struct symtab_and_line
*)
2032 xmalloc (sizeof (struct symtab_and_line
));
2037 sals
= decode_line_spec (args
, 1);
2041 old_chain
= make_cleanup (free
, sals
.sals
);
2042 if (sal
.symtab
== 0)
2044 printf_filtered ("TFIND: No line number information available");
2047 /* This is useful for "info line *0x7f34". If we can't tell the
2048 user about a source line, at least let them have the symbolic
2050 printf_filtered (" for address ");
2052 print_address (sal
.pc
, gdb_stdout
);
2053 printf_filtered (";\n -- will attempt to find by PC. \n");
2057 printf_filtered (".\n");
2058 return; /* no line, no PC; what can we do? */
2061 else if (sal
.line
> 0
2062 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2064 if (start_pc
== end_pc
)
2066 printf_filtered ("Line %d of \"%s\"",
2067 sal
.line
, sal
.symtab
->filename
);
2069 printf_filtered (" is at address ");
2070 print_address (start_pc
, gdb_stdout
);
2072 printf_filtered (" but contains no code.\n");
2073 sal
= find_pc_line (start_pc
, 0);
2075 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2077 printf_filtered ("Attempting to find line %d instead.\n",
2080 error ("Cannot find a good line.");
2084 /* Is there any case in which we get here, and have an address
2085 which the user would want to see? If we have debugging symbols
2086 and no line numbers? */
2087 error ("Line number %d is out of range for \"%s\".\n",
2088 sal
.line
, sal
.symtab
->filename
);
2090 if (args
&& *args
) /* find within range of stated line */
2091 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
2092 else /* find OUTSIDE OF range of CURRENT line */
2093 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
2094 finish_tfind_command (target_buf
, from_tty
);
2095 do_cleanups (old_chain
);
2098 error ("Trace can only be run on remote targets.");
2101 /* tfind range command */
2103 trace_find_range_command (args
, from_tty
)
2106 { /* STUB_COMM PART_IMPLEMENTED */
2107 static CORE_ADDR start
, stop
;
2111 if (target_is_remote ())
2113 if (args
== 0 || *args
== 0)
2114 { /* XXX FIXME: what should default behavior be? */
2115 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2119 if (0 != (tmp
= strchr (args
, ',' )))
2121 *tmp
++ = '\0'; /* terminate start address */
2122 while (isspace (*tmp
))
2124 start
= parse_and_eval_address (args
);
2125 stop
= parse_and_eval_address (tmp
);
2128 { /* no explicit end address? */
2129 start
= parse_and_eval_address (args
);
2130 stop
= start
+ 1; /* ??? */
2133 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2134 finish_tfind_command (target_buf
, from_tty
);
2137 error ("Trace can only be run on remote targets.");
2140 /* tfind outside command */
2142 trace_find_outside_command (args
, from_tty
)
2145 { /* STUB_COMM PART_IMPLEMENTED */
2146 CORE_ADDR start
, stop
;
2150 if (target_is_remote ())
2152 if (args
== 0 || *args
== 0)
2153 { /* XXX FIXME: what should default behavior be? */
2154 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2158 if (0 != (tmp
= strchr (args
, ',' )))
2160 *tmp
++ = '\0'; /* terminate start address */
2161 while (isspace (*tmp
))
2163 start
= parse_and_eval_address (args
);
2164 stop
= parse_and_eval_address (tmp
);
2167 { /* no explicit end address? */
2168 start
= parse_and_eval_address (args
);
2169 stop
= start
+ 1; /* ??? */
2172 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2173 finish_tfind_command (target_buf
, from_tty
);
2176 error ("Trace can only be run on remote targets.");
2179 /* save-tracepoints command */
2181 tracepoint_save_command (args
, from_tty
)
2185 struct tracepoint
*tp
;
2186 struct action_line
*line
;
2188 char *i1
= " ", *i2
= " ";
2189 char *indent
, *actionline
;
2191 if (args
== 0 || *args
== 0)
2192 error ("Argument required (file name in which to save tracepoints");
2194 if (tracepoint_chain
== 0)
2196 warning ("save-tracepoints: no tracepoints to save.\n");
2200 if (!(fp
= fopen (args
, "w")))
2201 error ("Unable to open file '%s' for saving tracepoints");
2203 ALL_TRACEPOINTS (tp
)
2205 if (tp
->addr_string
)
2206 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2208 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2211 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2215 fprintf (fp
, " actions\n");
2217 for (line
= tp
->actions
; line
; line
= line
->next
)
2219 struct cmd_list_element
*cmd
;
2221 QUIT
; /* allow user to bail out with ^C */
2222 actionline
= line
->action
;
2223 while (isspace(*actionline
))
2226 fprintf (fp
, "%s%s\n", indent
, actionline
);
2227 if (*actionline
!= '#') /* skip for comment lines */
2229 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2231 error ("Bad action list item: %s", actionline
);
2232 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2234 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2242 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2246 /* info scope command: list the locals for a scope. */
2248 scope_info (args
, from_tty
)
2252 struct symtab_and_line sal
;
2253 struct symtabs_and_lines sals
;
2255 struct minimal_symbol
*msym
;
2256 struct block
*block
;
2257 char **canonical
, *symname
, *save_args
= args
;
2258 int i
, nsyms
, count
= 0;
2260 if (args
== 0 || *args
== 0)
2261 error ("requires an argument (function, line or *addr) to define a scope");
2263 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2264 if (sals
.nelts
== 0)
2265 return; /* presumably decode_line_1 has already warned */
2267 /* Resolve line numbers to PC */
2268 resolve_sal_pc (&sals
.sals
[0]);
2269 block
= block_for_pc (sals
.sals
[0].pc
);
2273 QUIT
; /* allow user to bail out with ^C */
2274 nsyms
= BLOCK_NSYMS (block
);
2275 for (i
= 0; i
< nsyms
; i
++)
2277 QUIT
; /* allow user to bail out with ^C */
2279 printf_filtered ("Scope for %s:\n", save_args
);
2281 sym
= BLOCK_SYM (block
, i
);
2282 symname
= SYMBOL_NAME (sym
);
2283 if (symname
== NULL
|| *symname
== '\0')
2284 continue; /* probably botched, certainly useless */
2286 printf_filtered ("Symbol %s is ", symname
);
2287 switch (SYMBOL_CLASS (sym
)) {
2289 case LOC_UNDEF
: /* messed up symbol? */
2290 printf_filtered ("a bogus symbol, class %d.\n",
2291 SYMBOL_CLASS (sym
));
2292 count
--; /* don't count this one */
2295 printf_filtered ("a constant with value %d (0x%x)",
2296 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2298 case LOC_CONST_BYTES
:
2299 printf_filtered ("constant bytes: ");
2300 if (SYMBOL_TYPE (sym
))
2301 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2302 fprintf_filtered (gdb_stdout
, " %02x",
2303 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2306 printf_filtered ("in static storage at address ");
2307 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2310 printf_filtered ("a local variable in register $%s",
2311 reg_names
[SYMBOL_VALUE (sym
)]);
2315 printf_filtered ("an argument at stack/frame offset %ld",
2316 SYMBOL_VALUE (sym
));
2319 printf_filtered ("a local variable at frame offset %ld",
2320 SYMBOL_VALUE (sym
));
2323 printf_filtered ("a reference argument at offset %ld",
2324 SYMBOL_VALUE (sym
));
2327 printf_filtered ("an argument in register $%s",
2328 reg_names
[SYMBOL_VALUE (sym
)]);
2330 case LOC_REGPARM_ADDR
:
2331 printf_filtered ("the address of an argument, in register $%s",
2332 reg_names
[SYMBOL_VALUE (sym
)]);
2335 printf_filtered ("a typedef.\n");
2338 printf_filtered ("a label at address ");
2339 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2342 printf_filtered ("a function at address ");
2343 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2347 printf_filtered ("a variable at offset %d from register $%s",
2349 reg_names
[SYMBOL_BASEREG (sym
)]);
2351 case LOC_BASEREG_ARG
:
2352 printf_filtered ("an argument at offset %d from register $%s",
2354 reg_names
[SYMBOL_BASEREG (sym
)]);
2356 case LOC_UNRESOLVED
:
2357 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2359 printf_filtered ("Unresolved Static");
2362 printf_filtered ("static storage at address ");
2363 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2367 case LOC_OPTIMIZED_OUT
:
2368 printf_filtered ("optimized out.\n");
2371 if (SYMBOL_TYPE (sym
))
2372 printf_filtered (", length %d.\n",
2373 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2375 if (BLOCK_FUNCTION (block
))
2378 block
= BLOCK_SUPERBLOCK (block
);
2381 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2385 /* worker function (cleanup) */
2387 replace_comma (comma
)
2395 trace_dump_command (args
, from_tty
)
2399 struct tracepoint
*t
;
2400 struct action_line
*action
;
2401 char *action_exp
, *next_comma
;
2402 struct cleanup
*old_cleanups
;
2403 int stepping_actions
= 0;
2404 int stepping_frame
= 0;
2406 if (!target_is_remote ())
2408 error ("Trace can only be run on remote targets.");
2412 if (tracepoint_number
== -1)
2414 warning ("No current trace frame.");
2419 if (t
->number
== tracepoint_number
)
2423 error ("No known tracepoint matches 'current' tracepoint #%d.",
2426 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2428 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2429 tracepoint_number
, traceframe_number
);
2431 /* The current frame is a trap frame if the frame PC is equal
2432 to the tracepoint PC. If not, then the current frame was
2433 collected during single-stepping. */
2435 stepping_frame
= (t
->address
!= read_pc());
2437 for (action
= t
->actions
; action
; action
= action
->next
)
2439 struct cmd_list_element
*cmd
;
2441 QUIT
; /* allow user to bail out with ^C */
2442 action_exp
= action
->action
;
2443 while (isspace (*action_exp
))
2446 /* The collection actions to be done while stepping are
2447 bracketed by the commands "while-stepping" and "end". */
2449 if (*action_exp
== '#') /* comment line */
2452 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2454 error ("Bad action list item: %s", action_exp
);
2456 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2457 stepping_actions
= 1;
2458 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2459 stepping_actions
= 0;
2460 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2462 /* Display the collected data.
2463 For the trap frame, display only what was collected at the trap.
2464 Likewise for stepping frames, display only what was collected
2465 while stepping. This means that the two boolean variables,
2466 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2467 if (stepping_frame
== stepping_actions
)
2469 do { /* repeat over a comma-separated list */
2470 QUIT
; /* allow user to bail out with ^C */
2471 if (*action_exp
== ',')
2473 while (isspace (*action_exp
))
2476 next_comma
= strchr (action_exp
, ',');
2478 if (0 == strncasecmp (action_exp
, "$reg", 4))
2479 registers_info (NULL
, from_tty
);
2480 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2481 locals_info (NULL
, from_tty
);
2482 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2483 args_info (NULL
, from_tty
);
2488 make_cleanup (replace_comma
, next_comma
);
2491 printf_filtered ("%s = ", action_exp
);
2492 output_command (action_exp
, from_tty
);
2493 printf_filtered ("\n");
2497 action_exp
= next_comma
;
2498 } while (action_exp
&& *action_exp
== ',');
2502 discard_cleanups (old_cleanups
);
2505 /* Convert the memory pointed to by mem into hex, placing result in buf.
2506 * Return a pointer to the last char put in buf (null)
2507 * "stolen" from sparc-stub.c
2510 static const char hexchars
[]="0123456789abcdef";
2512 static unsigned char *
2513 mem2hex(mem
, buf
, count
)
2524 *buf
++ = hexchars
[ch
>> 4];
2525 *buf
++ = hexchars
[ch
& 0xf];
2533 int get_traceframe_number()
2535 return traceframe_number
;
2539 /* module initialization */
2541 _initialize_tracepoint ()
2543 tracepoint_chain
= 0;
2544 tracepoint_count
= 0;
2545 traceframe_number
= -1;
2546 tracepoint_number
= -1;
2548 set_internalvar (lookup_internalvar ("tpnum"),
2549 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2550 set_internalvar (lookup_internalvar ("trace_frame"),
2551 value_from_longest (builtin_type_int
, (LONGEST
) -1));
2553 if (tracepoint_list
.list
== NULL
)
2555 tracepoint_list
.listsize
= 128;
2556 tracepoint_list
.list
= xmalloc
2557 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2559 if (tracepoint_list
.aexpr_list
== NULL
)
2561 tracepoint_list
.aexpr_listsize
= 128;
2562 tracepoint_list
.aexpr_list
= xmalloc
2563 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2566 if (stepping_list
.list
== NULL
)
2568 stepping_list
.listsize
= 128;
2569 stepping_list
.list
= xmalloc
2570 (stepping_list
.listsize
* sizeof (struct memrange
));
2573 if (stepping_list
.aexpr_list
== NULL
)
2575 stepping_list
.aexpr_listsize
= 128;
2576 stepping_list
.aexpr_list
= xmalloc
2577 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2580 add_info ("scope", scope_info
,
2581 "List the variables local to a scope");
2583 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2584 "Tracing of program execution without stopping the program.",
2587 add_info ("tracepoints", tracepoints_info
,
2588 "Status of tracepoints, or tracepoint number NUMBER.\n\
2589 Convenience variable \"$tpnum\" contains the number of the\n\
2590 last tracepoint set.");
2592 add_info_alias ("tp", "tracepoints", 1);
2594 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2595 "Save current tracepoint definitions as a script.\n\
2596 Use the 'source' command in another debug session to restore them.");
2598 add_com ("tdump", class_trace
, trace_dump_command
,
2599 "Print everything collected at the current tracepoint.");
2601 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2602 "Select a trace frame;\n\
2603 No argument means forward by one frame; '-' meand backward by one frame.",
2604 &tfindlist
, "tfind ", 1, &cmdlist
);
2606 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2607 "Select a trace frame whose PC is outside the given \
2608 range.\nUsage: tfind outside addr1, addr2",
2611 add_cmd ("range", class_trace
, trace_find_range_command
,
2612 "Select a trace frame whose PC is in the given range.\n\
2613 Usage: tfind range addr1,addr2",
2616 add_cmd ("line", class_trace
, trace_find_line_command
,
2617 "Select a trace frame by source line.\n\
2618 Argument can be a line number (with optional source file), \n\
2619 a function name, or '*' followed by an address.\n\
2620 Default argument is 'the next source line that was traced'.",
2623 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2624 "Select a trace frame by tracepoint number.\n\
2625 Default is the tracepoint for the current trace frame.",
2628 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2629 "Select a trace frame by PC.\n\
2630 Default is the current PC, or the PC of the current trace frame.",
2633 add_cmd ("end", class_trace
, trace_find_end_command
,
2634 "Synonym for 'none'.\n\
2635 De-select any trace frame and resume 'live' debugging.",
2638 add_cmd ("none", class_trace
, trace_find_none_command
,
2639 "De-select any trace frame and resume 'live' debugging.",
2642 add_cmd ("start", class_trace
, trace_find_start_command
,
2643 "Select the first trace frame in the trace buffer.",
2646 add_com ("tstatus", class_trace
, trace_status_command
,
2647 "Display the status of the current trace data collection.");
2649 add_com ("tstop", class_trace
, trace_stop_command
,
2650 "Stop trace data collection.");
2652 add_com ("tstart", class_trace
, trace_start_command
,
2653 "Start trace data collection.");
2655 add_com ("passcount", class_trace
, trace_pass_command
,
2656 "Set the passcount for a tracepoint.\n\
2657 The trace will end when the tracepoint has been passed 'count' times.\n\
2658 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2659 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2661 add_com ("end", class_trace
, end_actions_pseudocommand
,
2662 "Ends a list of commands or actions.\n\
2663 Several GDB commands allow you to enter a list of commands or actions.\n\
2664 Entering \"end\" on a line by itself is the normal way to terminate\n\
2666 Note: the \"end\" command cannot be used at the gdb prompt.");
2668 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2669 "Specify single-stepping behavior at a tracepoint.\n\
2670 Argument is number of instructions to trace in single-step mode\n\
2671 following the tracepoint. This command is normally followed by\n\
2672 one or more \"collect\" commands, to specify what to collect\n\
2673 while single-stepping.\n\n\
2674 Note: this command can only be used in a tracepoint \"actions\" list.");
2676 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2677 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2679 add_com ("collect", class_trace
, collect_pseudocommand
,
2680 "Specify one or more data items to be collected at a tracepoint.\n\
2681 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2682 collect all data (variables, registers) referenced by that expression.\n\
2683 Also accepts the following special arguments:\n\
2684 $regs -- all registers.\n\
2685 $args -- all function arguments.\n\
2686 $locals -- all variables local to the block/function scope.\n\
2687 Note: this command can only be used in a tracepoint \"actions\" list.");
2689 add_com ("actions", class_trace
, trace_actions_command
,
2690 "Specify the actions to be taken at a tracepoint.\n\
2691 Tracepoint actions may include collecting of specified data, \n\
2692 single-stepping, or enabling/disabling other tracepoints, \n\
2693 depending on target's capabilities.");
2695 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2696 "Delete specified tracepoints.\n\
2697 Arguments are tracepoint numbers, separated by spaces.\n\
2698 No argument means delete all tracepoints.",
2701 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2702 "Disable specified tracepoints.\n\
2703 Arguments are tracepoint numbers, separated by spaces.\n\
2704 No argument means disable all tracepoints.",
2707 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2708 "Enable specified tracepoints.\n\
2709 Arguments are tracepoint numbers, separated by spaces.\n\
2710 No argument means enable all tracepoints.",
2713 add_com ("trace", class_trace
, trace_command
,
2714 "Set a tracepoint at a specified line or function or address.\n\
2715 Argument may be a line number, function name, or '*' plus an address.\n\
2716 For a line number or function, trace at the start of its code.\n\
2717 If an address is specified, trace at that exact address.\n\n\
2718 Do \"help tracepoints\" for info on other tracepoint commands.");
2720 add_com_alias ("tp", "trace", class_alias
, 0);
2721 add_com_alias ("tr", "trace", class_alias
, 1);
2722 add_com_alias ("tra", "trace", class_alias
, 1);
2723 add_com_alias ("trac", "trace", class_alias
, 1);