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
;
335 t
->source_file
= savestring (sal
.symtab
->filename
,
336 strlen (sal
.symtab
->filename
));
338 t
->section
= sal
.section
;
339 t
->language
= current_language
->la_language
;
340 t
->input_radix
= input_radix
;
341 t
->line_number
= sal
.line
;
342 t
->enabled
= enabled
;
346 t
->addr_string
= NULL
;
348 /* Add this tracepoint to the end of the chain
349 so that a list of tracepoints will come out in order
350 of increasing numbers. */
352 tc
= tracepoint_chain
;
354 tracepoint_chain
= t
;
361 discard_cleanups (old_chain
);
365 /* Set a tracepoint according to ARG (function, linenum or *address) */
367 trace_command (arg
, from_tty
)
371 char **canonical
= (char **)NULL
;
372 struct symtabs_and_lines sals
;
373 struct symtab_and_line sal
;
374 struct tracepoint
*t
;
375 char *addr_start
= 0, *addr_end
= 0;
379 error ("trace command requires an argument");
381 if (from_tty
&& info_verbose
)
382 printf_filtered ("TRACE %s\n", arg
);
385 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
388 return; /* ??? Presumably decode_line_1 has already warned? */
390 /* Resolve all line numbers to PC's */
391 for (i
= 0; i
< sals
.nelts
; i
++)
392 resolve_sal_pc (&sals
.sals
[i
]);
394 /* Now set all the tracepoints. */
395 for (i
= 0; i
< sals
.nelts
; i
++)
399 t
= set_raw_tracepoint (sal
);
400 set_tracepoint_count (tracepoint_count
+ 1);
401 t
->number
= tracepoint_count
;
403 /* If a canonical line spec is needed use that instead of the
405 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
406 t
->addr_string
= canonical
[i
];
408 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
412 /* Let the UI know of any additions */
413 if (create_tracepoint_hook
)
414 create_tracepoint_hook (t
);
419 printf_filtered ("Multiple tracepoints were set.\n");
420 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
424 /* Tell the user we have just set a tracepoint TP. */
428 struct tracepoint
*tp
;
430 printf_filtered ("Tracepoint %d", tp
->number
);
432 if (addressprint
|| (tp
->source_file
== NULL
))
434 printf_filtered (" at ");
435 print_address_numeric (tp
->address
, 1, gdb_stdout
);
438 printf_filtered (": file %s, line %d.",
439 tp
->source_file
, tp
->line_number
);
441 printf_filtered ("\n");
444 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
447 tracepoints_info (tpnum_exp
, from_tty
)
451 struct tracepoint
*t
;
452 struct action_line
*action
;
453 int found_a_tracepoint
= 0;
454 char wrap_indent
[80];
459 tpnum
= parse_and_eval_address (tpnum_exp
);
462 if (tpnum
== -1 || tpnum
== t
->number
)
464 extern int addressprint
; /* print machine addresses? */
466 if (!found_a_tracepoint
++)
468 printf_filtered ("Num Enb ");
470 printf_filtered ("Address ");
471 printf_filtered ("PassC StepC What\n");
473 strcpy (wrap_indent
, " ");
475 strcat (wrap_indent
, " ");
477 printf_filtered ("%-3d %-3s ", t
->number
,
478 t
->enabled
== enabled
? "y" : "n");
480 printf_filtered ("%s ",
481 local_hex_string_custom ((unsigned long) t
->address
,
483 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
487 sym
= find_pc_sect_function (t
->address
, t
->section
);
490 fputs_filtered ("in ", gdb_stdout
);
491 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
492 wrap_here (wrap_indent
);
493 fputs_filtered (" at ", gdb_stdout
);
495 fputs_filtered (t
->source_file
, gdb_stdout
);
496 printf_filtered (":%d", t
->line_number
);
499 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
501 printf_filtered ("\n");
504 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
505 for (action
= t
->actions
; action
; action
= action
->next
)
507 printf_filtered ("\t%s\n", action
->action
);
511 if (!found_a_tracepoint
)
514 printf_filtered ("No tracepoints.\n");
516 printf_filtered ("No tracepoint number %d.\n", tpnum
);
520 /* Optimization: the code to parse an enable, disable, or delete TP command
521 is virtually identical except for whether it performs an enable, disable,
522 or delete. Therefore I've combined them into one function with an opcode.
524 enum tracepoint_opcode
531 /* This function implements enable, disable and delete. */
533 tracepoint_operation (t
, from_tty
, opcode
)
534 struct tracepoint
*t
;
536 enum tracepoint_opcode opcode
;
538 struct tracepoint
*t2
;
542 t
->enabled
= enabled
;
543 if (modify_tracepoint_hook
)
544 modify_tracepoint_hook (t
);
547 t
->enabled
= disabled
;
548 if (modify_tracepoint_hook
)
549 modify_tracepoint_hook (t
);
552 if (tracepoint_chain
== t
)
553 tracepoint_chain
= t
->next
;
562 /* Let the UI know of any deletions */
563 if (delete_tracepoint_hook
)
564 delete_tracepoint_hook (t
);
567 free (t
->addr_string
);
569 free (t
->source_file
);
578 /* Utility: parse a tracepoint number and look it up in the list. */
580 get_tracepoint_by_number (arg
)
583 struct tracepoint
*t
;
589 error ("Bad tracepoint argument");
591 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
592 tpnum
= tracepoint_count
;
593 else if (**arg
== '$') /* handle convenience variable */
595 /* Make a copy of the name, so we can null-terminate it
596 to pass to lookup_internalvar(). */
598 while (isalnum(*end
) || *end
== '_')
600 copy
= (char *) alloca (end
- *arg
);
601 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
602 copy
[end
- *arg
- 1] = '\0';
605 val
= value_of_internalvar (lookup_internalvar (copy
));
606 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
607 error ("Convenience variable must have integral type.");
608 tpnum
= (int) value_as_long (val
);
610 else /* handle tracepoint number */
612 tpnum
= strtol (*arg
, arg
, 0);
613 if (tpnum
== 0) /* possible strtol failure */
614 while (**arg
&& !isspace (**arg
))
615 (*arg
)++; /* advance to next white space, if any */
618 if (t
->number
== tpnum
)
622 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
626 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
628 map_args_over_tracepoints (args
, from_tty
, opcode
)
631 enum tracepoint_opcode opcode
;
633 struct tracepoint
*t
, *tmp
;
637 if (args
== 0 || *args
== 0) /* do them all */
638 ALL_TRACEPOINTS_SAFE (t
, tmp
)
639 tracepoint_operation (t
, from_tty
, opcode
);
643 QUIT
; /* give user option to bail out with ^C */
644 if (t
= get_tracepoint_by_number (&args
))
645 tracepoint_operation (t
, from_tty
, opcode
);
646 while (*args
== ' ' || *args
== '\t')
651 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
653 enable_trace_command (args
, from_tty
)
658 map_args_over_tracepoints (args
, from_tty
, enable
);
661 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
663 disable_trace_command (args
, from_tty
)
668 map_args_over_tracepoints (args
, from_tty
, disable
);
671 /* Remove a tracepoint (or all if no argument) */
673 delete_trace_command (args
, from_tty
)
678 if (!args
|| !*args
) /* No args implies all tracepoints; */
679 if (from_tty
) /* confirm only if from_tty... */
680 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
681 if (!query ("Delete all tracepoints? "))
684 map_args_over_tracepoints (args
, from_tty
, delete);
687 /* Set passcount for tracepoint.
689 First command argument is passcount, second is tracepoint number.
690 If tracepoint number omitted, apply to most recently defined.
691 Also accepts special argument "all". */
694 trace_pass_command (args
, from_tty
)
698 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
701 if (args
== 0 || *args
== 0)
702 error ("PASS command requires an argument (count + optional TP num)");
704 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
706 while (*args
&& isspace (*args
))
709 if (*args
&& strncasecmp (args
, "all", 3) == 0)
710 args
+= 3; /* skip special argument "all" */
712 t1
= get_tracepoint_by_number (&args
);
715 error ("Junk at end of arguments.");
718 return; /* error, bad tracepoint number */
721 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
723 t2
->pass_count
= count
;
724 if (modify_tracepoint_hook
)
725 modify_tracepoint_hook (t2
);
727 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
732 /* ACTIONS functions: */
734 /* Prototypes for action-parsing utility commands */
735 static void read_actions
PARAMS((struct tracepoint
*));
736 static char *parse_and_eval_memrange
PARAMS ((char *,
742 /* The three functions:
743 collect_pseudocommand,
744 while_stepping_pseudocommand, and
745 end_actions_pseudocommand
746 are placeholders for "commands" that are actually ONLY to be used
747 within a tracepoint action list. If the actual function is ever called,
748 it means that somebody issued the "command" at the top level,
749 which is always an error. */
752 end_actions_pseudocommand (args
, from_tty
)
756 error ("This command cannot be used at the top level.");
760 while_stepping_pseudocommand (args
, from_tty
)
764 error ("This command can only be used in a tracepoint actions list.");
768 collect_pseudocommand (args
, from_tty
)
772 error ("This command can only be used in a tracepoint actions list.");
775 /* Enter a list of actions for a tracepoint. */
777 trace_actions_command (args
, from_tty
)
781 struct tracepoint
*t
;
784 char *end_msg
= "End with a line saying just \"end\".";
786 if (t
= get_tracepoint_by_number (&args
))
788 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
793 if (readline_begin_hook
)
794 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
795 else if (input_from_terminal_p ())
796 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
800 t
->step_count
= 0; /* read_actions may set this */
803 if (readline_end_hook
)
804 (*readline_end_hook
) ();
806 /* tracepoints_changed () */
808 /* else error, just return; */
811 /* worker function */
814 struct tracepoint
*t
;
817 char *prompt1
= "> ", *prompt2
= " > ";
818 char *prompt
= prompt1
;
819 enum actionline_type linetype
;
820 extern FILE *instream
;
821 struct action_line
*next
= NULL
, *temp
;
822 struct cleanup
*old_chain
;
824 /* Control-C quits instantly if typed while in this loop
825 since it should not wait until the user types a newline. */
829 signal (STOP_SIGNAL
, stop_sig
);
831 old_chain
= make_cleanup ((make_cleanup_func
) free_actions
, (void *) t
);
834 /* Make sure that all output has been output. Some machines may let
835 you get away with leaving out some of the gdb_flush, but not all. */
837 gdb_flush (gdb_stdout
);
838 gdb_flush (gdb_stderr
);
840 if (readline_hook
&& instream
== NULL
)
841 line
= (*readline_hook
) (prompt
);
842 else if (instream
== stdin
&& ISATTY (instream
))
844 line
= readline (prompt
);
845 if (line
&& *line
) /* add it to command history */
849 line
= gdb_readline (0);
851 linetype
= validate_actionline (&line
, t
);
852 if (linetype
== BADLINE
)
853 continue; /* already warned -- collect another line */
855 temp
= xmalloc (sizeof (struct action_line
));
859 if (next
== NULL
) /* first action for this tracepoint? */
860 t
->actions
= next
= temp
;
867 if (linetype
== STEPPING
) /* begin "while-stepping" */
868 if (prompt
== prompt2
)
870 warning ("Already processing 'while-stepping'");
874 prompt
= prompt2
; /* change prompt for stepping actions */
875 else if (linetype
== END
)
876 if (prompt
== prompt2
)
878 prompt
= prompt1
; /* end of single-stepping actions */
881 { /* end of actions */
882 if (t
->actions
->next
== NULL
)
884 /* an "end" all by itself with no other actions means
885 this tracepoint has no actions. Discard empty list. */
893 signal (STOP_SIGNAL
, SIG_DFL
);
896 discard_cleanups (old_chain
);
899 /* worker function */
901 validate_actionline (line
, t
)
903 struct tracepoint
*t
;
905 struct cmd_list_element
*c
;
906 struct expression
*exp
= NULL
;
907 value_ptr temp
, temp2
;
908 struct cleanup
*old_chain
= NULL
;
911 for (p
= *line
; isspace (*p
); )
914 /* symbol lookup etc. */
915 if (*p
== '\0') /* empty line: just prompt for another line. */
918 if (*p
== '#') /* comment line */
921 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
924 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
928 if (c
->function
.cfunc
== collect_pseudocommand
)
930 struct agent_expr
*aexpr
;
931 struct agent_reqs areqs
;
933 do { /* repeat over a comma-separated list */
934 QUIT
; /* allow user to bail out with ^C */
938 if (*p
== '$') /* look for special pseudo-symbols */
941 bfd_signed_vma offset
;
943 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
944 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
945 (0 == strncasecmp ("loc", p
+ 1, 3)))
950 /* else fall thru, treat p as an expression and parse it! */
952 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
953 old_chain
= make_cleanup ((make_cleanup_func
) free_current_contents
,
956 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
957 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
959 warning ("%s is constant (value %d): will not be collected.",
960 SYMBOL_NAME (exp
->elts
[2].symbol
),
961 SYMBOL_VALUE (exp
->elts
[2].symbol
));
964 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
966 warning ("%s is optimized away and cannot be collected.",
967 SYMBOL_NAME (exp
->elts
[2].symbol
));
971 /* we have something to collect, make sure that the expr to
972 bytecode translator can handle it and that it's not too long */
973 aexpr
= gen_trace_for_expr(exp
);
974 (void) make_cleanup ((make_cleanup_func
) free_agent_expr
, aexpr
);
976 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
977 error ("expression too complicated, try simplifying");
979 ax_reqs(aexpr
, &areqs
);
980 (void) make_cleanup (free
, areqs
.reg_mask
);
982 if (areqs
.flaw
!= agent_flaw_none
)
983 error ("malformed expression");
985 if (areqs
.min_height
< 0)
986 error ("gdb: Internal error: expression has min height < 0");
988 if (areqs
.max_height
> 20)
989 error ("expression too complicated, try simplifying");
991 do_cleanups (old_chain
);
992 } while (p
&& *p
++ == ',');
995 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
997 char *steparg
; /* in case warning is necessary */
1004 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1006 warning ("bad step-count: command ignored.", *line
);
1011 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1015 warning ("'%s' is not a supported tracepoint action.", *line
);
1020 /* worker function */
1023 struct tracepoint
*t
;
1025 struct action_line
*line
, *next
;
1027 for (line
= t
->actions
; line
; line
= next
)
1031 free (line
->action
);
1038 int type
; /* 0 for absolute memory range, else basereg number */
1039 bfd_signed_vma start
;
1043 struct collection_list
{
1044 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1047 struct memrange
*list
;
1048 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1049 long next_aexpr_elt
;
1050 struct agent_expr
**aexpr_list
;
1052 } tracepoint_list
, stepping_list
;
1054 /* MEMRANGE functions: */
1056 static int memrange_cmp
PARAMS ((const void *, const void *));
1058 /* compare memranges for qsort */
1060 memrange_cmp (va
, vb
)
1064 const struct memrange
*a
= va
, *b
= vb
;
1066 if (a
->type
< b
->type
)
1068 if (a
->type
> b
->type
)
1072 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1073 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1077 if (a
->start
< b
->start
)
1079 if (a
->start
> b
->start
)
1085 /* Sort the memrange list using qsort, and merge adjacent memranges */
1087 memrange_sortmerge (memranges
)
1088 struct collection_list
*memranges
;
1092 qsort (memranges
->list
, memranges
->next_memrange
,
1093 sizeof (struct memrange
), memrange_cmp
);
1094 if (memranges
->next_memrange
> 0)
1096 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1098 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1099 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1100 MAX_REGISTER_VIRTUAL_SIZE
)
1102 /* memrange b starts before memrange a ends; merge them. */
1103 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1104 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1105 continue; /* next b, same a */
1109 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1110 sizeof (struct memrange
));
1112 memranges
->next_memrange
= a
+ 1;
1116 /* Add a register to a collection list */
1118 add_register (collection
, regno
)
1119 struct collection_list
*collection
;
1120 unsigned long regno
;
1123 printf_filtered ("collect register %d\n", regno
);
1124 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1125 error ("Internal: register number %d too large for tracepoint",
1127 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1130 /* Add a memrange to a collection list */
1132 add_memrange (memranges
, type
, base
, len
)
1133 struct collection_list
*memranges
;
1135 bfd_signed_vma base
;
1139 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1140 /* type: 0 == memory, n == basereg */
1141 memranges
->list
[memranges
->next_memrange
].type
= type
;
1142 /* base: addr if memory, offset if reg relative. */
1143 memranges
->list
[memranges
->next_memrange
].start
= base
;
1144 /* len: we actually save end (base + len) for convenience */
1145 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1146 memranges
->next_memrange
++;
1147 if (memranges
->next_memrange
>= memranges
->listsize
)
1149 memranges
->listsize
*= 2;
1150 memranges
->list
= xrealloc (memranges
->list
,
1151 memranges
->listsize
);
1154 if (type
!= -1) /* better collect the base register! */
1155 add_register (memranges
, type
);
1158 /* Add a symbol to a collection list */
1160 collect_symbol (collect
, sym
, frame_regno
, frame_offset
)
1161 struct collection_list
*collect
;
1168 bfd_signed_vma offset
;
1170 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1171 switch (SYMBOL_CLASS (sym
)) {
1173 printf_filtered ("%s: don't know symbol class %d\n",
1174 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1177 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1178 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1181 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1183 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1184 SYMBOL_NAME (sym
), len
, offset
);
1185 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1189 reg
= SYMBOL_VALUE (sym
);
1191 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1192 add_register (collect
, reg
);
1193 /* check for doubles stored in two registers */
1194 /* FIXME: how about larger types stored in 3 or more regs? */
1195 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1196 len
> REGISTER_RAW_SIZE (reg
))
1197 add_register (collect
, reg
+ 1);
1200 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1201 printf_filtered (" (will not collect %s)\n",
1206 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1209 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1210 SYMBOL_NAME (sym
), len
);
1211 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1213 add_memrange (collect
, reg
, offset
, len
);
1215 case LOC_REGPARM_ADDR
:
1216 reg
= SYMBOL_VALUE (sym
);
1220 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
1221 SYMBOL_NAME (sym
), len
);
1222 printf_filtered (" %d from reg %d\n", offset
, reg
);
1224 add_memrange (collect
, reg
, offset
, len
);
1229 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1232 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1233 SYMBOL_NAME (sym
), len
);
1234 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1236 add_memrange (collect
, reg
, offset
, len
);
1239 case LOC_BASEREG_ARG
:
1240 reg
= SYMBOL_BASEREG (sym
);
1241 offset
= SYMBOL_VALUE (sym
);
1244 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1245 SYMBOL_NAME (sym
), len
, offset
, reg
);
1247 add_memrange (collect
, reg
, offset
, len
);
1249 case LOC_UNRESOLVED
:
1250 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1252 case LOC_OPTIMIZED_OUT
:
1253 printf_filtered ("%s has been optimized out of existance.\n",
1259 /* Add all locals (or args) symbols to collection list */
1261 add_local_symbols (collect
, pc
, frame_regno
, frame_offset
, type
)
1262 struct collection_list
*collect
;
1269 struct block
*block
;
1270 int i
, nsyms
, count
= 0;
1272 block
= block_for_pc (pc
);
1275 QUIT
; /* allow user to bail out with ^C */
1276 nsyms
= BLOCK_NSYMS (block
);
1277 for (i
= 0; i
< nsyms
; i
++)
1279 sym
= BLOCK_SYM (block
, i
);
1280 switch (SYMBOL_CLASS (sym
)) {
1285 if (type
== 'L') /* collecting Locals */
1288 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1295 case LOC_REGPARM_ADDR
:
1296 case LOC_BASEREG_ARG
:
1297 if (type
== 'A') /* collecting Arguments */
1300 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1304 if (BLOCK_FUNCTION (block
))
1307 block
= BLOCK_SUPERBLOCK (block
);
1310 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1313 /* worker function */
1315 clear_collection_list (list
)
1316 struct collection_list
*list
;
1320 list
->next_memrange
= 0;
1321 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1323 free_agent_expr(list
->aexpr_list
[ndx
]);
1324 list
->aexpr_list
[ndx
] = NULL
;
1326 list
->next_aexpr_elt
= 0;
1327 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1330 /* reduce a collection list to string form (for gdb protocol) */
1332 stringify_collection_list (list
, string
)
1333 struct collection_list
*list
;
1336 char temp_buf
[2048];
1339 char *(*str_list
)[];
1343 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1344 str_list
= (char *(*)[])xmalloc(count
* sizeof (char *));
1346 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1347 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1349 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1352 printf_filtered ("\nCollecting registers (mask): 0x");
1357 QUIT
; /* allow user to bail out with ^C */
1359 printf_filtered ("%02X", list
->regs_mask
[i
]);
1360 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1363 (*str_list
)[ndx
] = savestring(temp_buf
, end
- temp_buf
);
1367 printf_filtered ("\n");
1368 if (list
->next_memrange
> 0 && info_verbose
)
1369 printf_filtered ("Collecting memranges: \n");
1370 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1372 QUIT
; /* allow user to bail out with ^C */
1374 printf_filtered ("(%d, 0x%x, %d)\n",
1376 list
->list
[i
].start
,
1377 list
->list
[i
].end
- list
->list
[i
].start
);
1378 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1380 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1385 sprintf (end
, "M%X,%X,%X",
1387 list
->list
[i
].start
,
1388 list
->list
[i
].end
- list
->list
[i
].start
);
1389 count
+= strlen (end
);
1390 end
+= strlen (end
);
1393 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1395 QUIT
; /* allow user to bail out with ^C */
1396 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1398 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1403 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1404 end
+= 10; /* 'X' + 8 hex digits + ',' */
1407 end
= mem2hex(list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1408 count
+= 2 * list
->aexpr_list
[i
]->len
;
1413 (*str_list
)[ndx
] = savestring(temp_buf
, count
);
1418 (*str_list
)[ndx
] = NULL
;
1427 free_actions_list(actions_list
)
1428 char **actions_list
;
1432 if (actions_list
== 0)
1435 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1436 free(actions_list
[ndx
]);
1441 #ifndef TARGET_VIRTUAL_FRAME_POINTER
1442 /* If anybody else ever uses this macro, then move this
1443 default definition into some global header file such as defs.h.
1445 FIXME: GDB's whole scheme for dealing with "frames" and
1446 "frame pointers" needs a serious shakedown.
1449 #define TARGET_VIRTUAL_FRAME_POINTER(ADDR, REGP, OFFP) \
1450 do { *(REGP) = FP_REGNUM; *(OFFP) = 0; } while (0)
1453 /* render all actions into gdb protocol */
1455 encode_actions (t
, tdp_actions
, stepping_actions
)
1456 struct tracepoint
*t
;
1457 char ***tdp_actions
;
1458 char ***stepping_actions
;
1460 static char tdp_buff
[2048], step_buff
[2048];
1462 struct expression
*exp
= NULL
;
1463 struct action_line
*action
;
1464 bfd_signed_vma offset
;
1467 struct collection_list
*collect
;
1468 struct cmd_list_element
*cmd
;
1469 struct agent_expr
*aexpr
;
1470 long frame_reg
, frame_offset
;
1473 clear_collection_list (&tracepoint_list
);
1474 clear_collection_list (&stepping_list
);
1475 collect
= &tracepoint_list
;
1477 *tdp_actions
= NULL
;
1478 *stepping_actions
= NULL
;
1480 TARGET_VIRTUAL_FRAME_POINTER (t
->address
, &frame_reg
, &frame_offset
);
1482 for (action
= t
->actions
; action
; action
= action
->next
)
1484 QUIT
; /* allow user to bail out with ^C */
1485 action_exp
= action
->action
;
1486 while (isspace (*action_exp
))
1489 if (*action_exp
== '#') /* comment line */
1492 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1494 error ("Bad action list item: %s", action_exp
);
1496 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1498 do { /* repeat over a comma-separated list */
1499 QUIT
; /* allow user to bail out with ^C */
1500 while (isspace (*action_exp
))
1503 if (0 == strncasecmp ("$reg", action_exp
, 4))
1505 for (i
= 0; i
< NUM_REGS
; i
++)
1506 add_register (collect
, i
);
1507 action_exp
= strchr (action_exp
, ','); /* more? */
1509 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1511 add_local_symbols (collect
,
1516 action_exp
= strchr (action_exp
, ','); /* more? */
1518 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1520 add_local_symbols (collect
,
1525 action_exp
= strchr (action_exp
, ','); /* more? */
1529 unsigned long addr
, len
;
1530 struct cleanup
*old_chain
= NULL
;
1531 struct cleanup
*old_chain1
= NULL
;
1532 struct agent_reqs areqs
;
1534 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1535 old_chain
= make_cleanup ((make_cleanup_func
)
1536 free_current_contents
, &exp
);
1538 switch (exp
->elts
[0].opcode
) {
1540 i
= exp
->elts
[1].longconst
;
1542 printf_filtered ("OP_REGISTER: ");
1543 add_register (collect
, i
);
1547 /* safe because we know it's a simple expression */
1548 tempval
= evaluate_expression (exp
);
1549 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1550 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1551 add_memrange (collect
, -1, addr
, len
);
1555 collect_symbol (collect
,
1556 exp
->elts
[2].symbol
,
1561 default: /* full-fledged expression */
1562 aexpr
= gen_trace_for_expr (exp
);
1564 old_chain1
= make_cleanup ((make_cleanup_func
)
1565 free_agent_expr
, aexpr
);
1567 ax_reqs (aexpr
, &areqs
);
1568 if (areqs
.flaw
!= agent_flaw_none
)
1569 error ("malformed expression");
1571 if (areqs
.min_height
< 0)
1572 error ("gdb: Internal error: expression has min height < 0");
1573 if (areqs
.max_height
> 20)
1574 error ("expression too complicated, try simplifying");
1576 discard_cleanups (old_chain1
);
1577 add_aexpr (collect
, aexpr
);
1579 /* take care of the registers */
1580 if (areqs
.reg_mask_len
> 0)
1585 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1587 QUIT
; /* allow user to bail out with ^C */
1588 if (areqs
.reg_mask
[ndx1
] != 0)
1590 /* assume chars have 8 bits */
1591 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1592 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1593 /* it's used -- record it */
1594 add_register (collect
, ndx1
* 8 + ndx2
);
1600 do_cleanups (old_chain
);
1602 } while (action_exp
&& *action_exp
++ == ',');
1604 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1606 collect
= &stepping_list
;
1608 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1610 if (collect
== &stepping_list
) /* end stepping actions */
1611 collect
= &tracepoint_list
;
1613 break; /* end tracepoint actions */
1616 memrange_sortmerge (&tracepoint_list
);
1617 memrange_sortmerge (&stepping_list
);
1619 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1620 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1624 add_aexpr(collect
, aexpr
)
1625 struct collection_list
*collect
;
1626 struct agent_expr
*aexpr
;
1628 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1630 collect
->aexpr_list
=
1631 xrealloc (collect
->aexpr_list
,
1632 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1633 collect
->aexpr_listsize
*= 2;
1635 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1636 collect
->next_aexpr_elt
++;
1639 static char target_buf
[2048];
1641 /* Set "transparent" memory ranges
1643 Allow trace mechanism to treat text-like sections
1644 (and perhaps all read-only sections) transparently,
1645 i.e. don't reject memory requests from these address ranges
1646 just because they haven't been collected. */
1649 remote_set_transparent_ranges (void)
1651 extern bfd
*exec_bfd
;
1658 return; /* no information to give. */
1660 strcpy (target_buf
, "QTro");
1661 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1665 if ((s
->flags
& SEC_LOAD
) == 0 ||
1666 /* (s->flags & SEC_CODE) == 0 || */
1667 (s
->flags
& SEC_READONLY
) == 0)
1672 size
= bfd_get_section_size_before_reloc (s
);
1673 sprintf (tmp
, ":%x,%x", lma
, lma
+ size
);
1674 strcat (target_buf
, tmp
);
1678 putpkt (target_buf
);
1679 getpkt (target_buf
, 0);
1685 Tell target to clear any previous trace experiment.
1686 Walk the list of tracepoints, and send them (and their actions)
1687 to the target. If no errors,
1688 Tell target to start a new trace experiment. */
1691 trace_start_command (args
, from_tty
)
1694 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1695 struct tracepoint
*t
;
1698 char **stepping_actions
;
1700 struct cleanup
*old_chain
= NULL
;
1702 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1704 if (target_is_remote ())
1707 remote_get_noisy_reply (target_buf
);
1708 if (strcmp (target_buf
, "OK"))
1709 error ("Target does not support this command.");
1713 int ss_count
; /* if actions include singlestepping */
1714 int disable_mask
; /* ??? */
1715 int enable_mask
; /* ??? */
1717 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1718 t
->enabled
== enabled
? 'E' : 'D',
1719 t
->step_count
, t
->pass_count
);
1724 remote_get_noisy_reply (target_buf
);
1725 if (strcmp (target_buf
, "OK"))
1726 error ("Target does not support tracepoints.");
1730 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1731 old_chain
= make_cleanup (free_actions_list
, tdp_actions
);
1732 (void) make_cleanup (free_actions_list
, stepping_actions
);
1734 /* do_single_steps (t); */
1737 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1739 QUIT
; /* allow user to bail out with ^C */
1740 sprintf (buf
, "QTDP:-%x:%x:%s%c",
1741 t
->number
, t
->address
,
1743 ((tdp_actions
[ndx
+1] || stepping_actions
)
1746 remote_get_noisy_reply (target_buf
);
1747 if (strcmp (target_buf
, "OK"))
1748 error ("Error on target while setting tracepoints.");
1751 if (stepping_actions
)
1753 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1755 QUIT
; /* allow user to bail out with ^C */
1756 sprintf (buf
, "QTDP:-%x:%x:%s%s%s",
1757 t
->number
, t
->address
,
1758 ((ndx
== 0) ? "S" : ""),
1759 stepping_actions
[ndx
],
1760 (stepping_actions
[ndx
+1] ? "-" : ""));
1762 remote_get_noisy_reply (target_buf
);
1763 if (strcmp (target_buf
, "OK"))
1764 error ("Error on target while setting tracepoints.");
1768 do_cleanups (old_chain
);
1771 /* Tell target to treat text-like sections as transparent */
1772 remote_set_transparent_ranges ();
1773 /* Now insert traps and begin collecting data */
1775 remote_get_noisy_reply (target_buf
);
1776 if (strcmp (target_buf
, "OK"))
1777 error ("Bogus reply from target: %s", target_buf
);
1778 set_traceframe_num (-1); /* all old traceframes invalidated */
1779 set_tracepoint_num (-1);
1780 set_traceframe_context(-1);
1781 trace_running_p
= 1;
1782 if (trace_start_stop_hook
)
1783 trace_start_stop_hook(1, from_tty
);
1787 error ("Trace can only be run on remote targets.");
1792 trace_stop_command (args
, from_tty
)
1795 { /* STUB_COMM IS_IMPLEMENTED */
1796 if (target_is_remote ())
1799 remote_get_noisy_reply (target_buf
);
1800 if (strcmp (target_buf
, "OK"))
1801 error ("Bogus reply from target: %s", target_buf
);
1802 trace_running_p
= 0;
1803 if (trace_start_stop_hook
)
1804 trace_start_stop_hook(0, from_tty
);
1807 error ("Trace can only be run on remote targets.");
1810 unsigned long trace_running_p
;
1812 /* tstatus command */
1814 trace_status_command (args
, from_tty
)
1817 { /* STUB_COMM IS_IMPLEMENTED */
1818 if (target_is_remote ())
1820 putpkt ("qTStatus");
1821 remote_get_noisy_reply (target_buf
);
1823 if (target_buf
[0] != 'T' ||
1824 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1825 error ("Bogus reply from target: %s", target_buf
);
1827 /* exported for use by the GUI */
1828 trace_running_p
= (target_buf
[1] == '1');
1831 error ("Trace can only be run on remote targets.");
1834 /* Worker function for the various flavors of the tfind command */
1836 finish_tfind_command (msg
, from_tty
)
1840 int target_frameno
= -1, target_tracept
= -1;
1841 CORE_ADDR old_frame_addr
;
1842 struct symbol
*old_func
;
1845 old_frame_addr
= FRAME_FP (get_current_frame ());
1846 old_func
= find_pc_function (read_pc ());
1849 reply
= remote_get_noisy_reply (msg
);
1851 while (reply
&& *reply
)
1854 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1856 /* A request for a non-existant trace frame has failed.
1857 Our response will be different, depending on FROM_TTY:
1859 If FROM_TTY is true, meaning that this command was
1860 typed interactively by the user, then give an error
1861 and DO NOT change the state of traceframe_number etc.
1863 However if FROM_TTY is false, meaning that we're either
1864 in a script, a loop, or a user-defined command, then
1865 DON'T give an error, but DO change the state of
1866 traceframe_number etc. to invalid.
1868 The rationalle is that if you typed the command, you
1869 might just have committed a typo or something, and you'd
1870 like to NOT lose your current debugging state. However
1871 if you're in a user-defined command or especially in a
1872 loop, then you need a way to detect that the command
1873 failed WITHOUT aborting. This allows you to write
1874 scripts that search thru the trace buffer until the end,
1875 and then continue on to do something else. */
1878 error ("Target failed to find requested trace frame.");
1882 printf_filtered ("End of trace buffer.\n");
1883 /* The following will not recurse, since it's special-cased */
1884 trace_find_command ("-1", from_tty
);
1885 reply
= NULL
; /* break out of loop,
1886 (avoid recursive nonsense) */
1891 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1892 error ("Target failed to find requested trace frame.");
1894 case 'O': /* "OK"? */
1895 if (reply
[1] == 'K' && reply
[2] == '\0')
1898 error ("Bogus reply from target: %s", reply
);
1901 error ("Bogus reply from target: %s", reply
);
1904 flush_cached_frames ();
1905 registers_changed ();
1906 select_frame (get_current_frame (), 0);
1907 set_traceframe_num (target_frameno
);
1908 set_tracepoint_num (target_tracept
);
1909 if (target_frameno
== -1)
1910 set_traceframe_context (-1);
1912 set_traceframe_context (read_pc ());
1918 /* NOTE: in immitation of the step command, try to determine
1919 whether we have made a transition from one function to another.
1920 If so, we'll print the "stack frame" (ie. the new function and
1921 it's arguments) -- otherwise we'll just show the new source line.
1923 This determination is made by checking (1) whether the current
1924 function has changed, and (2) whether the current FP has changed.
1925 Hack: if the FP wasn't collected, either at the current or the
1926 previous frame, assume that the FP has NOT changed. */
1928 if (old_func
== find_pc_function (read_pc ()) &&
1929 (old_frame_addr
== 0 ||
1930 FRAME_FP (get_current_frame ()) == 0 ||
1931 old_frame_addr
== FRAME_FP (get_current_frame ())))
1936 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1941 /* trace_find_command takes a trace frame number n,
1942 sends "QTFrame:<n>" to the target,
1943 and accepts a reply that may contain several optional pieces
1944 of information: a frame number, a tracepoint number, and an
1945 indication of whether this is a trap frame or a stepping frame.
1947 The minimal response is just "OK" (which indicates that the
1948 target does not give us a frame number or a tracepoint number).
1949 Instead of that, the target may send us a string containing
1951 F<hexnum> (gives the selected frame number)
1952 T<hexnum> (gives the selected tracepoint number)
1957 trace_find_command (args
, from_tty
)
1960 { /* STUB_COMM PART_IMPLEMENTED */
1961 /* this should only be called with a numeric argument */
1965 if (target_is_remote ())
1967 if (trace_find_hook
)
1968 trace_find_hook (args
, from_tty
);
1970 if (args
== 0 || *args
== 0)
1971 { /* TFIND with no args means find NEXT trace frame. */
1972 if (traceframe_number
== -1)
1973 frameno
= 0; /* "next" is first one */
1975 frameno
= traceframe_number
+ 1;
1977 else if (0 == strcmp (args
, "-"))
1979 if (traceframe_number
== -1)
1980 error ("not debugging trace buffer");
1981 else if (from_tty
&& traceframe_number
== 0)
1982 error ("already at start of trace buffer");
1984 frameno
= traceframe_number
- 1;
1987 frameno
= parse_and_eval_address (args
);
1990 error ("invalid input (%d is less than zero)", frameno
);
1992 sprintf (target_buf
, "QTFrame:%x", frameno
);
1993 finish_tfind_command (target_buf
, from_tty
);
1996 error ("Trace can only be run on remote targets.");
2001 trace_find_end_command (args
, from_tty
)
2005 trace_find_command ("-1", from_tty
);
2010 trace_find_none_command (args
, from_tty
)
2014 trace_find_command ("-1", from_tty
);
2019 trace_find_start_command (args
, from_tty
)
2023 trace_find_command ("0", from_tty
);
2026 /* tfind pc command */
2028 trace_find_pc_command (args
, from_tty
)
2031 { /* STUB_COMM PART_IMPLEMENTED */
2035 if (target_is_remote ())
2037 if (args
== 0 || *args
== 0)
2038 pc
= read_pc (); /* default is current pc */
2040 pc
= parse_and_eval_address (args
);
2042 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
2043 finish_tfind_command (target_buf
, from_tty
);
2046 error ("Trace can only be run on remote targets.");
2049 /* tfind tracepoint command */
2051 trace_find_tracepoint_command (args
, from_tty
)
2054 { /* STUB_COMM PART_IMPLEMENTED */
2058 if (target_is_remote ())
2060 if (args
== 0 || *args
== 0)
2061 if (tracepoint_number
== -1)
2062 error ("No current tracepoint -- please supply an argument.");
2064 tdp
= tracepoint_number
; /* default is current TDP */
2066 tdp
= parse_and_eval_address (args
);
2068 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2069 finish_tfind_command (target_buf
, from_tty
);
2072 error ("Trace can only be run on remote targets.");
2075 /* TFIND LINE command:
2077 This command will take a sourceline for argument, just like BREAK
2078 or TRACE (ie. anything that "decode_line_1" can handle).
2080 With no argument, this command will find the next trace frame
2081 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2084 trace_find_line_command (args
, from_tty
)
2087 { /* STUB_COMM PART_IMPLEMENTED */
2088 static CORE_ADDR start_pc
, end_pc
;
2089 struct symtabs_and_lines sals
;
2090 struct symtab_and_line sal
;
2092 struct cleanup
*old_chain
;
2094 if (target_is_remote ())
2096 if (args
== 0 || *args
== 0)
2098 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2100 sals
.sals
= (struct symtab_and_line
*)
2101 xmalloc (sizeof (struct symtab_and_line
));
2106 sals
= decode_line_spec (args
, 1);
2110 old_chain
= make_cleanup (free
, sals
.sals
);
2111 if (sal
.symtab
== 0)
2113 printf_filtered ("TFIND: No line number information available");
2116 /* This is useful for "info line *0x7f34". If we can't tell the
2117 user about a source line, at least let them have the symbolic
2119 printf_filtered (" for address ");
2121 print_address (sal
.pc
, gdb_stdout
);
2122 printf_filtered (";\n -- will attempt to find by PC. \n");
2126 printf_filtered (".\n");
2127 return; /* no line, no PC; what can we do? */
2130 else if (sal
.line
> 0
2131 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2133 if (start_pc
== end_pc
)
2135 printf_filtered ("Line %d of \"%s\"",
2136 sal
.line
, sal
.symtab
->filename
);
2138 printf_filtered (" is at address ");
2139 print_address (start_pc
, gdb_stdout
);
2141 printf_filtered (" but contains no code.\n");
2142 sal
= find_pc_line (start_pc
, 0);
2144 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2146 printf_filtered ("Attempting to find line %d instead.\n",
2149 error ("Cannot find a good line.");
2153 /* Is there any case in which we get here, and have an address
2154 which the user would want to see? If we have debugging symbols
2155 and no line numbers? */
2156 error ("Line number %d is out of range for \"%s\".\n",
2157 sal
.line
, sal
.symtab
->filename
);
2159 if (args
&& *args
) /* find within range of stated line */
2160 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
2161 else /* find OUTSIDE OF range of CURRENT line */
2162 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
2163 finish_tfind_command (target_buf
, from_tty
);
2164 do_cleanups (old_chain
);
2167 error ("Trace can only be run on remote targets.");
2170 /* tfind range command */
2172 trace_find_range_command (args
, from_tty
)
2175 { /* STUB_COMM PART_IMPLEMENTED */
2176 static CORE_ADDR start
, stop
;
2179 if (target_is_remote ())
2181 if (args
== 0 || *args
== 0)
2182 { /* XXX FIXME: what should default behavior be? */
2183 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2187 if (0 != (tmp
= strchr (args
, ',' )))
2189 *tmp
++ = '\0'; /* terminate start address */
2190 while (isspace (*tmp
))
2192 start
= parse_and_eval_address (args
);
2193 stop
= parse_and_eval_address (tmp
);
2196 { /* no explicit end address? */
2197 start
= parse_and_eval_address (args
);
2198 stop
= start
+ 1; /* ??? */
2201 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2202 finish_tfind_command (target_buf
, from_tty
);
2205 error ("Trace can only be run on remote targets.");
2208 /* tfind outside command */
2210 trace_find_outside_command (args
, from_tty
)
2213 { /* STUB_COMM PART_IMPLEMENTED */
2214 CORE_ADDR start
, stop
;
2217 if (target_is_remote ())
2219 if (args
== 0 || *args
== 0)
2220 { /* XXX FIXME: what should default behavior be? */
2221 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2225 if (0 != (tmp
= strchr (args
, ',' )))
2227 *tmp
++ = '\0'; /* terminate start address */
2228 while (isspace (*tmp
))
2230 start
= parse_and_eval_address (args
);
2231 stop
= parse_and_eval_address (tmp
);
2234 { /* no explicit end address? */
2235 start
= parse_and_eval_address (args
);
2236 stop
= start
+ 1; /* ??? */
2239 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2240 finish_tfind_command (target_buf
, from_tty
);
2243 error ("Trace can only be run on remote targets.");
2246 /* save-tracepoints command */
2248 tracepoint_save_command (args
, from_tty
)
2252 struct tracepoint
*tp
;
2253 struct action_line
*line
;
2255 char *i1
= " ", *i2
= " ";
2256 char *indent
, *actionline
;
2258 if (args
== 0 || *args
== 0)
2259 error ("Argument required (file name in which to save tracepoints");
2261 if (tracepoint_chain
== 0)
2263 warning ("save-tracepoints: no tracepoints to save.\n");
2267 if (!(fp
= fopen (args
, "w")))
2268 error ("Unable to open file '%s' for saving tracepoints");
2270 ALL_TRACEPOINTS (tp
)
2272 if (tp
->addr_string
)
2273 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2275 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2278 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2282 fprintf (fp
, " actions\n");
2284 for (line
= tp
->actions
; line
; line
= line
->next
)
2286 struct cmd_list_element
*cmd
;
2288 QUIT
; /* allow user to bail out with ^C */
2289 actionline
= line
->action
;
2290 while (isspace(*actionline
))
2293 fprintf (fp
, "%s%s\n", indent
, actionline
);
2294 if (*actionline
!= '#') /* skip for comment lines */
2296 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2298 error ("Bad action list item: %s", actionline
);
2299 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2301 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2309 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2313 /* info scope command: list the locals for a scope. */
2315 scope_info (args
, from_tty
)
2319 struct symtab_and_line sal
;
2320 struct symtabs_and_lines sals
;
2322 struct minimal_symbol
*msym
;
2323 struct block
*block
;
2324 char **canonical
, *symname
, *save_args
= args
;
2325 int i
, nsyms
, count
= 0;
2327 if (args
== 0 || *args
== 0)
2328 error ("requires an argument (function, line or *addr) to define a scope");
2330 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2331 if (sals
.nelts
== 0)
2332 return; /* presumably decode_line_1 has already warned */
2334 /* Resolve line numbers to PC */
2335 resolve_sal_pc (&sals
.sals
[0]);
2336 block
= block_for_pc (sals
.sals
[0].pc
);
2340 QUIT
; /* allow user to bail out with ^C */
2341 nsyms
= BLOCK_NSYMS (block
);
2342 for (i
= 0; i
< nsyms
; i
++)
2344 QUIT
; /* allow user to bail out with ^C */
2346 printf_filtered ("Scope for %s:\n", save_args
);
2348 sym
= BLOCK_SYM (block
, i
);
2349 symname
= SYMBOL_NAME (sym
);
2350 if (symname
== NULL
|| *symname
== '\0')
2351 continue; /* probably botched, certainly useless */
2353 printf_filtered ("Symbol %s is ", symname
);
2354 switch (SYMBOL_CLASS (sym
)) {
2356 case LOC_UNDEF
: /* messed up symbol? */
2357 printf_filtered ("a bogus symbol, class %d.\n",
2358 SYMBOL_CLASS (sym
));
2359 count
--; /* don't count this one */
2362 printf_filtered ("a constant with value %d (0x%x)",
2363 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2365 case LOC_CONST_BYTES
:
2366 printf_filtered ("constant bytes: ");
2367 if (SYMBOL_TYPE (sym
))
2368 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2369 fprintf_filtered (gdb_stdout
, " %02x",
2370 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2373 printf_filtered ("in static storage at address ");
2374 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2377 printf_filtered ("a local variable in register $%s",
2378 reg_names
[SYMBOL_VALUE (sym
)]);
2382 printf_filtered ("an argument at stack/frame offset %ld",
2383 SYMBOL_VALUE (sym
));
2386 printf_filtered ("a local variable at frame offset %ld",
2387 SYMBOL_VALUE (sym
));
2390 printf_filtered ("a reference argument at offset %ld",
2391 SYMBOL_VALUE (sym
));
2394 printf_filtered ("an argument in register $%s",
2395 reg_names
[SYMBOL_VALUE (sym
)]);
2397 case LOC_REGPARM_ADDR
:
2398 printf_filtered ("the address of an argument, in register $%s",
2399 reg_names
[SYMBOL_VALUE (sym
)]);
2402 printf_filtered ("a typedef.\n");
2405 printf_filtered ("a label at address ");
2406 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2409 printf_filtered ("a function at address ");
2410 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2414 printf_filtered ("a variable at offset %d from register $%s",
2416 reg_names
[SYMBOL_BASEREG (sym
)]);
2418 case LOC_BASEREG_ARG
:
2419 printf_filtered ("an argument at offset %d from register $%s",
2421 reg_names
[SYMBOL_BASEREG (sym
)]);
2423 case LOC_UNRESOLVED
:
2424 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2426 printf_filtered ("Unresolved Static");
2429 printf_filtered ("static storage at address ");
2430 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2434 case LOC_OPTIMIZED_OUT
:
2435 printf_filtered ("optimized out.\n");
2438 if (SYMBOL_TYPE (sym
))
2439 printf_filtered (", length %d.\n",
2440 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2442 if (BLOCK_FUNCTION (block
))
2445 block
= BLOCK_SUPERBLOCK (block
);
2448 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2452 /* worker function (cleanup) */
2454 replace_comma (comma
)
2462 trace_dump_command (args
, from_tty
)
2466 struct tracepoint
*t
;
2467 struct action_line
*action
;
2468 char *action_exp
, *next_comma
;
2469 struct cleanup
*old_cleanups
;
2470 int stepping_actions
= 0;
2471 int stepping_frame
= 0;
2473 if (!target_is_remote ())
2475 error ("Trace can only be run on remote targets.");
2479 if (tracepoint_number
== -1)
2481 warning ("No current trace frame.");
2486 if (t
->number
== tracepoint_number
)
2490 error ("No known tracepoint matches 'current' tracepoint #%d.",
2493 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2495 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2496 tracepoint_number
, traceframe_number
);
2498 /* The current frame is a trap frame if the frame PC is equal
2499 to the tracepoint PC. If not, then the current frame was
2500 collected during single-stepping. */
2502 stepping_frame
= (t
->address
!= read_pc());
2504 for (action
= t
->actions
; action
; action
= action
->next
)
2506 struct cmd_list_element
*cmd
;
2508 QUIT
; /* allow user to bail out with ^C */
2509 action_exp
= action
->action
;
2510 while (isspace (*action_exp
))
2513 /* The collection actions to be done while stepping are
2514 bracketed by the commands "while-stepping" and "end". */
2516 if (*action_exp
== '#') /* comment line */
2519 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2521 error ("Bad action list item: %s", action_exp
);
2523 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2524 stepping_actions
= 1;
2525 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2526 stepping_actions
= 0;
2527 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2529 /* Display the collected data.
2530 For the trap frame, display only what was collected at the trap.
2531 Likewise for stepping frames, display only what was collected
2532 while stepping. This means that the two boolean variables,
2533 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2534 if (stepping_frame
== stepping_actions
)
2536 do { /* repeat over a comma-separated list */
2537 QUIT
; /* allow user to bail out with ^C */
2538 if (*action_exp
== ',')
2540 while (isspace (*action_exp
))
2543 next_comma
= strchr (action_exp
, ',');
2545 if (0 == strncasecmp (action_exp
, "$reg", 4))
2546 registers_info (NULL
, from_tty
);
2547 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2548 locals_info (NULL
, from_tty
);
2549 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2550 args_info (NULL
, from_tty
);
2555 make_cleanup (replace_comma
, next_comma
);
2558 printf_filtered ("%s = ", action_exp
);
2559 output_command (action_exp
, from_tty
);
2560 printf_filtered ("\n");
2564 action_exp
= next_comma
;
2565 } while (action_exp
&& *action_exp
== ',');
2569 discard_cleanups (old_cleanups
);
2572 /* Convert the memory pointed to by mem into hex, placing result in buf.
2573 * Return a pointer to the last char put in buf (null)
2574 * "stolen" from sparc-stub.c
2577 static const char hexchars
[]="0123456789abcdef";
2579 static unsigned char *
2580 mem2hex(mem
, buf
, count
)
2591 *buf
++ = hexchars
[ch
>> 4];
2592 *buf
++ = hexchars
[ch
& 0xf];
2600 int get_traceframe_number()
2602 return traceframe_number
;
2606 /* module initialization */
2608 _initialize_tracepoint ()
2610 tracepoint_chain
= 0;
2611 tracepoint_count
= 0;
2612 traceframe_number
= -1;
2613 tracepoint_number
= -1;
2615 set_internalvar (lookup_internalvar ("tpnum"),
2616 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2617 set_internalvar (lookup_internalvar ("trace_frame"),
2618 value_from_longest (builtin_type_int
, (LONGEST
) -1));
2620 if (tracepoint_list
.list
== NULL
)
2622 tracepoint_list
.listsize
= 128;
2623 tracepoint_list
.list
= xmalloc
2624 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2626 if (tracepoint_list
.aexpr_list
== NULL
)
2628 tracepoint_list
.aexpr_listsize
= 128;
2629 tracepoint_list
.aexpr_list
= xmalloc
2630 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2633 if (stepping_list
.list
== NULL
)
2635 stepping_list
.listsize
= 128;
2636 stepping_list
.list
= xmalloc
2637 (stepping_list
.listsize
* sizeof (struct memrange
));
2640 if (stepping_list
.aexpr_list
== NULL
)
2642 stepping_list
.aexpr_listsize
= 128;
2643 stepping_list
.aexpr_list
= xmalloc
2644 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2647 add_info ("scope", scope_info
,
2648 "List the variables local to a scope");
2650 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2651 "Tracing of program execution without stopping the program.",
2654 add_info ("tracepoints", tracepoints_info
,
2655 "Status of tracepoints, or tracepoint number NUMBER.\n\
2656 Convenience variable \"$tpnum\" contains the number of the\n\
2657 last tracepoint set.");
2659 add_info_alias ("tp", "tracepoints", 1);
2661 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2662 "Save current tracepoint definitions as a script.\n\
2663 Use the 'source' command in another debug session to restore them.");
2665 add_com ("tdump", class_trace
, trace_dump_command
,
2666 "Print everything collected at the current tracepoint.");
2668 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2669 "Select a trace frame;\n\
2670 No argument means forward by one frame; '-' meand backward by one frame.",
2671 &tfindlist
, "tfind ", 1, &cmdlist
);
2673 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2674 "Select a trace frame whose PC is outside the given \
2675 range.\nUsage: tfind outside addr1, addr2",
2678 add_cmd ("range", class_trace
, trace_find_range_command
,
2679 "Select a trace frame whose PC is in the given range.\n\
2680 Usage: tfind range addr1,addr2",
2683 add_cmd ("line", class_trace
, trace_find_line_command
,
2684 "Select a trace frame by source line.\n\
2685 Argument can be a line number (with optional source file), \n\
2686 a function name, or '*' followed by an address.\n\
2687 Default argument is 'the next source line that was traced'.",
2690 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2691 "Select a trace frame by tracepoint number.\n\
2692 Default is the tracepoint for the current trace frame.",
2695 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2696 "Select a trace frame by PC.\n\
2697 Default is the current PC, or the PC of the current trace frame.",
2700 add_cmd ("end", class_trace
, trace_find_end_command
,
2701 "Synonym for 'none'.\n\
2702 De-select any trace frame and resume 'live' debugging.",
2705 add_cmd ("none", class_trace
, trace_find_none_command
,
2706 "De-select any trace frame and resume 'live' debugging.",
2709 add_cmd ("start", class_trace
, trace_find_start_command
,
2710 "Select the first trace frame in the trace buffer.",
2713 add_com ("tstatus", class_trace
, trace_status_command
,
2714 "Display the status of the current trace data collection.");
2716 add_com ("tstop", class_trace
, trace_stop_command
,
2717 "Stop trace data collection.");
2719 add_com ("tstart", class_trace
, trace_start_command
,
2720 "Start trace data collection.");
2722 add_com ("passcount", class_trace
, trace_pass_command
,
2723 "Set the passcount for a tracepoint.\n\
2724 The trace will end when the tracepoint has been passed 'count' times.\n\
2725 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2726 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2728 add_com ("end", class_trace
, end_actions_pseudocommand
,
2729 "Ends a list of commands or actions.\n\
2730 Several GDB commands allow you to enter a list of commands or actions.\n\
2731 Entering \"end\" on a line by itself is the normal way to terminate\n\
2733 Note: the \"end\" command cannot be used at the gdb prompt.");
2735 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2736 "Specify single-stepping behavior at a tracepoint.\n\
2737 Argument is number of instructions to trace in single-step mode\n\
2738 following the tracepoint. This command is normally followed by\n\
2739 one or more \"collect\" commands, to specify what to collect\n\
2740 while single-stepping.\n\n\
2741 Note: this command can only be used in a tracepoint \"actions\" list.");
2743 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2744 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2746 add_com ("collect", class_trace
, collect_pseudocommand
,
2747 "Specify one or more data items to be collected at a tracepoint.\n\
2748 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2749 collect all data (variables, registers) referenced by that expression.\n\
2750 Also accepts the following special arguments:\n\
2751 $regs -- all registers.\n\
2752 $args -- all function arguments.\n\
2753 $locals -- all variables local to the block/function scope.\n\
2754 Note: this command can only be used in a tracepoint \"actions\" list.");
2756 add_com ("actions", class_trace
, trace_actions_command
,
2757 "Specify the actions to be taken at a tracepoint.\n\
2758 Tracepoint actions may include collecting of specified data, \n\
2759 single-stepping, or enabling/disabling other tracepoints, \n\
2760 depending on target's capabilities.");
2762 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2763 "Delete specified tracepoints.\n\
2764 Arguments are tracepoint numbers, separated by spaces.\n\
2765 No argument means delete all tracepoints.",
2768 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2769 "Disable specified tracepoints.\n\
2770 Arguments are tracepoint numbers, separated by spaces.\n\
2771 No argument means disable all tracepoints.",
2774 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2775 "Enable specified tracepoints.\n\
2776 Arguments are tracepoint numbers, separated by spaces.\n\
2777 No argument means enable all tracepoints.",
2780 add_com ("trace", class_trace
, trace_command
,
2781 "Set a tracepoint at a specified line or function or address.\n\
2782 Argument may be a line number, function name, or '*' plus an address.\n\
2783 For a line number or function, trace at the start of its code.\n\
2784 If an address is specified, trace at that exact address.\n\n\
2785 Do \"help tracepoints\" for info on other tracepoint commands.");
2787 add_com_alias ("tp", "trace", class_alias
, 0);
2788 add_com_alias ("tr", "trace", class_alias
, 1);
2789 add_com_alias ("tra", "trace", class_alias
, 1);
2790 add_com_alias ("trac", "trace", class_alias
, 1);