1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997, 1998 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 ((make_cleanup_func
) 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 ((make_cleanup_func
) free_current_contents
,
975 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
976 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
978 warning ("%s is constant (value %d): will not be collected.",
979 SYMBOL_NAME (exp
->elts
[2].symbol
),
980 SYMBOL_VALUE (exp
->elts
[2].symbol
));
983 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
985 warning ("%s is optimized away and cannot be collected.",
986 SYMBOL_NAME (exp
->elts
[2].symbol
));
990 /* we have something to collect, make sure that the expr to
991 bytecode translator can handle it and that it's not too long */
992 aexpr
= gen_trace_for_expr(exp
);
993 (void) make_cleanup ((make_cleanup_func
) free_agent_expr
, aexpr
);
995 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
996 error ("expression too complicated, try simplifying");
998 ax_reqs(aexpr
, &areqs
);
999 (void) make_cleanup (free
, areqs
.reg_mask
);
1001 if (areqs
.flaw
!= agent_flaw_none
)
1002 error ("malformed expression");
1004 if (areqs
.min_height
< 0)
1005 error ("gdb: Internal error: expression has min height < 0");
1007 if (areqs
.max_height
> 20)
1008 error ("expression too complicated, try simplifying");
1010 do_cleanups (old_chain
);
1011 } while (p
&& *p
++ == ',');
1014 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
1016 char *steparg
; /* in case warning is necessary */
1018 while (isspace (*p
))
1023 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1025 warning ("bad step-count: command ignored.", *line
);
1030 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1034 warning ("'%s' is not a supported tracepoint action.", *line
);
1039 /* worker function */
1042 struct tracepoint
*t
;
1044 struct action_line
*line
, *next
;
1046 for (line
= t
->actions
; line
; line
= next
)
1050 free (line
->action
);
1057 int type
; /* 0 for absolute memory range, else basereg number */
1058 bfd_signed_vma start
;
1062 struct collection_list
{
1063 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1066 struct memrange
*list
;
1067 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1068 long next_aexpr_elt
;
1069 struct agent_expr
**aexpr_list
;
1071 } tracepoint_list
, stepping_list
;
1073 /* MEMRANGE functions: */
1075 static int memrange_cmp
PARAMS ((const void *, const void *));
1077 /* compare memranges for qsort */
1079 memrange_cmp (va
, vb
)
1083 const struct memrange
*a
= va
, *b
= vb
;
1085 if (a
->type
< b
->type
)
1087 if (a
->type
> b
->type
)
1091 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1092 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1096 if (a
->start
< b
->start
)
1098 if (a
->start
> b
->start
)
1104 /* Sort the memrange list using qsort, and merge adjacent memranges */
1106 memrange_sortmerge (memranges
)
1107 struct collection_list
*memranges
;
1111 qsort (memranges
->list
, memranges
->next_memrange
,
1112 sizeof (struct memrange
), memrange_cmp
);
1113 if (memranges
->next_memrange
> 0)
1115 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1117 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1118 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1119 MAX_REGISTER_VIRTUAL_SIZE
)
1121 /* memrange b starts before memrange a ends; merge them. */
1122 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1123 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1124 continue; /* next b, same a */
1128 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1129 sizeof (struct memrange
));
1131 memranges
->next_memrange
= a
+ 1;
1135 /* Add a register to a collection list */
1137 add_register (collection
, regno
)
1138 struct collection_list
*collection
;
1139 unsigned long regno
;
1142 printf_filtered ("collect register %d\n", regno
);
1143 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1144 error ("Internal: register number %d too large for tracepoint",
1146 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1149 /* Add a memrange to a collection list */
1151 add_memrange (memranges
, type
, base
, len
)
1152 struct collection_list
*memranges
;
1154 bfd_signed_vma base
;
1158 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1159 /* type: 0 == memory, n == basereg */
1160 memranges
->list
[memranges
->next_memrange
].type
= type
;
1161 /* base: addr if memory, offset if reg relative. */
1162 memranges
->list
[memranges
->next_memrange
].start
= base
;
1163 /* len: we actually save end (base + len) for convenience */
1164 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1165 memranges
->next_memrange
++;
1166 if (memranges
->next_memrange
>= memranges
->listsize
)
1168 memranges
->listsize
*= 2;
1169 memranges
->list
= xrealloc (memranges
->list
,
1170 memranges
->listsize
);
1173 if (type
!= -1) /* better collect the base register! */
1174 add_register (memranges
, type
);
1177 /* Add a symbol to a collection list */
1179 collect_symbol (collect
, sym
)
1180 struct collection_list
*collect
;
1185 bfd_signed_vma offset
;
1187 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1188 switch (SYMBOL_CLASS (sym
)) {
1190 printf_filtered ("%s: don't know symbol class %d\n",
1191 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1194 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1195 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1198 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1200 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1201 SYMBOL_NAME (sym
), len
, offset
);
1202 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1206 reg
= SYMBOL_VALUE (sym
);
1208 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1209 add_register (collect
, reg
);
1210 /* check for doubles stored in two registers */
1211 /* FIXME: how about larger types stored in 3 or more regs? */
1212 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1213 len
> REGISTER_RAW_SIZE (reg
))
1214 add_register (collect
, reg
+ 1);
1217 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1218 printf_filtered (" (will not collect %s)\n",
1222 offset
= SYMBOL_VALUE (sym
);
1226 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1227 SYMBOL_NAME (sym
), len
);
1228 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1230 add_memrange (collect
, reg
, offset
, len
);
1232 case LOC_REGPARM_ADDR
:
1233 reg
= SYMBOL_VALUE (sym
);
1237 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
1238 SYMBOL_NAME (sym
), len
);
1239 printf_filtered (" %d from reg %d\n", offset
, reg
);
1241 add_memrange (collect
, reg
, offset
, len
);
1245 offset
= SYMBOL_VALUE (sym
);
1249 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1250 SYMBOL_NAME (sym
), len
);
1251 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1253 add_memrange (collect
, reg
, offset
, len
);
1256 case LOC_BASEREG_ARG
:
1257 reg
= SYMBOL_BASEREG (sym
);
1258 offset
= SYMBOL_VALUE (sym
);
1261 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1262 SYMBOL_NAME (sym
), len
, offset
, reg
);
1264 add_memrange (collect
, reg
, offset
, len
);
1266 case LOC_UNRESOLVED
:
1267 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1269 case LOC_OPTIMIZED_OUT
:
1270 printf_filtered ("%s has been optimized out of existance.\n",
1276 /* Add all locals (or args) symbols to collection list */
1278 add_local_symbols (collect
, pc
, type
)
1279 struct collection_list
*collect
;
1284 struct block
*block
;
1285 int i
, nsyms
, count
= 0;
1287 block
= block_for_pc (pc
);
1290 QUIT
; /* allow user to bail out with ^C */
1291 nsyms
= BLOCK_NSYMS (block
);
1292 for (i
= 0; i
< nsyms
; i
++)
1294 sym
= BLOCK_SYM (block
, i
);
1295 switch (SYMBOL_CLASS (sym
)) {
1300 if (type
== 'L') /* collecting Locals */
1303 collect_symbol (collect
, sym
);
1310 case LOC_REGPARM_ADDR
:
1311 case LOC_BASEREG_ARG
:
1312 if (type
== 'A') /* collecting Arguments */
1315 collect_symbol (collect
, sym
);
1319 if (BLOCK_FUNCTION (block
))
1322 block
= BLOCK_SUPERBLOCK (block
);
1325 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1328 /* worker function */
1330 clear_collection_list (list
)
1331 struct collection_list
*list
;
1335 list
->next_memrange
= 0;
1336 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1338 free_agent_expr(list
->aexpr_list
[ndx
]);
1339 list
->aexpr_list
[ndx
] = NULL
;
1341 list
->next_aexpr_elt
= 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
;
1351 char temp_buf
[2048];
1354 char *(*str_list
)[];
1358 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1359 str_list
= (char *(*)[])xmalloc(count
* sizeof (char *));
1361 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1362 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1364 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1367 printf_filtered ("\nCollecting registers (mask): 0x");
1372 QUIT
; /* allow user to bail out with ^C */
1374 printf_filtered ("%02X", list
->regs_mask
[i
]);
1375 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1378 (*str_list
)[ndx
] = savestring(temp_buf
, end
- temp_buf
);
1382 printf_filtered ("\n");
1383 if (list
->next_memrange
> 0 && info_verbose
)
1384 printf_filtered ("Collecting memranges: \n");
1385 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1387 QUIT
; /* allow user to bail out with ^C */
1389 printf_filtered ("(%d, 0x%x, %d)\n",
1391 list
->list
[i
].start
,
1392 list
->list
[i
].end
- list
->list
[i
].start
);
1393 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1395 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1400 sprintf (end
, "M%X,%X,%X",
1402 list
->list
[i
].start
,
1403 list
->list
[i
].end
- list
->list
[i
].start
);
1404 count
+= strlen (end
);
1405 end
+= strlen (end
);
1408 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1410 QUIT
; /* allow user to bail out with ^C */
1411 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1413 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1418 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1419 end
+= 10; /* 'X' + 8 hex digits + ',' */
1422 end
= mem2hex(list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1423 count
+= 2 * list
->aexpr_list
[i
]->len
;
1428 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1433 (*str_list
)[ndx
] = NULL
;
1442 free_actions_list(actions_list
)
1443 char **actions_list
;
1447 if (actions_list
== 0)
1450 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1451 free(actions_list
[ndx
]);
1456 /* render all actions into gdb protocol */
1458 encode_actions (t
, tdp_actions
, stepping_actions
)
1459 struct tracepoint
*t
;
1460 char ***tdp_actions
;
1461 char ***stepping_actions
;
1463 static char tdp_buff
[2048], step_buff
[2048];
1465 struct expression
*exp
= NULL
;
1466 struct action_line
*action
;
1467 bfd_signed_vma offset
;
1470 struct collection_list
*collect
;
1471 struct cmd_list_element
*cmd
;
1472 struct agent_expr
*aexpr
;
1474 clear_collection_list (&tracepoint_list
);
1475 clear_collection_list (&stepping_list
);
1476 collect
= &tracepoint_list
;
1478 *tdp_actions
= NULL
;
1479 *stepping_actions
= NULL
;
1481 for (action
= t
->actions
; action
; action
= action
->next
)
1483 QUIT
; /* allow user to bail out with ^C */
1484 action_exp
= action
->action
;
1485 while (isspace (*action_exp
))
1488 if (*action_exp
== '#') /* comment line */
1491 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1493 error ("Bad action list item: %s", action_exp
);
1495 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1497 do { /* repeat over a comma-separated list */
1498 QUIT
; /* allow user to bail out with ^C */
1499 while (isspace (*action_exp
))
1502 if (0 == strncasecmp ("$reg", action_exp
, 4))
1504 for (i
= 0; i
< NUM_REGS
; i
++)
1505 add_register (collect
, i
);
1506 action_exp
= strchr (action_exp
, ','); /* more? */
1508 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1510 add_local_symbols (collect
, t
->address
, 'A');
1511 action_exp
= strchr (action_exp
, ','); /* more? */
1513 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1515 add_local_symbols (collect
, t
->address
, 'L');
1516 action_exp
= strchr (action_exp
, ','); /* more? */
1520 unsigned long addr
, len
;
1521 struct cleanup
*old_chain
= NULL
;
1522 struct cleanup
*old_chain1
= NULL
;
1523 struct agent_reqs areqs
;
1525 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1526 old_chain
= make_cleanup ((make_cleanup_func
)
1527 free_current_contents
, &exp
);
1529 switch (exp
->elts
[0].opcode
) {
1531 i
= exp
->elts
[1].longconst
;
1533 printf_filtered ("OP_REGISTER: ");
1534 add_register (collect
, i
);
1538 /* safe because we know it's a simple expression */
1539 tempval
= evaluate_expression (exp
);
1540 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1541 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1542 add_memrange (collect
, -1, addr
, len
);
1546 collect_symbol (collect
, exp
->elts
[2].symbol
);
1549 default: /* full-fledged expression */
1550 aexpr
= gen_trace_for_expr (exp
);
1552 old_chain1
= make_cleanup ((make_cleanup_func
)
1553 free_agent_expr
, aexpr
);
1555 ax_reqs (aexpr
, &areqs
);
1556 if (areqs
.flaw
!= agent_flaw_none
)
1557 error ("malformed expression");
1559 if (areqs
.min_height
< 0)
1560 error ("gdb: Internal error: expression has min height < 0");
1561 if (areqs
.max_height
> 20)
1562 error ("expression too complicated, try simplifying");
1564 discard_cleanups (old_chain1
);
1565 add_aexpr (collect
, aexpr
);
1567 /* take care of the registers */
1568 if (areqs
.reg_mask_len
> 0)
1573 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1575 QUIT
; /* allow user to bail out with ^C */
1576 if (areqs
.reg_mask
[ndx1
] != 0)
1578 /* assume chars have 8 bits */
1579 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1580 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1581 /* it's used -- record it */
1582 add_register (collect
, ndx1
* 8 + ndx2
);
1588 do_cleanups (old_chain
);
1590 } while (action_exp
&& *action_exp
++ == ',');
1592 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1594 collect
= &stepping_list
;
1596 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1598 if (collect
== &stepping_list
) /* end stepping actions */
1599 collect
= &tracepoint_list
;
1601 break; /* end tracepoint actions */
1604 memrange_sortmerge (&tracepoint_list
);
1605 memrange_sortmerge (&stepping_list
);
1607 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1608 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1612 add_aexpr(collect
, aexpr
)
1613 struct collection_list
*collect
;
1614 struct agent_expr
*aexpr
;
1616 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1618 collect
->aexpr_list
=
1619 xrealloc (collect
->aexpr_list
,
1620 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1621 collect
->aexpr_listsize
*= 2;
1623 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1624 collect
->next_aexpr_elt
++;
1627 static char target_buf
[2048];
1629 /* Set "transparent" memory ranges
1631 Allow trace mechanism to treat text-like sections
1632 (and perhaps all read-only sections) transparently,
1633 i.e. don't reject memory requests from these address ranges
1634 just because they haven't been collected. */
1637 remote_set_transparent_ranges (void)
1639 extern bfd
*exec_bfd
;
1646 return; /* no information to give. */
1648 strcpy (target_buf
, "QTro");
1649 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1653 if ((s
->flags
& SEC_LOAD
) == 0 ||
1654 /* (s->flags & SEC_CODE) == 0 || */
1655 (s
->flags
& SEC_READONLY
) == 0)
1660 size
= bfd_get_section_size_before_reloc (s
);
1661 sprintf (tmp
, ":%x,%x", lma
, lma
+ size
);
1662 strcat (target_buf
, tmp
);
1666 putpkt (target_buf
);
1667 getpkt (target_buf
, 0);
1673 Tell target to clear any previous trace experiment.
1674 Walk the list of tracepoints, and send them (and their actions)
1675 to the target. If no errors,
1676 Tell target to start a new trace experiment. */
1679 trace_start_command (args
, from_tty
)
1682 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1683 struct tracepoint
*t
;
1686 char **stepping_actions
;
1688 struct cleanup
*old_chain
= NULL
;
1690 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1692 if (target_is_remote ())
1695 remote_get_noisy_reply (target_buf
);
1696 if (strcmp (target_buf
, "OK"))
1697 error ("Target does not support this command.");
1701 int ss_count
; /* if actions include singlestepping */
1702 int disable_mask
; /* ??? */
1703 int enable_mask
; /* ??? */
1705 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1706 t
->enabled
== enabled
? 'E' : 'D',
1707 t
->step_count
, t
->pass_count
);
1712 remote_get_noisy_reply (target_buf
);
1713 if (strcmp (target_buf
, "OK"))
1714 error ("Target does not support tracepoints.");
1718 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1719 old_chain
= make_cleanup (free_actions_list
, tdp_actions
);
1720 (void) make_cleanup (free_actions_list
, stepping_actions
);
1722 /* do_single_steps (t); */
1725 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1727 QUIT
; /* allow user to bail out with ^C */
1728 sprintf (buf
, "QTDP:-%x:%x:%s%c",
1729 t
->number
, t
->address
,
1731 ((tdp_actions
[ndx
+1] || stepping_actions
)
1734 remote_get_noisy_reply (target_buf
);
1735 if (strcmp (target_buf
, "OK"))
1736 error ("Error on target while setting tracepoints.");
1739 if (stepping_actions
)
1741 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1743 QUIT
; /* allow user to bail out with ^C */
1744 sprintf (buf
, "QTDP:-%x:%x:%s%s%s",
1745 t
->number
, t
->address
,
1746 ((ndx
== 0) ? "S" : ""),
1747 stepping_actions
[ndx
],
1748 (stepping_actions
[ndx
+1] ? "-" : ""));
1750 remote_get_noisy_reply (target_buf
);
1751 if (strcmp (target_buf
, "OK"))
1752 error ("Error on target while setting tracepoints.");
1756 do_cleanups (old_chain
);
1759 /* Tell target to treat text-like sections as transparent */
1760 remote_set_transparent_ranges ();
1761 /* Now insert traps and begin collecting data */
1763 remote_get_noisy_reply (target_buf
);
1764 if (strcmp (target_buf
, "OK"))
1765 error ("Bogus reply from target: %s", target_buf
);
1766 set_traceframe_num (-1); /* all old traceframes invalidated */
1767 set_tracepoint_num (-1);
1768 set_traceframe_context(-1);
1769 trace_running_p
= 1;
1772 error ("Trace can only be run on remote targets.");
1777 trace_stop_command (args
, from_tty
)
1780 { /* STUB_COMM IS_IMPLEMENTED */
1781 if (target_is_remote ())
1784 remote_get_noisy_reply (target_buf
);
1785 if (strcmp (target_buf
, "OK"))
1786 error ("Bogus reply from target: %s", target_buf
);
1787 trace_running_p
= 0;
1790 error ("Trace can only be run on remote targets.");
1793 unsigned long trace_running_p
;
1795 /* tstatus command */
1797 trace_status_command (args
, from_tty
)
1800 { /* STUB_COMM IS_IMPLEMENTED */
1801 if (target_is_remote ())
1803 putpkt ("qTStatus");
1804 remote_get_noisy_reply (target_buf
);
1806 if (target_buf
[0] != 'T' ||
1807 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1808 error ("Bogus reply from target: %s", target_buf
);
1810 /* exported for use by the GUI */
1811 trace_running_p
= (target_buf
[1] == '1');
1814 error ("Trace can only be run on remote targets.");
1817 /* Worker function for the various flavors of the tfind command */
1819 finish_tfind_command (msg
, from_tty
)
1823 int target_frameno
= -1, target_tracept
= -1;
1824 CORE_ADDR old_frame_addr
;
1825 struct symbol
*old_func
;
1828 old_frame_addr
= FRAME_FP (get_current_frame ());
1829 old_func
= find_pc_function (read_pc ());
1832 reply
= remote_get_noisy_reply (msg
);
1834 while (reply
&& *reply
)
1837 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1839 /* A request for a non-existant trace frame has failed.
1840 Our response will be different, depending on FROM_TTY:
1842 If FROM_TTY is true, meaning that this command was
1843 typed interactively by the user, then give an error
1844 and DO NOT change the state of traceframe_number etc.
1846 However if FROM_TTY is false, meaning that we're either
1847 in a script, a loop, or a user-defined command, then
1848 DON'T give an error, but DO change the state of
1849 traceframe_number etc. to invalid.
1851 The rationalle is that if you typed the command, you
1852 might just have committed a typo or something, and you'd
1853 like to NOT lose your current debugging state. However
1854 if you're in a user-defined command or especially in a
1855 loop, then you need a way to detect that the command
1856 failed WITHOUT aborting. This allows you to write
1857 scripts that search thru the trace buffer until the end,
1858 and then continue on to do something else. */
1861 error ("Target failed to find requested trace frame.");
1865 printf_filtered ("End of trace buffer.\n");
1866 /* The following will not recurse, since it's special-cased */
1867 trace_find_command ("-1", from_tty
);
1868 reply
= NULL
; /* break out of loop,
1869 (avoid recursive nonsense) */
1874 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1875 error ("Target failed to find requested trace frame.");
1877 case 'O': /* "OK"? */
1878 if (reply
[1] == 'K' && reply
[2] == '\0')
1881 error ("Bogus reply from target: %s", reply
);
1884 error ("Bogus reply from target: %s", reply
);
1887 flush_cached_frames ();
1888 registers_changed ();
1889 select_frame (get_current_frame (), 0);
1890 set_traceframe_num (target_frameno
);
1891 set_tracepoint_num (target_tracept
);
1892 if (target_frameno
== -1)
1893 set_traceframe_context (-1);
1895 set_traceframe_context (read_pc ());
1901 /* NOTE: in immitation of the step command, try to determine
1902 whether we have made a transition from one function to another.
1903 If so, we'll print the "stack frame" (ie. the new function and
1904 it's arguments) -- otherwise we'll just show the new source line.
1906 This determination is made by checking (1) whether the current
1907 function has changed, and (2) whether the current FP has changed.
1908 Hack: if the FP wasn't collected, either at the current or the
1909 previous frame, assume that the FP has NOT changed. */
1911 if (old_func
== find_pc_function (read_pc ()) &&
1912 (old_frame_addr
== 0 ||
1913 FRAME_FP (get_current_frame ()) == 0 ||
1914 old_frame_addr
== FRAME_FP (get_current_frame ())))
1919 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1924 /* trace_find_command takes a trace frame number n,
1925 sends "QTFrame:<n>" to the target,
1926 and accepts a reply that may contain several optional pieces
1927 of information: a frame number, a tracepoint number, and an
1928 indication of whether this is a trap frame or a stepping frame.
1930 The minimal response is just "OK" (which indicates that the
1931 target does not give us a frame number or a tracepoint number).
1932 Instead of that, the target may send us a string containing
1934 F<hexnum> (gives the selected frame number)
1935 T<hexnum> (gives the selected tracepoint number)
1940 trace_find_command (args
, from_tty
)
1943 { /* STUB_COMM PART_IMPLEMENTED */
1944 /* this should only be called with a numeric argument */
1948 if (target_is_remote ())
1950 if (args
== 0 || *args
== 0)
1951 { /* TFIND with no args means find NEXT trace frame. */
1952 if (traceframe_number
== -1)
1953 frameno
= 0; /* "next" is first one */
1955 frameno
= traceframe_number
+ 1;
1957 else if (0 == strcmp (args
, "-"))
1959 if (traceframe_number
== -1)
1960 error ("not debugging trace buffer");
1961 else if (from_tty
&& traceframe_number
== 0)
1962 error ("already at start of trace buffer");
1964 frameno
= traceframe_number
- 1;
1967 frameno
= parse_and_eval_address (args
);
1970 error ("invalid input (%d is less than zero)", frameno
);
1972 sprintf (target_buf
, "QTFrame:%x", frameno
);
1973 finish_tfind_command (target_buf
, from_tty
);
1976 error ("Trace can only be run on remote targets.");
1981 trace_find_end_command (args
, from_tty
)
1985 trace_find_command ("-1", from_tty
);
1990 trace_find_none_command (args
, from_tty
)
1994 trace_find_command ("-1", from_tty
);
1999 trace_find_start_command (args
, from_tty
)
2003 trace_find_command ("0", from_tty
);
2006 /* tfind pc command */
2008 trace_find_pc_command (args
, from_tty
)
2011 { /* STUB_COMM PART_IMPLEMENTED */
2015 if (target_is_remote ())
2017 if (args
== 0 || *args
== 0)
2018 pc
= read_pc (); /* default is current pc */
2020 pc
= parse_and_eval_address (args
);
2022 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
2023 finish_tfind_command (target_buf
, from_tty
);
2026 error ("Trace can only be run on remote targets.");
2029 /* tfind tracepoint command */
2031 trace_find_tracepoint_command (args
, from_tty
)
2034 { /* STUB_COMM PART_IMPLEMENTED */
2038 if (target_is_remote ())
2040 if (args
== 0 || *args
== 0)
2041 if (tracepoint_number
== -1)
2042 error ("No current tracepoint -- please supply an argument.");
2044 tdp
= tracepoint_number
; /* default is current TDP */
2046 tdp
= parse_and_eval_address (args
);
2048 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2049 finish_tfind_command (target_buf
, from_tty
);
2052 error ("Trace can only be run on remote targets.");
2055 /* TFIND LINE command:
2057 This command will take a sourceline for argument, just like BREAK
2058 or TRACE (ie. anything that "decode_line_1" can handle).
2060 With no argument, this command will find the next trace frame
2061 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2064 trace_find_line_command (args
, from_tty
)
2067 { /* STUB_COMM PART_IMPLEMENTED */
2068 static CORE_ADDR start_pc
, end_pc
;
2069 struct symtabs_and_lines sals
;
2070 struct symtab_and_line sal
;
2072 struct cleanup
*old_chain
;
2074 if (target_is_remote ())
2076 if (args
== 0 || *args
== 0)
2078 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2080 sals
.sals
= (struct symtab_and_line
*)
2081 xmalloc (sizeof (struct symtab_and_line
));
2086 sals
= decode_line_spec (args
, 1);
2090 old_chain
= make_cleanup (free
, sals
.sals
);
2091 if (sal
.symtab
== 0)
2093 printf_filtered ("TFIND: No line number information available");
2096 /* This is useful for "info line *0x7f34". If we can't tell the
2097 user about a source line, at least let them have the symbolic
2099 printf_filtered (" for address ");
2101 print_address (sal
.pc
, gdb_stdout
);
2102 printf_filtered (";\n -- will attempt to find by PC. \n");
2106 printf_filtered (".\n");
2107 return; /* no line, no PC; what can we do? */
2110 else if (sal
.line
> 0
2111 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2113 if (start_pc
== end_pc
)
2115 printf_filtered ("Line %d of \"%s\"",
2116 sal
.line
, sal
.symtab
->filename
);
2118 printf_filtered (" is at address ");
2119 print_address (start_pc
, gdb_stdout
);
2121 printf_filtered (" but contains no code.\n");
2122 sal
= find_pc_line (start_pc
, 0);
2124 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2126 printf_filtered ("Attempting to find line %d instead.\n",
2129 error ("Cannot find a good line.");
2133 /* Is there any case in which we get here, and have an address
2134 which the user would want to see? If we have debugging symbols
2135 and no line numbers? */
2136 error ("Line number %d is out of range for \"%s\".\n",
2137 sal
.line
, sal
.symtab
->filename
);
2139 if (args
&& *args
) /* find within range of stated line */
2140 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
2141 else /* find OUTSIDE OF range of CURRENT line */
2142 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
2143 finish_tfind_command (target_buf
, from_tty
);
2144 do_cleanups (old_chain
);
2147 error ("Trace can only be run on remote targets.");
2150 /* tfind range command */
2152 trace_find_range_command (args
, from_tty
)
2155 { /* STUB_COMM PART_IMPLEMENTED */
2156 static CORE_ADDR start
, stop
;
2159 if (target_is_remote ())
2161 if (args
== 0 || *args
== 0)
2162 { /* XXX FIXME: what should default behavior be? */
2163 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2167 if (0 != (tmp
= strchr (args
, ',' )))
2169 *tmp
++ = '\0'; /* terminate start address */
2170 while (isspace (*tmp
))
2172 start
= parse_and_eval_address (args
);
2173 stop
= parse_and_eval_address (tmp
);
2176 { /* no explicit end address? */
2177 start
= parse_and_eval_address (args
);
2178 stop
= start
+ 1; /* ??? */
2181 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2182 finish_tfind_command (target_buf
, from_tty
);
2185 error ("Trace can only be run on remote targets.");
2188 /* tfind outside command */
2190 trace_find_outside_command (args
, from_tty
)
2193 { /* STUB_COMM PART_IMPLEMENTED */
2194 CORE_ADDR start
, stop
;
2197 if (target_is_remote ())
2199 if (args
== 0 || *args
== 0)
2200 { /* XXX FIXME: what should default behavior be? */
2201 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2205 if (0 != (tmp
= strchr (args
, ',' )))
2207 *tmp
++ = '\0'; /* terminate start address */
2208 while (isspace (*tmp
))
2210 start
= parse_and_eval_address (args
);
2211 stop
= parse_and_eval_address (tmp
);
2214 { /* no explicit end address? */
2215 start
= parse_and_eval_address (args
);
2216 stop
= start
+ 1; /* ??? */
2219 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2220 finish_tfind_command (target_buf
, from_tty
);
2223 error ("Trace can only be run on remote targets.");
2226 /* save-tracepoints command */
2228 tracepoint_save_command (args
, from_tty
)
2232 struct tracepoint
*tp
;
2233 struct action_line
*line
;
2235 char *i1
= " ", *i2
= " ";
2236 char *indent
, *actionline
;
2238 if (args
== 0 || *args
== 0)
2239 error ("Argument required (file name in which to save tracepoints");
2241 if (tracepoint_chain
== 0)
2243 warning ("save-tracepoints: no tracepoints to save.\n");
2247 if (!(fp
= fopen (args
, "w")))
2248 error ("Unable to open file '%s' for saving tracepoints");
2250 ALL_TRACEPOINTS (tp
)
2252 if (tp
->addr_string
)
2253 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2255 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2258 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2262 fprintf (fp
, " actions\n");
2264 for (line
= tp
->actions
; line
; line
= line
->next
)
2266 struct cmd_list_element
*cmd
;
2268 QUIT
; /* allow user to bail out with ^C */
2269 actionline
= line
->action
;
2270 while (isspace(*actionline
))
2273 fprintf (fp
, "%s%s\n", indent
, actionline
);
2274 if (*actionline
!= '#') /* skip for comment lines */
2276 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2278 error ("Bad action list item: %s", actionline
);
2279 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2281 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2289 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2293 /* info scope command: list the locals for a scope. */
2295 scope_info (args
, from_tty
)
2299 struct symtab_and_line sal
;
2300 struct symtabs_and_lines sals
;
2302 struct minimal_symbol
*msym
;
2303 struct block
*block
;
2304 char **canonical
, *symname
, *save_args
= args
;
2305 int i
, nsyms
, count
= 0;
2307 if (args
== 0 || *args
== 0)
2308 error ("requires an argument (function, line or *addr) to define a scope");
2310 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2311 if (sals
.nelts
== 0)
2312 return; /* presumably decode_line_1 has already warned */
2314 /* Resolve line numbers to PC */
2315 resolve_sal_pc (&sals
.sals
[0]);
2316 block
= block_for_pc (sals
.sals
[0].pc
);
2320 QUIT
; /* allow user to bail out with ^C */
2321 nsyms
= BLOCK_NSYMS (block
);
2322 for (i
= 0; i
< nsyms
; i
++)
2324 QUIT
; /* allow user to bail out with ^C */
2326 printf_filtered ("Scope for %s:\n", save_args
);
2328 sym
= BLOCK_SYM (block
, i
);
2329 symname
= SYMBOL_NAME (sym
);
2330 if (symname
== NULL
|| *symname
== '\0')
2331 continue; /* probably botched, certainly useless */
2333 printf_filtered ("Symbol %s is ", symname
);
2334 switch (SYMBOL_CLASS (sym
)) {
2336 case LOC_UNDEF
: /* messed up symbol? */
2337 printf_filtered ("a bogus symbol, class %d.\n",
2338 SYMBOL_CLASS (sym
));
2339 count
--; /* don't count this one */
2342 printf_filtered ("a constant with value %d (0x%x)",
2343 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2345 case LOC_CONST_BYTES
:
2346 printf_filtered ("constant bytes: ");
2347 if (SYMBOL_TYPE (sym
))
2348 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2349 fprintf_filtered (gdb_stdout
, " %02x",
2350 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2353 printf_filtered ("in static storage at address ");
2354 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2357 printf_filtered ("a local variable in register $%s",
2358 reg_names
[SYMBOL_VALUE (sym
)]);
2362 printf_filtered ("an argument at stack/frame offset %ld",
2363 SYMBOL_VALUE (sym
));
2366 printf_filtered ("a local variable at frame offset %ld",
2367 SYMBOL_VALUE (sym
));
2370 printf_filtered ("a reference argument at offset %ld",
2371 SYMBOL_VALUE (sym
));
2374 printf_filtered ("an argument in register $%s",
2375 reg_names
[SYMBOL_VALUE (sym
)]);
2377 case LOC_REGPARM_ADDR
:
2378 printf_filtered ("the address of an argument, in register $%s",
2379 reg_names
[SYMBOL_VALUE (sym
)]);
2382 printf_filtered ("a typedef.\n");
2385 printf_filtered ("a label at address ");
2386 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2389 printf_filtered ("a function at address ");
2390 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2394 printf_filtered ("a variable at offset %d from register $%s",
2396 reg_names
[SYMBOL_BASEREG (sym
)]);
2398 case LOC_BASEREG_ARG
:
2399 printf_filtered ("an argument at offset %d from register $%s",
2401 reg_names
[SYMBOL_BASEREG (sym
)]);
2403 case LOC_UNRESOLVED
:
2404 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2406 printf_filtered ("Unresolved Static");
2409 printf_filtered ("static storage at address ");
2410 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2414 case LOC_OPTIMIZED_OUT
:
2415 printf_filtered ("optimized out.\n");
2418 if (SYMBOL_TYPE (sym
))
2419 printf_filtered (", length %d.\n",
2420 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2422 if (BLOCK_FUNCTION (block
))
2425 block
= BLOCK_SUPERBLOCK (block
);
2428 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2432 /* worker function (cleanup) */
2434 replace_comma (comma
)
2442 trace_dump_command (args
, from_tty
)
2446 struct tracepoint
*t
;
2447 struct action_line
*action
;
2448 char *action_exp
, *next_comma
;
2449 struct cleanup
*old_cleanups
;
2450 int stepping_actions
= 0;
2451 int stepping_frame
= 0;
2453 if (!target_is_remote ())
2455 error ("Trace can only be run on remote targets.");
2459 if (tracepoint_number
== -1)
2461 warning ("No current trace frame.");
2466 if (t
->number
== tracepoint_number
)
2470 error ("No known tracepoint matches 'current' tracepoint #%d.",
2473 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2475 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2476 tracepoint_number
, traceframe_number
);
2478 /* The current frame is a trap frame if the frame PC is equal
2479 to the tracepoint PC. If not, then the current frame was
2480 collected during single-stepping. */
2482 stepping_frame
= (t
->address
!= read_pc());
2484 for (action
= t
->actions
; action
; action
= action
->next
)
2486 struct cmd_list_element
*cmd
;
2488 QUIT
; /* allow user to bail out with ^C */
2489 action_exp
= action
->action
;
2490 while (isspace (*action_exp
))
2493 /* The collection actions to be done while stepping are
2494 bracketed by the commands "while-stepping" and "end". */
2496 if (*action_exp
== '#') /* comment line */
2499 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2501 error ("Bad action list item: %s", action_exp
);
2503 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2504 stepping_actions
= 1;
2505 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2506 stepping_actions
= 0;
2507 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2509 /* Display the collected data.
2510 For the trap frame, display only what was collected at the trap.
2511 Likewise for stepping frames, display only what was collected
2512 while stepping. This means that the two boolean variables,
2513 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2514 if (stepping_frame
== stepping_actions
)
2516 do { /* repeat over a comma-separated list */
2517 QUIT
; /* allow user to bail out with ^C */
2518 if (*action_exp
== ',')
2520 while (isspace (*action_exp
))
2523 next_comma
= strchr (action_exp
, ',');
2525 if (0 == strncasecmp (action_exp
, "$reg", 4))
2526 registers_info (NULL
, from_tty
);
2527 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2528 locals_info (NULL
, from_tty
);
2529 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2530 args_info (NULL
, from_tty
);
2535 make_cleanup (replace_comma
, next_comma
);
2538 printf_filtered ("%s = ", action_exp
);
2539 output_command (action_exp
, from_tty
);
2540 printf_filtered ("\n");
2544 action_exp
= next_comma
;
2545 } while (action_exp
&& *action_exp
== ',');
2549 discard_cleanups (old_cleanups
);
2552 /* Convert the memory pointed to by mem into hex, placing result in buf.
2553 * Return a pointer to the last char put in buf (null)
2554 * "stolen" from sparc-stub.c
2557 static const char hexchars
[]="0123456789abcdef";
2559 static unsigned char *
2560 mem2hex(mem
, buf
, count
)
2571 *buf
++ = hexchars
[ch
>> 4];
2572 *buf
++ = hexchars
[ch
& 0xf];
2580 int get_traceframe_number()
2582 return traceframe_number
;
2586 /* module initialization */
2588 _initialize_tracepoint ()
2590 tracepoint_chain
= 0;
2591 tracepoint_count
= 0;
2592 traceframe_number
= -1;
2593 tracepoint_number
= -1;
2595 set_internalvar (lookup_internalvar ("tpnum"),
2596 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2597 set_internalvar (lookup_internalvar ("trace_frame"),
2598 value_from_longest (builtin_type_int
, (LONGEST
) -1));
2600 if (tracepoint_list
.list
== NULL
)
2602 tracepoint_list
.listsize
= 128;
2603 tracepoint_list
.list
= xmalloc
2604 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2606 if (tracepoint_list
.aexpr_list
== NULL
)
2608 tracepoint_list
.aexpr_listsize
= 128;
2609 tracepoint_list
.aexpr_list
= xmalloc
2610 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2613 if (stepping_list
.list
== NULL
)
2615 stepping_list
.listsize
= 128;
2616 stepping_list
.list
= xmalloc
2617 (stepping_list
.listsize
* sizeof (struct memrange
));
2620 if (stepping_list
.aexpr_list
== NULL
)
2622 stepping_list
.aexpr_listsize
= 128;
2623 stepping_list
.aexpr_list
= xmalloc
2624 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2627 add_info ("scope", scope_info
,
2628 "List the variables local to a scope");
2630 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2631 "Tracing of program execution without stopping the program.",
2634 add_info ("tracepoints", tracepoints_info
,
2635 "Status of tracepoints, or tracepoint number NUMBER.\n\
2636 Convenience variable \"$tpnum\" contains the number of the\n\
2637 last tracepoint set.");
2639 add_info_alias ("tp", "tracepoints", 1);
2641 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2642 "Save current tracepoint definitions as a script.\n\
2643 Use the 'source' command in another debug session to restore them.");
2645 add_com ("tdump", class_trace
, trace_dump_command
,
2646 "Print everything collected at the current tracepoint.");
2648 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2649 "Select a trace frame;\n\
2650 No argument means forward by one frame; '-' meand backward by one frame.",
2651 &tfindlist
, "tfind ", 1, &cmdlist
);
2653 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2654 "Select a trace frame whose PC is outside the given \
2655 range.\nUsage: tfind outside addr1, addr2",
2658 add_cmd ("range", class_trace
, trace_find_range_command
,
2659 "Select a trace frame whose PC is in the given range.\n\
2660 Usage: tfind range addr1,addr2",
2663 add_cmd ("line", class_trace
, trace_find_line_command
,
2664 "Select a trace frame by source line.\n\
2665 Argument can be a line number (with optional source file), \n\
2666 a function name, or '*' followed by an address.\n\
2667 Default argument is 'the next source line that was traced'.",
2670 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2671 "Select a trace frame by tracepoint number.\n\
2672 Default is the tracepoint for the current trace frame.",
2675 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2676 "Select a trace frame by PC.\n\
2677 Default is the current PC, or the PC of the current trace frame.",
2680 add_cmd ("end", class_trace
, trace_find_end_command
,
2681 "Synonym for 'none'.\n\
2682 De-select any trace frame and resume 'live' debugging.",
2685 add_cmd ("none", class_trace
, trace_find_none_command
,
2686 "De-select any trace frame and resume 'live' debugging.",
2689 add_cmd ("start", class_trace
, trace_find_start_command
,
2690 "Select the first trace frame in the trace buffer.",
2693 add_com ("tstatus", class_trace
, trace_status_command
,
2694 "Display the status of the current trace data collection.");
2696 add_com ("tstop", class_trace
, trace_stop_command
,
2697 "Stop trace data collection.");
2699 add_com ("tstart", class_trace
, trace_start_command
,
2700 "Start trace data collection.");
2702 add_com ("passcount", class_trace
, trace_pass_command
,
2703 "Set the passcount for a tracepoint.\n\
2704 The trace will end when the tracepoint has been passed 'count' times.\n\
2705 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2706 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2708 add_com ("end", class_trace
, end_actions_pseudocommand
,
2709 "Ends a list of commands or actions.\n\
2710 Several GDB commands allow you to enter a list of commands or actions.\n\
2711 Entering \"end\" on a line by itself is the normal way to terminate\n\
2713 Note: the \"end\" command cannot be used at the gdb prompt.");
2715 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2716 "Specify single-stepping behavior at a tracepoint.\n\
2717 Argument is number of instructions to trace in single-step mode\n\
2718 following the tracepoint. This command is normally followed by\n\
2719 one or more \"collect\" commands, to specify what to collect\n\
2720 while single-stepping.\n\n\
2721 Note: this command can only be used in a tracepoint \"actions\" list.");
2723 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2724 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2726 add_com ("collect", class_trace
, collect_pseudocommand
,
2727 "Specify one or more data items to be collected at a tracepoint.\n\
2728 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2729 collect all data (variables, registers) referenced by that expression.\n\
2730 Also accepts the following special arguments:\n\
2731 $regs -- all registers.\n\
2732 $args -- all function arguments.\n\
2733 $locals -- all variables local to the block/function scope.\n\
2734 Note: this command can only be used in a tracepoint \"actions\" list.");
2736 add_com ("actions", class_trace
, trace_actions_command
,
2737 "Specify the actions to be taken at a tracepoint.\n\
2738 Tracepoint actions may include collecting of specified data, \n\
2739 single-stepping, or enabling/disabling other tracepoints, \n\
2740 depending on target's capabilities.");
2742 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2743 "Delete specified tracepoints.\n\
2744 Arguments are tracepoint numbers, separated by spaces.\n\
2745 No argument means delete all tracepoints.",
2748 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2749 "Disable specified tracepoints.\n\
2750 Arguments are tracepoint numbers, separated by spaces.\n\
2751 No argument means disable all tracepoints.",
2754 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2755 "Enable specified tracepoints.\n\
2756 Arguments are tracepoint numbers, separated by spaces.\n\
2757 No argument means enable all tracepoints.",
2760 add_com ("trace", class_trace
, trace_command
,
2761 "Set a tracepoint at a specified line or function or address.\n\
2762 Argument may be a line number, function name, or '*' plus an address.\n\
2763 For a line number or function, trace at the start of its code.\n\
2764 If an address is specified, trace at that exact address.\n\n\
2765 Do \"help tracepoints\" for info on other tracepoint commands.");
2767 add_com_alias ("tp", "trace", class_alias
, 0);
2768 add_com_alias ("tr", "trace", class_alias
, 1);
2769 add_com_alias ("tra", "trace", class_alias
, 1);
2770 add_com_alias ("trac", "trace", class_alias
, 1);