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
;
338 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) +
339 strlen (sal
.symtab
->dirname
) + 2);
341 strcpy (t
->source_file
, sal
.symtab
->dirname
);
345 if (*(--p
) != '/') /* Will this work on Windows? */
346 strcat (t
->source_file
, "/");
347 strcat (t
->source_file
, sal
.symtab
->filename
);
350 t
->language
= current_language
->la_language
;
351 t
->input_radix
= input_radix
;
352 t
->line_number
= sal
.line
;
353 t
->enabled
= enabled
;
357 t
->addr_string
= NULL
;
359 /* Add this tracepoint to the end of the chain
360 so that a list of tracepoints will come out in order
361 of increasing numbers. */
363 tc
= tracepoint_chain
;
365 tracepoint_chain
= t
;
372 discard_cleanups (old_chain
);
376 /* Set a tracepoint according to ARG (function, linenum or *address) */
378 trace_command (arg
, from_tty
)
382 char **canonical
= (char **)NULL
;
383 struct symtabs_and_lines sals
;
384 struct symtab_and_line sal
;
385 struct tracepoint
*t
;
386 char *addr_start
= 0, *addr_end
= 0;
390 error ("trace command requires an argument");
392 if (from_tty
&& info_verbose
)
393 printf_filtered ("TRACE %s\n", arg
);
396 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
399 return; /* ??? Presumably decode_line_1 has already warned? */
401 /* Resolve all line numbers to PC's */
402 for (i
= 0; i
< sals
.nelts
; i
++)
403 resolve_sal_pc (&sals
.sals
[i
]);
405 /* Now set all the tracepoints. */
406 for (i
= 0; i
< sals
.nelts
; i
++)
410 t
= set_raw_tracepoint (sal
);
411 set_tracepoint_count (tracepoint_count
+ 1);
412 t
->number
= tracepoint_count
;
414 /* If a canonical line spec is needed use that instead of the
416 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
417 t
->addr_string
= canonical
[i
];
419 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
423 /* Let the UI know of any additions */
424 if (create_tracepoint_hook
)
425 create_tracepoint_hook (t
);
430 printf_filtered ("Multiple tracepoints were set.\n");
431 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
435 /* Tell the user we have just set a tracepoint TP. */
439 struct tracepoint
*tp
;
441 printf_filtered ("Tracepoint %d", tp
->number
);
443 if (addressprint
|| (tp
->source_file
== NULL
))
445 printf_filtered (" at ");
446 print_address_numeric (tp
->address
, 1, gdb_stdout
);
449 printf_filtered (": file %s, line %d.",
450 tp
->source_file
, tp
->line_number
);
452 printf_filtered ("\n");
455 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
458 tracepoints_info (tpnum_exp
, from_tty
)
462 struct tracepoint
*t
;
463 struct action_line
*action
;
464 int found_a_tracepoint
= 0;
465 char wrap_indent
[80];
470 tpnum
= parse_and_eval_address (tpnum_exp
);
473 if (tpnum
== -1 || tpnum
== t
->number
)
475 extern int addressprint
; /* print machine addresses? */
477 if (!found_a_tracepoint
++)
479 printf_filtered ("Num Enb ");
481 printf_filtered ("Address ");
482 printf_filtered ("PassC StepC What\n");
484 strcpy (wrap_indent
, " ");
486 strcat (wrap_indent
, " ");
488 printf_filtered ("%-3d %-3s ", t
->number
,
489 t
->enabled
== enabled
? "y" : "n");
491 printf_filtered ("%s ",
492 local_hex_string_custom ((unsigned long) t
->address
,
494 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
498 sym
= find_pc_function (t
->address
);
501 fputs_filtered ("in ", gdb_stdout
);
502 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
503 wrap_here (wrap_indent
);
504 fputs_filtered (" at ", gdb_stdout
);
506 fputs_filtered (t
->source_file
, gdb_stdout
);
507 printf_filtered (":%d", t
->line_number
);
510 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
512 printf_filtered ("\n");
515 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
516 for (action
= t
->actions
; action
; action
= action
->next
)
518 printf_filtered ("\t%s\n", action
->action
);
522 if (!found_a_tracepoint
)
525 printf_filtered ("No tracepoints.\n");
527 printf_filtered ("No tracepoint number %d.\n", tpnum
);
531 /* Optimization: the code to parse an enable, disable, or delete TP command
532 is virtually identical except for whether it performs an enable, disable,
533 or delete. Therefore I've combined them into one function with an opcode.
535 enum tracepoint_opcode
542 /* This function implements enable, disable and delete. */
544 tracepoint_operation (t
, from_tty
, opcode
)
545 struct tracepoint
*t
;
547 enum tracepoint_opcode opcode
;
549 struct tracepoint
*t2
;
553 t
->enabled
= enabled
;
554 if (modify_tracepoint_hook
)
555 modify_tracepoint_hook (t
);
558 t
->enabled
= disabled
;
559 if (modify_tracepoint_hook
)
560 modify_tracepoint_hook (t
);
563 if (tracepoint_chain
== t
)
564 tracepoint_chain
= t
->next
;
573 /* Let the UI know of any deletions */
574 if (delete_tracepoint_hook
)
575 delete_tracepoint_hook (t
);
578 free (t
->addr_string
);
580 free (t
->source_file
);
589 /* Utility: parse a tracepoint number and look it up in the list. */
591 get_tracepoint_by_number (arg
)
594 struct tracepoint
*t
;
600 error ("Bad tracepoint argument");
602 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
603 tpnum
= tracepoint_count
;
604 else if (**arg
== '$') /* handle convenience variable */
606 /* Make a copy of the name, so we can null-terminate it
607 to pass to lookup_internalvar(). */
609 while (isalnum(*end
) || *end
== '_')
611 copy
= (char *) alloca (end
- *arg
);
612 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
613 copy
[end
- *arg
- 1] = '\0';
616 val
= value_of_internalvar (lookup_internalvar (copy
));
617 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
618 error ("Convenience variable must have integral type.");
619 tpnum
= (int) value_as_long (val
);
621 else /* handle tracepoint number */
623 tpnum
= strtol (*arg
, arg
, 0);
624 if (tpnum
== 0) /* possible strtol failure */
625 while (**arg
&& !isspace (**arg
))
626 (*arg
)++; /* advance to next white space, if any */
629 if (t
->number
== tpnum
)
633 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
637 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
639 map_args_over_tracepoints (args
, from_tty
, opcode
)
642 enum tracepoint_opcode opcode
;
644 struct tracepoint
*t
, *tmp
;
648 if (args
== 0 || *args
== 0) /* do them all */
649 ALL_TRACEPOINTS_SAFE (t
, tmp
)
650 tracepoint_operation (t
, from_tty
, opcode
);
654 QUIT
; /* give user option to bail out with ^C */
655 if (t
= get_tracepoint_by_number (&args
))
656 tracepoint_operation (t
, from_tty
, opcode
);
657 while (*args
== ' ' || *args
== '\t')
662 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
664 enable_trace_command (args
, from_tty
)
669 map_args_over_tracepoints (args
, from_tty
, enable
);
672 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
674 disable_trace_command (args
, from_tty
)
679 map_args_over_tracepoints (args
, from_tty
, disable
);
682 /* Remove a tracepoint (or all if no argument) */
684 delete_trace_command (args
, from_tty
)
689 if (!args
|| !*args
) /* No args implies all tracepoints; */
690 if (from_tty
) /* confirm only if from_tty... */
691 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
692 if (!query ("Delete all tracepoints? "))
695 map_args_over_tracepoints (args
, from_tty
, delete);
698 /* Set passcount for tracepoint.
700 First command argument is passcount, second is tracepoint number.
701 If tracepoint number omitted, apply to most recently defined.
702 Also accepts special argument "all". */
705 trace_pass_command (args
, from_tty
)
709 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
712 if (args
== 0 || *args
== 0)
713 error ("PASS command requires an argument (count + optional TP num)");
715 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
717 while (*args
&& isspace (*args
))
720 if (*args
&& strncasecmp (args
, "all", 3) == 0)
721 args
+= 3; /* skip special argument "all" */
723 t1
= get_tracepoint_by_number (&args
);
726 error ("Junk at end of arguments.");
729 return; /* error, bad tracepoint number */
732 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
734 t2
->pass_count
= count
;
735 if (modify_tracepoint_hook
)
736 modify_tracepoint_hook (t2
);
738 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
743 /* ACTIONS functions: */
745 /* Prototypes for action-parsing utility commands */
746 static void read_actions
PARAMS((struct tracepoint
*));
747 static char *parse_and_eval_memrange
PARAMS ((char *,
753 /* The three functions:
754 collect_pseudocommand,
755 while_stepping_pseudocommand, and
756 end_actions_pseudocommand
757 are placeholders for "commands" that are actually ONLY to be used
758 within a tracepoint action list. If the actual function is ever called,
759 it means that somebody issued the "command" at the top level,
760 which is always an error. */
763 end_actions_pseudocommand (args
, from_tty
)
767 error ("This command cannot be used at the top level.");
771 while_stepping_pseudocommand (args
, from_tty
)
775 error ("This command can only be used in a tracepoint actions list.");
779 collect_pseudocommand (args
, from_tty
)
783 error ("This command can only be used in a tracepoint actions list.");
786 /* Enter a list of actions for a tracepoint. */
788 trace_actions_command (args
, from_tty
)
792 struct tracepoint
*t
;
795 char *end_msg
= "End with a line saying just \"end\".";
797 if (t
= get_tracepoint_by_number (&args
))
799 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
804 if (readline_begin_hook
)
805 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
806 else if (input_from_terminal_p ())
807 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
811 t
->step_count
= 0; /* read_actions may set this */
814 if (readline_end_hook
)
815 (*readline_end_hook
) ();
817 /* tracepoints_changed () */
819 /* else error, just return; */
822 /* worker function */
825 struct tracepoint
*t
;
828 char *prompt1
= "> ", *prompt2
= " > ";
829 char *prompt
= prompt1
;
830 enum actionline_type linetype
;
831 extern FILE *instream
;
832 struct action_line
*next
= NULL
, *temp
;
833 struct cleanup
*old_chain
;
835 /* Control-C quits instantly if typed while in this loop
836 since it should not wait until the user types a newline. */
840 signal (STOP_SIGNAL
, stop_sig
);
842 old_chain
= make_cleanup (free_actions
, (void *) t
);
845 /* Make sure that all output has been output. Some machines may let
846 you get away with leaving out some of the gdb_flush, but not all. */
848 gdb_flush (gdb_stdout
);
849 gdb_flush (gdb_stderr
);
851 if (readline_hook
&& instream
== NULL
)
852 line
= (*readline_hook
) (prompt
);
853 else if (instream
== stdin
&& ISATTY (instream
))
855 line
= readline (prompt
);
856 if (line
&& *line
) /* add it to command history */
860 line
= gdb_readline (0);
862 linetype
= validate_actionline (&line
, t
);
863 if (linetype
== BADLINE
)
864 continue; /* already warned -- collect another line */
866 temp
= xmalloc (sizeof (struct action_line
));
870 if (next
== NULL
) /* first action for this tracepoint? */
871 t
->actions
= next
= temp
;
878 if (linetype
== STEPPING
) /* begin "while-stepping" */
879 if (prompt
== prompt2
)
881 warning ("Already processing 'while-stepping'");
885 prompt
= prompt2
; /* change prompt for stepping actions */
886 else if (linetype
== END
)
887 if (prompt
== prompt2
)
889 prompt
= prompt1
; /* end of single-stepping actions */
892 { /* end of actions */
893 if (t
->actions
->next
== NULL
)
895 /* an "end" all by itself with no other actions means
896 this tracepoint has no actions. Discard empty list. */
904 signal (STOP_SIGNAL
, SIG_DFL
);
907 discard_cleanups (old_chain
);
910 /* worker function */
912 validate_actionline (line
, t
)
914 struct tracepoint
*t
;
916 struct cmd_list_element
*c
;
917 struct expression
*exp
= NULL
;
918 value_ptr temp
, temp2
;
919 struct cleanup
*old_chain
= NULL
;
922 for (p
= *line
; isspace (*p
); )
925 /* symbol lookup etc. */
926 if (*p
== '\0') /* empty line: just prompt for another line. */
929 if (*p
== '#') /* comment line */
932 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
935 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
939 if (c
->function
.cfunc
== collect_pseudocommand
)
941 struct agent_expr
*aexpr
;
942 struct agent_reqs areqs
;
944 do { /* repeat over a comma-separated list */
945 QUIT
; /* allow user to bail out with ^C */
949 if (*p
== '$') /* look for special pseudo-symbols */
952 bfd_signed_vma offset
;
954 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
955 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
956 (0 == strncasecmp ("loc", p
+ 1, 3)))
961 /* else fall thru, treat p as an expression and parse it! */
963 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
964 old_chain
= make_cleanup (free_current_contents
, &exp
);
966 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
967 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
969 warning ("%s is constant (value %d): will not be collected.",
970 SYMBOL_NAME (exp
->elts
[2].symbol
),
971 SYMBOL_VALUE (exp
->elts
[2].symbol
));
974 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
976 warning ("%s is optimized away and cannot be collected.",
977 SYMBOL_NAME (exp
->elts
[2].symbol
));
981 /* we have something to collect, make sure that the expr to
982 bytecode translator can handle it and that it's not too long */
983 aexpr
= gen_trace_for_expr(exp
);
984 (void) make_cleanup (free_agent_expr
, aexpr
);
986 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
987 error ("expression too complicated, try simplifying");
989 ax_reqs(aexpr
, &areqs
);
990 (void) make_cleanup (free
, areqs
.reg_mask
);
992 if (areqs
.flaw
!= agent_flaw_none
)
993 error ("malformed expression");
995 if (areqs
.min_height
< 0)
996 error ("gdb: Internal error: expression has min height < 0");
998 if (areqs
.max_height
> 20)
999 error ("expression too complicated, try simplifying");
1001 do_cleanups (old_chain
);
1002 } while (p
&& *p
++ == ',');
1005 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
1007 char *steparg
; /* in case warning is necessary */
1009 while (isspace (*p
))
1014 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1016 warning ("bad step-count: command ignored.", *line
);
1021 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1025 warning ("'%s' is not a supported tracepoint action.", *line
);
1030 /* worker function */
1033 struct tracepoint
*t
;
1035 struct action_line
*line
, *next
;
1037 for (line
= t
->actions
; line
; line
= next
)
1041 free (line
->action
);
1048 int type
; /* 0 for absolute memory range, else basereg number */
1049 bfd_signed_vma start
;
1053 struct collection_list
{
1054 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1057 struct memrange
*list
;
1058 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1059 long next_aexpr_elt
;
1060 struct agent_expr
**aexpr_list
;
1062 } tracepoint_list
, stepping_list
;
1064 /* MEMRANGE functions: */
1066 static int memrange_cmp
PARAMS ((const void *, const void *));
1068 /* compare memranges for qsort */
1070 memrange_cmp (va
, vb
)
1074 const struct memrange
*a
= va
, *b
= vb
;
1076 if (a
->type
< b
->type
)
1078 if (a
->type
> b
->type
)
1082 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1083 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1087 if (a
->start
< b
->start
)
1089 if (a
->start
> b
->start
)
1095 /* Sort the memrange list using qsort, and merge adjacent memranges */
1097 memrange_sortmerge (memranges
)
1098 struct collection_list
*memranges
;
1102 qsort (memranges
->list
, memranges
->next_memrange
,
1103 sizeof (struct memrange
), memrange_cmp
);
1104 if (memranges
->next_memrange
> 0)
1106 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1108 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1109 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1110 MAX_REGISTER_VIRTUAL_SIZE
)
1112 /* memrange b starts before memrange a ends; merge them. */
1113 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1114 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1115 continue; /* next b, same a */
1119 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1120 sizeof (struct memrange
));
1122 memranges
->next_memrange
= a
+ 1;
1126 /* Add a register to a collection list */
1128 add_register (collection
, regno
)
1129 struct collection_list
*collection
;
1130 unsigned long regno
;
1133 printf_filtered ("collect register %d\n", regno
);
1134 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1135 error ("Internal: register number %d too large for tracepoint",
1137 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1140 /* Add a memrange to a collection list */
1142 add_memrange (memranges
, type
, base
, len
)
1143 struct collection_list
*memranges
;
1145 bfd_signed_vma base
;
1149 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1150 /* type: 0 == memory, n == basereg */
1151 memranges
->list
[memranges
->next_memrange
].type
= type
;
1152 /* base: addr if memory, offset if reg relative. */
1153 memranges
->list
[memranges
->next_memrange
].start
= base
;
1154 /* len: we actually save end (base + len) for convenience */
1155 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1156 memranges
->next_memrange
++;
1157 if (memranges
->next_memrange
>= memranges
->listsize
)
1159 memranges
->listsize
*= 2;
1160 memranges
->list
= xrealloc (memranges
->list
,
1161 memranges
->listsize
);
1164 if (type
!= -1) /* better collect the base register! */
1165 add_register (memranges
, type
);
1168 /* Add a symbol to a collection list */
1170 collect_symbol (collect
, sym
)
1171 struct collection_list
*collect
;
1176 bfd_signed_vma offset
;
1178 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1179 switch (SYMBOL_CLASS (sym
)) {
1181 printf_filtered ("%s: don't know symbol class %d\n",
1182 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1185 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1186 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1189 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1191 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1192 SYMBOL_NAME (sym
), len
, offset
);
1193 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1197 reg
= SYMBOL_VALUE (sym
);
1199 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1200 add_register (collect
, reg
);
1204 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1205 printf_filtered (" (will not collect %s)\n",
1208 case LOC_REGPARM_ADDR
:
1209 reg
= SYMBOL_VALUE (sym
);
1213 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1214 SYMBOL_NAME (sym
), len
, offset
, reg
);
1216 add_memrange (collect
, reg
, offset
, len
);
1220 offset
= SYMBOL_VALUE (sym
);
1224 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1225 SYMBOL_NAME (sym
), len
, offset
, reg
);
1227 add_memrange (collect
, reg
, offset
, len
);
1230 case LOC_BASEREG_ARG
:
1231 reg
= SYMBOL_BASEREG (sym
);
1232 offset
= SYMBOL_VALUE (sym
);
1235 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1236 SYMBOL_NAME (sym
), len
, offset
, reg
);
1238 add_memrange (collect
, reg
, offset
, len
);
1240 case LOC_UNRESOLVED
:
1241 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1243 case LOC_OPTIMIZED_OUT
:
1244 printf_filtered ("%s has been optimized out of existance.\n",
1250 /* Add all locals (or args) symbols to collection list */
1252 add_local_symbols (collect
, pc
, type
)
1253 struct collection_list
*collect
;
1258 struct block
*block
;
1259 int i
, nsyms
, count
= 0;
1261 block
= block_for_pc (pc
);
1264 QUIT
; /* allow user to bail out with ^C */
1265 nsyms
= BLOCK_NSYMS (block
);
1266 for (i
= 0; i
< nsyms
; i
++)
1268 sym
= BLOCK_SYM (block
, i
);
1269 switch (SYMBOL_CLASS (sym
)) {
1274 if (type
== 'L') /* collecting Locals */
1277 collect_symbol (collect
, sym
);
1284 case LOC_REGPARM_ADDR
:
1285 case LOC_BASEREG_ARG
:
1286 if (type
== 'A') /* collecting Arguments */
1289 collect_symbol (collect
, sym
);
1293 if (BLOCK_FUNCTION (block
))
1296 block
= BLOCK_SUPERBLOCK (block
);
1299 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1302 /* worker function */
1304 clear_collection_list (list
)
1305 struct collection_list
*list
;
1309 list
->next_memrange
= 0;
1310 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1312 free_agent_expr(list
->aexpr_list
[ndx
]);
1313 list
->aexpr_list
[ndx
] = NULL
;
1315 list
->next_aexpr_elt
= 0;
1316 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1319 /* reduce a collection list to string form (for gdb protocol) */
1321 stringify_collection_list (list
, string
)
1322 struct collection_list
*list
;
1325 char temp_buf
[2048];
1328 char *(*str_list
)[];
1332 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1333 str_list
= (char *(*)[])xmalloc(count
* sizeof (char *));
1335 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1336 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1338 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1341 printf_filtered ("\nCollecting registers (mask): 0x");
1346 QUIT
; /* allow user to bail out with ^C */
1348 printf_filtered ("%02X", list
->regs_mask
[i
]);
1349 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1352 (*str_list
)[ndx
] = savestring(temp_buf
, end
- temp_buf
);
1356 printf_filtered ("\n");
1357 if (list
->next_memrange
> 0 && info_verbose
)
1358 printf_filtered ("Collecting memranges: \n");
1359 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1361 QUIT
; /* allow user to bail out with ^C */
1363 printf_filtered ("(%d, 0x%x, %d)\n",
1365 list
->list
[i
].start
,
1366 list
->list
[i
].end
- list
->list
[i
].start
);
1367 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1369 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1374 sprintf (end
, "M%X,%X,%X",
1376 list
->list
[i
].start
,
1377 list
->list
[i
].end
- list
->list
[i
].start
);
1378 count
+= strlen (end
);
1379 end
+= strlen (end
);
1382 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1384 QUIT
; /* allow user to bail out with ^C */
1385 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1387 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1392 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1393 end
+= 10; /* 'X' + 8 hex digits + ',' */
1396 end
= mem2hex(list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1397 count
+= 2 * list
->aexpr_list
[i
]->len
;
1402 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1407 (*str_list
)[ndx
] = NULL
;
1416 free_actions_list(actions_list
)
1417 char **actions_list
;
1421 if (actions_list
== 0)
1424 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1425 free(actions_list
[ndx
]);
1430 /* render all actions into gdb protocol */
1432 encode_actions (t
, tdp_actions
, stepping_actions
)
1433 struct tracepoint
*t
;
1434 char ***tdp_actions
;
1435 char ***stepping_actions
;
1437 static char tdp_buff
[2048], step_buff
[2048];
1439 struct expression
*exp
= NULL
;
1440 struct action_line
*action
;
1441 bfd_signed_vma offset
;
1444 struct collection_list
*collect
;
1445 struct cmd_list_element
*cmd
;
1446 struct agent_expr
*aexpr
;
1448 clear_collection_list (&tracepoint_list
);
1449 clear_collection_list (&stepping_list
);
1450 collect
= &tracepoint_list
;
1452 *tdp_actions
= NULL
;
1453 *stepping_actions
= NULL
;
1455 for (action
= t
->actions
; action
; action
= action
->next
)
1457 QUIT
; /* allow user to bail out with ^C */
1458 action_exp
= action
->action
;
1459 while (isspace (*action_exp
))
1462 if (*action_exp
== '#') /* comment line */
1465 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1467 error ("Bad action list item: %s", action_exp
);
1469 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1471 do { /* repeat over a comma-separated list */
1472 QUIT
; /* allow user to bail out with ^C */
1473 while (isspace (*action_exp
))
1476 if (0 == strncasecmp ("$reg", action_exp
, 4))
1478 for (i
= 0; i
< NUM_REGS
; i
++)
1479 add_register (collect
, i
);
1480 action_exp
= strchr (action_exp
, ','); /* more? */
1482 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1484 add_local_symbols (collect
, t
->address
, 'A');
1485 action_exp
= strchr (action_exp
, ','); /* more? */
1487 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1489 add_local_symbols (collect
, t
->address
, 'L');
1490 action_exp
= strchr (action_exp
, ','); /* more? */
1494 unsigned long addr
, len
;
1495 struct cleanup
*old_chain
= NULL
;
1496 struct cleanup
*old_chain1
= NULL
;
1497 struct agent_reqs areqs
;
1499 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1501 old_chain
= make_cleanup (free_current_contents
, &exp
);
1503 aexpr
= gen_trace_for_expr (exp
);
1505 old_chain1
= make_cleanup (free_agent_expr
, aexpr
);
1507 ax_reqs (aexpr
, &areqs
);
1508 if (areqs
.flaw
!= agent_flaw_none
)
1509 error ("malformed expression");
1511 if (areqs
.min_height
< 0)
1512 error ("gdb: Internal error: expression has min height < 0");
1513 if (areqs
.max_height
> 20)
1514 error ("expression too complicated, try simplifying");
1516 discard_cleanups (old_chain1
);
1517 add_aexpr (collect
, aexpr
);
1519 /* take care of the registers */
1520 if (areqs
.reg_mask_len
> 0)
1525 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1527 QUIT
; /* allow user to bail out with ^C */
1528 if (areqs
.reg_mask
[ndx1
] != 0)
1530 /* assume chars have 8 bits */
1531 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1532 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1533 /* it's used -- record it */
1534 add_register (collect
, ndx1
* 8 + ndx2
);
1538 do_cleanups (old_chain
);
1540 } while (action_exp
&& *action_exp
++ == ',');
1542 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1544 collect
= &stepping_list
;
1546 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1548 if (collect
== &stepping_list
) /* end stepping actions */
1549 collect
= &tracepoint_list
;
1551 break; /* end tracepoint actions */
1554 memrange_sortmerge (&tracepoint_list
);
1555 memrange_sortmerge (&stepping_list
);
1557 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1558 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1562 add_aexpr(collect
, aexpr
)
1563 struct collection_list
*collect
;
1564 struct agent_expr
*aexpr
;
1566 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1568 collect
->aexpr_list
=
1569 xrealloc (collect
->aexpr_list
,
1570 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1571 collect
->aexpr_listsize
*= 2;
1573 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1574 collect
->next_aexpr_elt
++;
1578 static char target_buf
[2048];
1582 Tell target to clear any previous trace experiment.
1583 Walk the list of tracepoints, and send them (and their actions)
1584 to the target. If no errors,
1585 Tell target to start a new trace experiment. */
1588 trace_start_command (args
, from_tty
)
1591 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1592 struct tracepoint
*t
;
1595 char **stepping_actions
;
1597 struct cleanup
*old_chain
= NULL
;
1599 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1601 if (target_is_remote ())
1604 remote_get_noisy_reply (target_buf
);
1605 if (strcmp (target_buf
, "OK"))
1606 error ("Target does not support this command.");
1610 int ss_count
; /* if actions include singlestepping */
1611 int disable_mask
; /* ??? */
1612 int enable_mask
; /* ??? */
1614 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1615 t
->enabled
== enabled
? 'E' : 'D',
1616 t
->step_count
, t
->pass_count
);
1621 remote_get_noisy_reply (target_buf
);
1622 if (strcmp (target_buf
, "OK"))
1623 error ("Target does not support tracepoints.");
1627 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1628 old_chain
= make_cleanup (free_actions_list
, tdp_actions
);
1629 (void) make_cleanup (free_actions_list
, stepping_actions
);
1631 /* do_single_steps (t); */
1634 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1636 QUIT
; /* allow user to bail out with ^C */
1637 sprintf (buf
, "QTDP:-%x:%x:%s%c",
1638 t
->number
, t
->address
,
1640 ((tdp_actions
[ndx
+1] || stepping_actions
)
1643 remote_get_noisy_reply (target_buf
);
1644 if (strcmp (target_buf
, "OK"))
1645 error ("Error on target while setting tracepoints.");
1648 if (stepping_actions
)
1650 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1652 QUIT
; /* allow user to bail out with ^C */
1653 sprintf (buf
, "QTDP:-%x:%x:%s%s%s",
1654 t
->number
, t
->address
,
1655 ((ndx
== 0) ? "S" : ""),
1656 stepping_actions
[ndx
],
1657 (stepping_actions
[ndx
+1] ? "-" : ""));
1659 remote_get_noisy_reply (target_buf
);
1660 if (strcmp (target_buf
, "OK"))
1661 error ("Error on target while setting tracepoints.");
1665 do_cleanups (old_chain
);
1669 remote_get_noisy_reply (target_buf
);
1670 if (strcmp (target_buf
, "OK"))
1671 error ("Bogus reply from target: %s", target_buf
);
1672 set_traceframe_num (-1); /* all old traceframes invalidated */
1673 set_tracepoint_num (-1);
1674 set_traceframe_context(-1);
1675 trace_running_p
= 1;
1678 error ("Trace can only be run on remote targets.");
1683 trace_stop_command (args
, from_tty
)
1686 { /* STUB_COMM IS_IMPLEMENTED */
1687 if (target_is_remote ())
1690 remote_get_noisy_reply (target_buf
);
1691 if (strcmp (target_buf
, "OK"))
1692 error ("Bogus reply from target: %s", target_buf
);
1693 trace_running_p
= 0;
1696 error ("Trace can only be run on remote targets.");
1699 unsigned long trace_running_p
;
1701 /* tstatus command */
1703 trace_status_command (args
, from_tty
)
1706 { /* STUB_COMM IS_IMPLEMENTED */
1707 if (target_is_remote ())
1709 putpkt ("qTStatus");
1710 remote_get_noisy_reply (target_buf
);
1712 if (target_buf
[0] != 'T' ||
1713 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1714 error ("Bogus reply from target: %s", target_buf
);
1716 /* exported for use by the GUI */
1717 trace_running_p
= (target_buf
[1] == '1');
1720 error ("Trace can only be run on remote targets.");
1723 /* Worker function for the various flavors of the tfind command */
1725 finish_tfind_command (msg
, from_tty
)
1729 int target_frameno
= -1, target_tracept
= -1;
1730 CORE_ADDR old_frame_addr
;
1731 struct symbol
*old_func
;
1734 old_frame_addr
= FRAME_FP (get_current_frame ());
1735 old_func
= find_pc_function (read_pc ());
1738 reply
= remote_get_noisy_reply (msg
);
1740 while (reply
&& *reply
)
1743 if ((target_frameno
= strtol (++reply
, &reply
, 16)) == -1)
1745 /* A request for a non-existant trace frame has failed.
1746 Our response will be different, depending on FROM_TTY:
1748 If FROM_TTY is true, meaning that this command was
1749 typed interactively by the user, then give an error
1750 and DO NOT change the state of traceframe_number etc.
1752 However if FROM_TTY is false, meaning that we're either
1753 in a script, a loop, or a user-defined command, then
1754 DON'T give an error, but DO change the state of
1755 traceframe_number etc. to invalid.
1757 The rationalle is that if you typed the command, you
1758 might just have committed a typo or something, and you'd
1759 like to NOT lose your current debugging state. However
1760 if you're in a user-defined command or especially in a
1761 loop, then you need a way to detect that the command
1762 failed WITHOUT aborting. This allows you to write
1763 scripts that search thru the trace buffer until the end,
1764 and then continue on to do something else. */
1767 error ("Target failed to find requested trace frame.");
1771 printf_filtered ("End of trace buffer.\n");
1772 /* The following will not recurse, since it's special-cased */
1773 trace_find_command ("-1", from_tty
);
1774 reply
= NULL
; /* break out of loop,
1775 (avoid recursive nonsense) */
1780 if ((target_tracept
= strtol (++reply
, &reply
, 16)) == -1)
1781 error ("Target failed to find requested trace frame.");
1783 case 'O': /* "OK"? */
1784 if (reply
[1] == 'K' && reply
[2] == '\0')
1787 error ("Bogus reply from target: %s", reply
);
1790 error ("Bogus reply from target: %s", reply
);
1793 flush_cached_frames ();
1794 registers_changed ();
1795 select_frame (get_current_frame (), 0);
1796 set_traceframe_num (target_frameno
);
1797 set_tracepoint_num (target_tracept
);
1798 if (target_frameno
== -1)
1799 set_traceframe_context (-1);
1801 set_traceframe_context (read_pc ());
1807 /* NOTE: in immitation of the step command, try to determine
1808 whether we have made a transition from one function to another.
1809 If so, we'll print the "stack frame" (ie. the new function and
1810 it's arguments) -- otherwise we'll just show the new source line.
1812 This determination is made by checking (1) whether the current
1813 function has changed, and (2) whether the current FP has changed.
1814 Hack: if the FP wasn't collected, either at the current or the
1815 previous frame, assume that the FP has NOT changed. */
1817 if (old_func
== find_pc_function (read_pc ()) &&
1818 (old_frame_addr
== 0 ||
1819 FRAME_FP (get_current_frame ()) == 0 ||
1820 old_frame_addr
== FRAME_FP (get_current_frame ())))
1825 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1830 /* trace_find_command takes a trace frame number n,
1831 sends "QTFrame:<n>" to the target,
1832 and accepts a reply that may contain several optional pieces
1833 of information: a frame number, a tracepoint number, and an
1834 indication of whether this is a trap frame or a stepping frame.
1836 The minimal response is just "OK" (which indicates that the
1837 target does not give us a frame number or a tracepoint number).
1838 Instead of that, the target may send us a string containing
1840 F<hexnum> (gives the selected frame number)
1841 T<hexnum> (gives the selected tracepoint number)
1846 trace_find_command (args
, from_tty
)
1849 { /* STUB_COMM PART_IMPLEMENTED */
1850 /* this should only be called with a numeric argument */
1852 int target_frameno
= -1, target_tracept
= -1, target_stepfrm
= 0;
1855 if (target_is_remote ())
1857 if (args
== 0 || *args
== 0)
1858 { /* TFIND with no args means find NEXT trace frame. */
1859 if (traceframe_number
== -1)
1860 frameno
= 0; /* "next" is first one */
1862 frameno
= traceframe_number
+ 1;
1864 else if (0 == strcmp (args
, "-"))
1866 if (traceframe_number
== -1)
1867 error ("not debugging trace buffer");
1868 else if (from_tty
&& traceframe_number
== 0)
1869 error ("already at start of trace buffer");
1871 frameno
= traceframe_number
- 1;
1874 frameno
= parse_and_eval_address (args
);
1877 error ("invalid input (%d is less than zero)", frameno
);
1879 sprintf (target_buf
, "QTFrame:%x", frameno
);
1880 finish_tfind_command (target_buf
, from_tty
);
1883 error ("Trace can only be run on remote targets.");
1888 trace_find_end_command (args
, from_tty
)
1892 trace_find_command ("-1", from_tty
);
1897 trace_find_none_command (args
, from_tty
)
1901 trace_find_command ("-1", from_tty
);
1906 trace_find_start_command (args
, from_tty
)
1910 trace_find_command ("0", from_tty
);
1913 /* tfind pc command */
1915 trace_find_pc_command (args
, from_tty
)
1918 { /* STUB_COMM PART_IMPLEMENTED */
1923 if (target_is_remote ())
1925 if (args
== 0 || *args
== 0)
1926 pc
= read_pc (); /* default is current pc */
1928 pc
= parse_and_eval_address (args
);
1930 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
1931 finish_tfind_command (target_buf
, from_tty
);
1934 error ("Trace can only be run on remote targets.");
1937 /* tfind tracepoint command */
1939 trace_find_tracepoint_command (args
, from_tty
)
1942 { /* STUB_COMM PART_IMPLEMENTED */
1943 int target_frameno
, tdp
;
1946 if (target_is_remote ())
1948 if (args
== 0 || *args
== 0)
1949 if (tracepoint_number
== -1)
1950 error ("No current tracepoint -- please supply an argument.");
1952 tdp
= tracepoint_number
; /* default is current TDP */
1954 tdp
= parse_and_eval_address (args
);
1956 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
1957 finish_tfind_command (target_buf
, from_tty
);
1960 error ("Trace can only be run on remote targets.");
1963 /* TFIND LINE command:
1965 This command will take a sourceline for argument, just like BREAK
1966 or TRACE (ie. anything that "decode_line_1" can handle).
1968 With no argument, this command will find the next trace frame
1969 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1972 trace_find_line_command (args
, from_tty
)
1975 { /* STUB_COMM PART_IMPLEMENTED */
1976 static CORE_ADDR start_pc
, end_pc
;
1977 struct symtabs_and_lines sals
;
1978 struct symtab_and_line sal
;
1981 struct cleanup
*old_chain
;
1983 if (target_is_remote ())
1985 if (args
== 0 || *args
== 0)
1987 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
1989 sals
.sals
= (struct symtab_and_line
*)
1990 xmalloc (sizeof (struct symtab_and_line
));
1995 sals
= decode_line_spec (args
, 1);
1999 old_chain
= make_cleanup (free
, sals
.sals
);
2000 if (sal
.symtab
== 0)
2002 printf_filtered ("TFIND: No line number information available");
2005 /* This is useful for "info line *0x7f34". If we can't tell the
2006 user about a source line, at least let them have the symbolic
2008 printf_filtered (" for address ");
2010 print_address (sal
.pc
, gdb_stdout
);
2011 printf_filtered (";\n -- will attempt to find by PC. \n");
2015 printf_filtered (".\n");
2016 return; /* no line, no PC; what can we do? */
2019 else if (sal
.line
> 0
2020 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2022 if (start_pc
== end_pc
)
2024 printf_filtered ("Line %d of \"%s\"",
2025 sal
.line
, sal
.symtab
->filename
);
2027 printf_filtered (" is at address ");
2028 print_address (start_pc
, gdb_stdout
);
2030 printf_filtered (" but contains no code.\n");
2031 sal
= find_pc_line (start_pc
, 0);
2033 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2035 printf_filtered ("Attempting to find line %d instead.\n",
2038 error ("Cannot find a good line.");
2042 /* Is there any case in which we get here, and have an address
2043 which the user would want to see? If we have debugging symbols
2044 and no line numbers? */
2045 error ("Line number %d is out of range for \"%s\".\n",
2046 sal
.line
, sal
.symtab
->filename
);
2048 if (args
&& *args
) /* find within range of stated line */
2049 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
2050 else /* find OUTSIDE OF range of CURRENT line */
2051 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
2052 finish_tfind_command (target_buf
, from_tty
);
2053 do_cleanups (old_chain
);
2056 error ("Trace can only be run on remote targets.");
2059 /* tfind range command */
2061 trace_find_range_command (args
, from_tty
)
2064 { /* STUB_COMM PART_IMPLEMENTED */
2065 static CORE_ADDR start
, stop
;
2069 if (target_is_remote ())
2071 if (args
== 0 || *args
== 0)
2072 { /* XXX FIXME: what should default behavior be? */
2073 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2077 if (0 != (tmp
= strchr (args
, ',' )))
2079 *tmp
++ = '\0'; /* terminate start address */
2080 while (isspace (*tmp
))
2082 start
= parse_and_eval_address (args
);
2083 stop
= parse_and_eval_address (tmp
);
2086 { /* no explicit end address? */
2087 start
= parse_and_eval_address (args
);
2088 stop
= start
+ 1; /* ??? */
2091 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2092 finish_tfind_command (target_buf
, from_tty
);
2095 error ("Trace can only be run on remote targets.");
2098 /* tfind outside command */
2100 trace_find_outside_command (args
, from_tty
)
2103 { /* STUB_COMM PART_IMPLEMENTED */
2104 CORE_ADDR start
, stop
;
2108 if (target_is_remote ())
2110 if (args
== 0 || *args
== 0)
2111 { /* XXX FIXME: what should default behavior be? */
2112 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2116 if (0 != (tmp
= strchr (args
, ',' )))
2118 *tmp
++ = '\0'; /* terminate start address */
2119 while (isspace (*tmp
))
2121 start
= parse_and_eval_address (args
);
2122 stop
= parse_and_eval_address (tmp
);
2125 { /* no explicit end address? */
2126 start
= parse_and_eval_address (args
);
2127 stop
= start
+ 1; /* ??? */
2130 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2131 finish_tfind_command (target_buf
, from_tty
);
2134 error ("Trace can only be run on remote targets.");
2137 /* save-tracepoints command */
2139 tracepoint_save_command (args
, from_tty
)
2143 struct tracepoint
*tp
;
2144 struct action_line
*line
;
2146 char *i1
= " ", *i2
= " ";
2147 char *indent
, *actionline
;
2149 if (args
== 0 || *args
== 0)
2150 error ("Argument required (file name in which to save tracepoints");
2152 if (tracepoint_chain
== 0)
2154 warning ("save-tracepoints: no tracepoints to save.\n");
2158 if (!(fp
= fopen (args
, "w")))
2159 error ("Unable to open file '%s' for saving tracepoints");
2161 ALL_TRACEPOINTS (tp
)
2163 if (tp
->addr_string
)
2164 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2166 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2169 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2173 fprintf (fp
, " actions\n");
2175 for (line
= tp
->actions
; line
; line
= line
->next
)
2177 struct cmd_list_element
*cmd
;
2179 QUIT
; /* allow user to bail out with ^C */
2180 actionline
= line
->action
;
2181 while (isspace(*actionline
))
2184 fprintf (fp
, "%s%s\n", indent
, actionline
);
2185 if (*actionline
!= '#') /* skip for comment lines */
2187 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2189 error ("Bad action list item: %s", actionline
);
2190 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2192 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2200 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2204 /* info scope command: list the locals for a scope. */
2206 scope_info (args
, from_tty
)
2210 struct symtab_and_line sal
;
2211 struct symtabs_and_lines sals
;
2213 struct minimal_symbol
*msym
;
2214 struct block
*block
;
2215 char **canonical
, *symname
, *save_args
= args
;
2216 int i
, nsyms
, count
= 0;
2218 if (args
== 0 || *args
== 0)
2219 error ("requires an argument (function, line or *addr) to define a scope");
2221 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2222 if (sals
.nelts
== 0)
2223 return; /* presumably decode_line_1 has already warned */
2225 /* Resolve line numbers to PC */
2226 resolve_sal_pc (&sals
.sals
[0]);
2227 block
= block_for_pc (sals
.sals
[0].pc
);
2231 QUIT
; /* allow user to bail out with ^C */
2232 nsyms
= BLOCK_NSYMS (block
);
2233 for (i
= 0; i
< nsyms
; i
++)
2235 QUIT
; /* allow user to bail out with ^C */
2237 printf_filtered ("Scope for %s:\n", save_args
);
2239 sym
= BLOCK_SYM (block
, i
);
2240 symname
= SYMBOL_NAME (sym
);
2241 if (symname
== NULL
|| *symname
== '\0')
2242 continue; /* probably botched, certainly useless */
2244 printf_filtered ("Symbol %s is ", symname
);
2245 switch (SYMBOL_CLASS (sym
)) {
2247 case LOC_UNDEF
: /* messed up symbol? */
2248 printf_filtered ("a bogus symbol, class %d.\n",
2249 SYMBOL_CLASS (sym
));
2250 count
--; /* don't count this one */
2253 printf_filtered ("a constant with value %d (0x%x)",
2254 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2256 case LOC_CONST_BYTES
:
2257 printf_filtered ("constant bytes: ");
2258 if (SYMBOL_TYPE (sym
))
2259 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2260 fprintf_filtered (gdb_stdout
, " %02x",
2261 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2264 printf_filtered ("in static storage at address ");
2265 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2268 printf_filtered ("a local variable in register $%s",
2269 reg_names
[SYMBOL_VALUE (sym
)]);
2273 printf_filtered ("an argument at stack/frame offset %ld",
2274 SYMBOL_VALUE (sym
));
2277 printf_filtered ("a local variable at frame offset %ld",
2278 SYMBOL_VALUE (sym
));
2281 printf_filtered ("a reference argument at offset %ld",
2282 SYMBOL_VALUE (sym
));
2285 printf_filtered ("an argument in register $%s",
2286 reg_names
[SYMBOL_VALUE (sym
)]);
2288 case LOC_REGPARM_ADDR
:
2289 printf_filtered ("the address of an argument, in register $%s",
2290 reg_names
[SYMBOL_VALUE (sym
)]);
2293 printf_filtered ("a typedef.\n");
2296 printf_filtered ("a label at address ");
2297 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2300 printf_filtered ("a function at address ");
2301 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2305 printf_filtered ("a variable at offset %d from register $%s",
2307 reg_names
[SYMBOL_BASEREG (sym
)]);
2309 case LOC_BASEREG_ARG
:
2310 printf_filtered ("an argument at offset %d from register $%s",
2312 reg_names
[SYMBOL_BASEREG (sym
)]);
2314 case LOC_UNRESOLVED
:
2315 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2317 printf_filtered ("Unresolved Static");
2320 printf_filtered ("static storage at address ");
2321 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2325 case LOC_OPTIMIZED_OUT
:
2326 printf_filtered ("optimized out.\n");
2329 if (SYMBOL_TYPE (sym
))
2330 printf_filtered (", length %d.\n",
2331 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2333 if (BLOCK_FUNCTION (block
))
2336 block
= BLOCK_SUPERBLOCK (block
);
2339 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2343 /* worker function (cleanup) */
2345 replace_comma (comma
)
2353 trace_dump_command (args
, from_tty
)
2357 struct tracepoint
*t
;
2358 struct action_line
*action
;
2359 char *action_exp
, *next_comma
;
2360 struct cleanup
*old_cleanups
;
2361 int stepping_actions
= 0;
2362 int stepping_frame
= 0;
2364 if (!target_is_remote ())
2366 error ("Trace can only be run on remote targets.");
2370 if (tracepoint_number
== -1)
2372 warning ("No current trace frame.");
2377 if (t
->number
== tracepoint_number
)
2381 error ("No known tracepoint matches 'current' tracepoint #%d.",
2384 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2386 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2387 tracepoint_number
, traceframe_number
);
2389 /* The current frame is a trap frame if the frame PC is equal
2390 to the tracepoint PC. If not, then the current frame was
2391 collected during single-stepping. */
2393 stepping_frame
= (t
->address
!= read_pc());
2395 for (action
= t
->actions
; action
; action
= action
->next
)
2397 struct cmd_list_element
*cmd
;
2399 QUIT
; /* allow user to bail out with ^C */
2400 action_exp
= action
->action
;
2401 while (isspace (*action_exp
))
2404 /* The collection actions to be done while stepping are
2405 bracketed by the commands "while-stepping" and "end". */
2407 if (*action_exp
== '#') /* comment line */
2410 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2412 error ("Bad action list item: %s", action_exp
);
2414 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2415 stepping_actions
= 1;
2416 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2417 stepping_actions
= 0;
2418 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2420 /* Display the collected data.
2421 For the trap frame, display only what was collected at the trap.
2422 Likewise for stepping frames, display only what was collected
2423 while stepping. This means that the two boolean variables,
2424 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2425 if (stepping_frame
== stepping_actions
)
2427 do { /* repeat over a comma-separated list */
2428 QUIT
; /* allow user to bail out with ^C */
2429 if (*action_exp
== ',')
2431 while (isspace (*action_exp
))
2434 next_comma
= strchr (action_exp
, ',');
2436 if (0 == strncasecmp (action_exp
, "$reg", 4))
2437 registers_info (NULL
, from_tty
);
2438 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2439 locals_info (NULL
, from_tty
);
2440 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2441 args_info (NULL
, from_tty
);
2446 make_cleanup (replace_comma
, next_comma
);
2449 printf_filtered ("%s = ", action_exp
);
2450 output_command (action_exp
, from_tty
);
2451 printf_filtered ("\n");
2455 action_exp
= next_comma
;
2456 } while (action_exp
&& *action_exp
== ',');
2460 discard_cleanups (old_cleanups
);
2463 /* Convert the memory pointed to by mem into hex, placing result in buf.
2464 * Return a pointer to the last char put in buf (null)
2465 * "stolen" from sparc-stub.c
2468 static const char hexchars
[]="0123456789abcdef";
2470 static unsigned char *
2471 mem2hex(mem
, buf
, count
)
2482 *buf
++ = hexchars
[ch
>> 4];
2483 *buf
++ = hexchars
[ch
& 0xf];
2491 int get_traceframe_number()
2493 return traceframe_number
;
2497 /* module initialization */
2499 _initialize_tracepoint ()
2501 tracepoint_chain
= 0;
2502 tracepoint_count
= 0;
2503 traceframe_number
= -1;
2504 tracepoint_number
= -1;
2506 set_internalvar (lookup_internalvar ("tpnum"),
2507 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2508 set_internalvar (lookup_internalvar ("trace_frame"),
2509 value_from_longest (builtin_type_int
, (LONGEST
) -1));
2511 if (tracepoint_list
.list
== NULL
)
2513 tracepoint_list
.listsize
= 128;
2514 tracepoint_list
.list
= xmalloc
2515 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2517 if (tracepoint_list
.aexpr_list
== NULL
)
2519 tracepoint_list
.aexpr_listsize
= 128;
2520 tracepoint_list
.aexpr_list
= xmalloc
2521 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2524 if (stepping_list
.list
== NULL
)
2526 stepping_list
.listsize
= 128;
2527 stepping_list
.list
= xmalloc
2528 (stepping_list
.listsize
* sizeof (struct memrange
));
2531 if (stepping_list
.aexpr_list
== NULL
)
2533 stepping_list
.aexpr_listsize
= 128;
2534 stepping_list
.aexpr_list
= xmalloc
2535 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2538 add_info ("scope", scope_info
,
2539 "List the variables local to a scope");
2541 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2542 "Tracing of program execution without stopping the program.",
2545 add_info ("tracepoints", tracepoints_info
,
2546 "Status of tracepoints, or tracepoint number NUMBER.\n\
2547 Convenience variable \"$tpnum\" contains the number of the\n\
2548 last tracepoint set.");
2550 add_info_alias ("tp", "tracepoints", 1);
2552 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2553 "Save current tracepoint definitions as a script.\n\
2554 Use the 'source' command in another debug session to restore them.");
2556 add_com ("tdump", class_trace
, trace_dump_command
,
2557 "Print everything collected at the current tracepoint.");
2559 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2560 "Select a trace frame;\n\
2561 No argument means forward by one frame; '-' meand backward by one frame.",
2562 &tfindlist
, "tfind ", 1, &cmdlist
);
2564 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2565 "Select a trace frame whose PC is outside the given \
2566 range.\nUsage: tfind outside addr1, addr2",
2569 add_cmd ("range", class_trace
, trace_find_range_command
,
2570 "Select a trace frame whose PC is in the given range.\n\
2571 Usage: tfind range addr1,addr2",
2574 add_cmd ("line", class_trace
, trace_find_line_command
,
2575 "Select a trace frame by source line.\n\
2576 Argument can be a line number (with optional source file), \n\
2577 a function name, or '*' followed by an address.\n\
2578 Default argument is 'the next source line that was traced'.",
2581 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2582 "Select a trace frame by tracepoint number.\n\
2583 Default is the tracepoint for the current trace frame.",
2586 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2587 "Select a trace frame by PC.\n\
2588 Default is the current PC, or the PC of the current trace frame.",
2591 add_cmd ("end", class_trace
, trace_find_end_command
,
2592 "Synonym for 'none'.\n\
2593 De-select any trace frame and resume 'live' debugging.",
2596 add_cmd ("none", class_trace
, trace_find_none_command
,
2597 "De-select any trace frame and resume 'live' debugging.",
2600 add_cmd ("start", class_trace
, trace_find_start_command
,
2601 "Select the first trace frame in the trace buffer.",
2604 add_com ("tstatus", class_trace
, trace_status_command
,
2605 "Display the status of the current trace data collection.");
2607 add_com ("tstop", class_trace
, trace_stop_command
,
2608 "Stop trace data collection.");
2610 add_com ("tstart", class_trace
, trace_start_command
,
2611 "Start trace data collection.");
2613 add_com ("passcount", class_trace
, trace_pass_command
,
2614 "Set the passcount for a tracepoint.\n\
2615 The trace will end when the tracepoint has been passed 'count' times.\n\
2616 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2617 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2619 add_com ("end", class_trace
, end_actions_pseudocommand
,
2620 "Ends a list of commands or actions.\n\
2621 Several GDB commands allow you to enter a list of commands or actions.\n\
2622 Entering \"end\" on a line by itself is the normal way to terminate\n\
2624 Note: the \"end\" command cannot be used at the gdb prompt.");
2626 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2627 "Specify single-stepping behavior at a tracepoint.\n\
2628 Argument is number of instructions to trace in single-step mode\n\
2629 following the tracepoint. This command is normally followed by\n\
2630 one or more \"collect\" commands, to specify what to collect\n\
2631 while single-stepping.\n\n\
2632 Note: this command can only be used in a tracepoint \"actions\" list.");
2634 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2635 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2637 add_com ("collect", class_trace
, collect_pseudocommand
,
2638 "Specify one or more data items to be collected at a tracepoint.\n\
2639 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2640 collect all data (variables, registers) referenced by that expression.\n\
2641 Also accepts the following special arguments:\n\
2642 $regs -- all registers.\n\
2643 $args -- all function arguments.\n\
2644 $locals -- all variables local to the block/function scope.\n\
2645 Note: this command can only be used in a tracepoint \"actions\" list.");
2647 add_com ("actions", class_trace
, trace_actions_command
,
2648 "Specify the actions to be taken at a tracepoint.\n\
2649 Tracepoint actions may include collecting of specified data, \n\
2650 single-stepping, or enabling/disabling other tracepoints, \n\
2651 depending on target's capabilities.");
2653 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2654 "Delete specified tracepoints.\n\
2655 Arguments are tracepoint numbers, separated by spaces.\n\
2656 No argument means delete all tracepoints.",
2659 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2660 "Disable specified tracepoints.\n\
2661 Arguments are tracepoint numbers, separated by spaces.\n\
2662 No argument means disable all tracepoints.",
2665 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2666 "Enable specified tracepoints.\n\
2667 Arguments are tracepoint numbers, separated by spaces.\n\
2668 No argument means enable all tracepoints.",
2671 add_com ("trace", class_trace
, trace_command
,
2672 "Set a tracepoint at a specified line or function or address.\n\
2673 Argument may be a line number, function name, or '*' plus an address.\n\
2674 For a line number or function, trace at the start of its code.\n\
2675 If an address is specified, trace at that exact address.\n\n\
2676 Do \"help tracepoints\" for info on other tracepoint commands.");
2678 add_com_alias ("tp", "trace", class_alias
, 0);
2679 add_com_alias ("tr", "trace", class_alias
, 1);
2680 add_com_alias ("tra", "trace", class_alias
, 1);
2681 add_com_alias ("trac", "trace", class_alias
, 1);