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,
19 Boston, MA 02111-1307, USA. */
24 #include "tracepoint.h"
26 #include "expression.h"
31 #include "gdb_string.h"
36 /* readline include files */
37 #include <readline/readline.h>
38 #include <readline/history.h>
40 /* readline defines this. */
47 /* maximum length of an agent aexpression.
48 this accounts for the fact that packets are limited to 400 bytes
49 (which includes everything -- including the checksum), and assumes
50 the worst case of maximum length for each of the pieces of a
53 NOTE: expressions get mem2hex'ed otherwise this would be twice as
54 large. (400 - 31)/2 == 184 */
55 #define MAX_AGENT_EXPR_LEN 184
58 extern int info_verbose
;
59 extern void (*readline_begin_hook
) PARAMS ((char *,...));
60 extern char *(*readline_hook
) PARAMS ((char *));
61 extern void (*readline_end_hook
) PARAMS ((void));
62 extern void x_command
PARAMS ((char *, int));
63 extern int addressprint
; /* Print machine addresses? */
65 /* If this definition isn't overridden by the header files, assume
66 that isatty and fileno exist on this system. */
68 #define ISATTY(FP) (isatty (fileno (FP)))
74 This module defines the following debugger commands:
75 trace : set a tracepoint on a function, line, or address.
76 info trace : list all debugger-defined tracepoints.
77 delete trace : delete one or more tracepoints.
78 enable trace : enable one or more tracepoints.
79 disable trace : disable one or more tracepoints.
80 actions : specify actions to be taken at a tracepoint.
81 passcount : specify a pass count for a tracepoint.
82 tstart : start a trace experiment.
83 tstop : stop a trace experiment.
84 tstatus : query the status of a trace experiment.
85 tfind : find a trace frame in the trace buffer.
86 tdump : print everything collected at the current tracepoint.
87 save-tracepoints : write tracepoint setup into a file.
89 This module defines the following user-visible debugger variables:
90 $trace_frame : sequence number of trace frame currently being debugged.
91 $trace_line : source line of trace frame currently being debugged.
92 $trace_file : source file of trace frame currently being debugged.
93 $tracepoint : tracepoint number of trace frame currently being debugged.
97 /* ======= Important global variables: ======= */
99 /* Chain of all tracepoints defined. */
100 struct tracepoint
*tracepoint_chain
;
102 /* Number of last tracepoint made. */
103 static int tracepoint_count
;
105 /* Number of last traceframe collected. */
106 static int traceframe_number
;
108 /* Tracepoint for last traceframe collected. */
109 static int tracepoint_number
;
111 /* Symbol for function for last traceframe collected */
112 static struct symbol
*traceframe_fun
;
114 /* Symtab and line for last traceframe collected */
115 static struct symtab_and_line traceframe_sal
;
117 /* Tracing command lists */
118 static struct cmd_list_element
*tfindlist
;
120 /* ======= Important command functions: ======= */
121 static void trace_command
PARAMS ((char *, int));
122 static void tracepoints_info
PARAMS ((char *, int));
123 static void delete_trace_command
PARAMS ((char *, int));
124 static void enable_trace_command
PARAMS ((char *, int));
125 static void disable_trace_command
PARAMS ((char *, int));
126 static void trace_pass_command
PARAMS ((char *, int));
127 static void trace_actions_command
PARAMS ((char *, int));
128 static void trace_start_command
PARAMS ((char *, int));
129 static void trace_stop_command
PARAMS ((char *, int));
130 static void trace_status_command
PARAMS ((char *, int));
131 static void trace_find_command
PARAMS ((char *, int));
132 static void trace_find_pc_command
PARAMS ((char *, int));
133 static void trace_find_tracepoint_command
PARAMS ((char *, int));
134 static void trace_find_line_command
PARAMS ((char *, int));
135 static void trace_find_range_command
PARAMS ((char *, int));
136 static void trace_find_outside_command
PARAMS ((char *, int));
137 static void tracepoint_save_command
PARAMS ((char *, int));
138 static void trace_dump_command
PARAMS ((char *, int));
140 /* support routines */
141 static void trace_mention
PARAMS ((struct tracepoint
*));
144 struct collection_list
;
146 static void add_aexpr
PARAMS ((struct collection_list
*, struct agent_expr
*));
147 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
148 static void add_register
PARAMS ((struct collection_list
* collection
, unsigned long regno
));
149 static void free_actions_list
PARAMS ((char **actions_list
));
150 static void free_actions_list_cleanup_wrapper
PARAMS ((void *));
152 extern void _initialize_tracepoint
PARAMS ((void));
154 /* Utility: returns true if "target remote" */
158 if (current_target
.to_shortname
&&
159 strcmp (current_target
.to_shortname
, "remote") == 0)
165 /* Utility: generate error from an incoming stub packet. */
171 return; /* not an error msg */
174 case '1': /* malformed packet error */
175 if (*++buf
== '0') /* general case: */
176 error ("tracepoint.c: error in outgoing packet.");
178 error ("tracepoint.c: error in outgoing packet at field #%d.",
179 strtol (buf
, NULL
, 16));
181 error ("trace API error 0x%s.", ++buf
);
183 error ("Target returns error code '%s'.", buf
);
187 /* Utility: wait for reply from stub, while accepting "O" packets */
189 remote_get_noisy_reply (buf
)
192 do /* loop on reply from remote stub */
194 QUIT
; /* allow user to bail out with ^C */
197 error ("Target does not support this command.");
198 else if (buf
[0] == 'E')
200 else if (buf
[0] == 'O' &&
202 remote_console_output (buf
+ 1); /* 'O' message from stub */
204 return buf
; /* here's the actual reply */
209 /* Set tracepoint count to NUM. */
211 set_tracepoint_count (num
)
214 tracepoint_count
= num
;
215 set_internalvar (lookup_internalvar ("tpnum"),
216 value_from_longest (builtin_type_int
, (LONGEST
) num
));
219 /* Set traceframe number to NUM. */
221 set_traceframe_num (num
)
224 traceframe_number
= num
;
225 set_internalvar (lookup_internalvar ("trace_frame"),
226 value_from_longest (builtin_type_int
, (LONGEST
) num
));
229 /* Set tracepoint number to NUM. */
231 set_tracepoint_num (num
)
234 tracepoint_number
= num
;
235 set_internalvar (lookup_internalvar ("tracepoint"),
236 value_from_longest (builtin_type_int
, (LONGEST
) num
));
239 /* Set externally visible debug variables for querying/printing
240 the traceframe context (line, function, file) */
243 set_traceframe_context (trace_pc
)
246 static struct type
*func_string
, *file_string
;
247 static struct type
*func_range
, *file_range
;
248 static value_ptr func_val
, file_val
;
249 static struct type
*charstar
;
252 if (charstar
== (struct type
*) NULL
)
253 charstar
= lookup_pointer_type (builtin_type_char
);
255 if (trace_pc
== -1) /* cease debugging any trace buffers */
258 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
259 traceframe_sal
.symtab
= NULL
;
260 set_internalvar (lookup_internalvar ("trace_func"),
261 value_from_longest (charstar
, (LONGEST
) 0));
262 set_internalvar (lookup_internalvar ("trace_file"),
263 value_from_longest (charstar
, (LONGEST
) 0));
264 set_internalvar (lookup_internalvar ("trace_line"),
265 value_from_longest (builtin_type_int
, (LONGEST
) - 1));
269 /* save as globals for internal use */
270 traceframe_sal
= find_pc_line (trace_pc
, 0);
271 traceframe_fun
= find_pc_function (trace_pc
);
273 /* save linenumber as "$trace_line", a debugger variable visible to users */
274 set_internalvar (lookup_internalvar ("trace_line"),
275 value_from_longest (builtin_type_int
,
276 (LONGEST
) traceframe_sal
.line
));
278 /* save func name as "$trace_func", a debugger variable visible to users */
279 if (traceframe_fun
== NULL
||
280 SYMBOL_NAME (traceframe_fun
) == NULL
)
281 set_internalvar (lookup_internalvar ("trace_func"),
282 value_from_longest (charstar
, (LONGEST
) 0));
285 len
= strlen (SYMBOL_NAME (traceframe_fun
));
286 func_range
= create_range_type (func_range
,
287 builtin_type_int
, 0, len
- 1);
288 func_string
= create_array_type (func_string
,
289 builtin_type_char
, func_range
);
290 func_val
= allocate_value (func_string
);
291 VALUE_TYPE (func_val
) = func_string
;
292 memcpy (VALUE_CONTENTS_RAW (func_val
),
293 SYMBOL_NAME (traceframe_fun
),
295 func_val
->modifiable
= 0;
296 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
299 /* save file name as "$trace_file", a debugger variable visible to users */
300 if (traceframe_sal
.symtab
== NULL
||
301 traceframe_sal
.symtab
->filename
== NULL
)
302 set_internalvar (lookup_internalvar ("trace_file"),
303 value_from_longest (charstar
, (LONGEST
) 0));
306 len
= strlen (traceframe_sal
.symtab
->filename
);
307 file_range
= create_range_type (file_range
,
308 builtin_type_int
, 0, len
- 1);
309 file_string
= create_array_type (file_string
,
310 builtin_type_char
, file_range
);
311 file_val
= allocate_value (file_string
);
312 VALUE_TYPE (file_val
) = file_string
;
313 memcpy (VALUE_CONTENTS_RAW (file_val
),
314 traceframe_sal
.symtab
->filename
,
316 file_val
->modifiable
= 0;
317 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
321 /* Low level routine to set a tracepoint.
322 Returns the tracepoint object so caller can set other things.
323 Does not set the tracepoint number!
324 Does not print anything.
326 ==> This routine should not be called if there is a chance of later
327 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
328 your arguments BEFORE calling this routine! */
330 static struct tracepoint
*
331 set_raw_tracepoint (sal
)
332 struct symtab_and_line sal
;
334 register struct tracepoint
*t
, *tc
;
335 struct cleanup
*old_chain
;
337 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
338 old_chain
= make_cleanup (free
, t
);
339 memset (t
, 0, sizeof (*t
));
341 if (sal
.symtab
== NULL
)
342 t
->source_file
= NULL
;
344 t
->source_file
= savestring (sal
.symtab
->filename
,
345 strlen (sal
.symtab
->filename
));
347 t
->section
= sal
.section
;
348 t
->language
= current_language
->la_language
;
349 t
->input_radix
= input_radix
;
350 t
->line_number
= sal
.line
;
351 t
->enabled
= enabled
;
355 t
->addr_string
= NULL
;
357 /* Add this tracepoint to the end of the chain
358 so that a list of tracepoints will come out in order
359 of increasing numbers. */
361 tc
= tracepoint_chain
;
363 tracepoint_chain
= t
;
370 discard_cleanups (old_chain
);
374 /* Set a tracepoint according to ARG (function, linenum or *address) */
376 trace_command (arg
, from_tty
)
380 char **canonical
= (char **) NULL
;
381 struct symtabs_and_lines sals
;
382 struct symtab_and_line sal
;
383 struct tracepoint
*t
;
384 char *addr_start
= 0, *addr_end
= 0;
388 error ("trace command requires an argument");
390 if (from_tty
&& info_verbose
)
391 printf_filtered ("TRACE %s\n", arg
);
394 sals
= decode_line_1 (&arg
, 1, (struct symtab
*) NULL
, 0, &canonical
);
397 return; /* ??? Presumably decode_line_1 has already warned? */
399 /* Resolve all line numbers to PC's */
400 for (i
= 0; i
< sals
.nelts
; i
++)
401 resolve_sal_pc (&sals
.sals
[i
]);
403 /* Now set all the tracepoints. */
404 for (i
= 0; i
< sals
.nelts
; i
++)
408 t
= set_raw_tracepoint (sal
);
409 set_tracepoint_count (tracepoint_count
+ 1);
410 t
->number
= tracepoint_count
;
412 /* If a canonical line spec is needed use that instead of the
414 if (canonical
!= (char **) NULL
&& canonical
[i
] != NULL
)
415 t
->addr_string
= canonical
[i
];
417 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
421 /* Let the UI know of any additions */
422 if (create_tracepoint_hook
)
423 create_tracepoint_hook (t
);
428 printf_filtered ("Multiple tracepoints were set.\n");
429 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
433 /* Tell the user we have just set a tracepoint TP. */
437 struct tracepoint
*tp
;
439 printf_filtered ("Tracepoint %d", tp
->number
);
441 if (addressprint
|| (tp
->source_file
== NULL
))
443 printf_filtered (" at ");
444 print_address_numeric (tp
->address
, 1, gdb_stdout
);
447 printf_filtered (": file %s, line %d.",
448 tp
->source_file
, tp
->line_number
);
450 printf_filtered ("\n");
453 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
456 tracepoints_info (tpnum_exp
, from_tty
)
460 struct tracepoint
*t
;
461 struct action_line
*action
;
462 int found_a_tracepoint
= 0;
463 char wrap_indent
[80];
468 tpnum
= parse_and_eval_address (tpnum_exp
);
471 if (tpnum
== -1 || tpnum
== t
->number
)
473 extern int addressprint
; /* print machine addresses? */
475 if (!found_a_tracepoint
++)
477 printf_filtered ("Num Enb ");
479 printf_filtered ("Address ");
480 printf_filtered ("PassC StepC What\n");
482 strcpy (wrap_indent
, " ");
484 strcat (wrap_indent
, " ");
486 printf_filtered ("%-3d %-3s ", t
->number
,
487 t
->enabled
== enabled
? "y" : "n");
489 printf_filtered ("%s ",
490 local_hex_string_custom ((unsigned long) t
->address
,
492 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
496 sym
= find_pc_sect_function (t
->address
, t
->section
);
499 fputs_filtered ("in ", gdb_stdout
);
500 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
501 wrap_here (wrap_indent
);
502 fputs_filtered (" at ", gdb_stdout
);
504 fputs_filtered (t
->source_file
, gdb_stdout
);
505 printf_filtered (":%d", t
->line_number
);
508 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
510 printf_filtered ("\n");
513 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
514 for (action
= t
->actions
; action
; action
= action
->next
)
516 printf_filtered ("\t%s\n", action
->action
);
520 if (!found_a_tracepoint
)
523 printf_filtered ("No tracepoints.\n");
525 printf_filtered ("No tracepoint number %d.\n", tpnum
);
529 /* Optimization: the code to parse an enable, disable, or delete TP command
530 is virtually identical except for whether it performs an enable, disable,
531 or delete. Therefore I've combined them into one function with an opcode.
533 enum tracepoint_opcode
540 /* This function implements enable, disable and delete. */
542 tracepoint_operation (t
, from_tty
, opcode
)
543 struct tracepoint
*t
;
545 enum tracepoint_opcode opcode
;
547 struct tracepoint
*t2
;
552 t
->enabled
= enabled
;
553 if (modify_tracepoint_hook
)
554 modify_tracepoint_hook (t
);
557 t
->enabled
= disabled
;
558 if (modify_tracepoint_hook
)
559 modify_tracepoint_hook (t
);
562 if (tracepoint_chain
== t
)
563 tracepoint_chain
= t
->next
;
572 /* Let the UI know of any deletions */
573 if (delete_tracepoint_hook
)
574 delete_tracepoint_hook (t
);
577 free (t
->addr_string
);
579 free (t
->source_file
);
588 /* Utility: parse a tracepoint number and look it up in the list. */
590 get_tracepoint_by_number (arg
)
593 struct tracepoint
*t
;
599 error ("Bad tracepoint argument");
601 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
602 tpnum
= tracepoint_count
;
603 else if (**arg
== '$') /* handle convenience variable */
605 /* Make a copy of the name, so we can null-terminate it
606 to pass to lookup_internalvar(). */
608 while (isalnum (*end
) || *end
== '_')
610 copy
= (char *) alloca (end
- *arg
);
611 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
612 copy
[end
- *arg
- 1] = '\0';
615 val
= value_of_internalvar (lookup_internalvar (copy
));
616 if (TYPE_CODE (VALUE_TYPE (val
)) != TYPE_CODE_INT
)
617 error ("Convenience variable must have integral type.");
618 tpnum
= (int) value_as_long (val
);
621 /* 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 t
= get_tracepoint_by_number (&args
);
657 tracepoint_operation (t
, from_tty
, opcode
);
658 while (*args
== ' ' || *args
== '\t')
663 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
665 enable_trace_command (args
, from_tty
)
670 map_args_over_tracepoints (args
, from_tty
, enable
);
673 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
675 disable_trace_command (args
, from_tty
)
680 map_args_over_tracepoints (args
, from_tty
, disable
);
683 /* Remove a tracepoint (or all if no argument) */
685 delete_trace_command (args
, from_tty
)
690 if (!args
|| !*args
) /* No args implies all tracepoints; */
691 if (from_tty
) /* confirm only if from_tty... */
692 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
693 if (!query ("Delete all tracepoints? "))
696 map_args_over_tracepoints (args
, from_tty
, delete);
699 /* Set passcount for tracepoint.
701 First command argument is passcount, second is tracepoint number.
702 If tracepoint number omitted, apply to most recently defined.
703 Also accepts special argument "all". */
706 trace_pass_command (args
, from_tty
)
710 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
713 if (args
== 0 || *args
== 0)
714 error ("PASS command requires an argument (count + optional TP num)");
716 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
718 while (*args
&& isspace (*args
))
721 if (*args
&& strncasecmp (args
, "all", 3) == 0)
722 args
+= 3; /* skip special argument "all" */
724 t1
= get_tracepoint_by_number (&args
);
727 error ("Junk at end of arguments.");
730 return; /* error, bad tracepoint number */
733 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
735 t2
->pass_count
= count
;
736 if (modify_tracepoint_hook
)
737 modify_tracepoint_hook (t2
);
739 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
744 /* ACTIONS functions: */
746 /* Prototypes for action-parsing utility commands */
747 static void read_actions
PARAMS ((struct tracepoint
*));
748 static char *parse_and_eval_memrange
PARAMS ((char *,
754 /* The three functions:
755 collect_pseudocommand,
756 while_stepping_pseudocommand, and
757 end_actions_pseudocommand
758 are placeholders for "commands" that are actually ONLY to be used
759 within a tracepoint action list. If the actual function is ever called,
760 it means that somebody issued the "command" at the top level,
761 which is always an error. */
764 end_actions_pseudocommand (args
, from_tty
)
768 error ("This command cannot be used at the top level.");
772 while_stepping_pseudocommand (args
, from_tty
)
776 error ("This command can only be used in a tracepoint actions list.");
780 collect_pseudocommand (args
, from_tty
)
784 error ("This command can only be used in a tracepoint actions list.");
787 /* Enter a list of actions for a tracepoint. */
789 trace_actions_command (args
, from_tty
)
793 struct tracepoint
*t
;
796 char *end_msg
= "End with a line saying just \"end\".";
798 t
= get_tracepoint_by_number (&args
);
801 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
806 if (readline_begin_hook
)
807 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
808 else if (input_from_terminal_p ())
809 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
813 t
->step_count
= 0; /* read_actions may set this */
816 if (readline_end_hook
)
817 (*readline_end_hook
) ();
819 /* tracepoints_changed () */
821 /* else error, just return; */
824 /* worker function */
827 struct tracepoint
*t
;
830 char *prompt1
= "> ", *prompt2
= " > ";
831 char *prompt
= prompt1
;
832 enum actionline_type linetype
;
833 extern FILE *instream
;
834 struct action_line
*next
= NULL
, *temp
;
835 struct cleanup
*old_chain
;
837 /* Control-C quits instantly if typed while in this loop
838 since it should not wait until the user types a newline. */
844 signal (STOP_SIGNAL
, handle_stop_sig
);
846 signal (STOP_SIGNAL
, stop_sig
);
849 old_chain
= make_cleanup ((make_cleanup_func
) free_actions
, (void *) t
);
852 /* Make sure that all output has been output. Some machines may let
853 you get away with leaving out some of the gdb_flush, but not all. */
855 gdb_flush (gdb_stdout
);
856 gdb_flush (gdb_stderr
);
858 if (readline_hook
&& instream
== NULL
)
859 line
= (*readline_hook
) (prompt
);
860 else if (instream
== stdin
&& ISATTY (instream
))
862 line
= readline (prompt
);
863 if (line
&& *line
) /* add it to command history */
867 line
= gdb_readline (0);
869 linetype
= validate_actionline (&line
, t
);
870 if (linetype
== BADLINE
)
871 continue; /* already warned -- collect another line */
873 temp
= xmalloc (sizeof (struct action_line
));
877 if (next
== NULL
) /* first action for this tracepoint? */
878 t
->actions
= next
= temp
;
885 if (linetype
== STEPPING
) /* begin "while-stepping" */
887 if (prompt
== prompt2
)
889 warning ("Already processing 'while-stepping'");
893 prompt
= prompt2
; /* change prompt for stepping actions */
895 else if (linetype
== END
)
897 if (prompt
== prompt2
)
899 prompt
= prompt1
; /* end of single-stepping actions */
902 { /* end of actions */
903 if (t
->actions
->next
== NULL
)
905 /* an "end" all by itself with no other actions means
906 this tracepoint has no actions. Discard empty list. */
915 signal (STOP_SIGNAL
, SIG_DFL
);
918 discard_cleanups (old_chain
);
921 /* worker function */
923 validate_actionline (line
, t
)
925 struct tracepoint
*t
;
927 struct cmd_list_element
*c
;
928 struct expression
*exp
= NULL
;
929 value_ptr temp
, temp2
;
930 struct cleanup
*old_chain
= NULL
;
933 for (p
= *line
; isspace (*p
);)
936 /* symbol lookup etc. */
937 if (*p
== '\0') /* empty line: just prompt for another line. */
940 if (*p
== '#') /* comment line */
943 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
946 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
950 if (c
->function
.cfunc
== collect_pseudocommand
)
952 struct agent_expr
*aexpr
;
953 struct agent_reqs areqs
;
956 { /* repeat over a comma-separated list */
957 QUIT
; /* allow user to bail out with ^C */
961 if (*p
== '$') /* look for special pseudo-symbols */
964 bfd_signed_vma offset
;
966 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
967 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
968 (0 == strncasecmp ("loc", p
+ 1, 3)))
973 /* else fall thru, treat p as an expression and parse it! */
975 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
976 old_chain
= make_cleanup ((make_cleanup_func
) free_current_contents
,
979 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
981 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
983 warning ("%s is constant (value %d): will not be collected.",
984 SYMBOL_NAME (exp
->elts
[2].symbol
),
985 SYMBOL_VALUE (exp
->elts
[2].symbol
));
988 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
990 warning ("%s is optimized away and cannot be collected.",
991 SYMBOL_NAME (exp
->elts
[2].symbol
));
996 /* we have something to collect, make sure that the expr to
997 bytecode translator can handle it and that it's not too long */
998 aexpr
= gen_trace_for_expr (t
->address
, exp
);
999 (void) make_cleanup ((make_cleanup_func
) free_agent_expr
, aexpr
);
1001 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
1002 error ("expression too complicated, try simplifying");
1004 ax_reqs (aexpr
, &areqs
);
1005 (void) make_cleanup (free
, areqs
.reg_mask
);
1007 if (areqs
.flaw
!= agent_flaw_none
)
1008 error ("malformed expression");
1010 if (areqs
.min_height
< 0)
1011 error ("gdb: Internal error: expression has min height < 0");
1013 if (areqs
.max_height
> 20)
1014 error ("expression too complicated, try simplifying");
1016 do_cleanups (old_chain
);
1018 while (p
&& *p
++ == ',');
1021 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
1023 char *steparg
; /* in case warning is necessary */
1025 while (isspace (*p
))
1030 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1032 warning ("bad step-count: command ignored.", *line
);
1037 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1041 warning ("'%s' is not a supported tracepoint action.", *line
);
1046 /* worker function */
1049 struct tracepoint
*t
;
1051 struct action_line
*line
, *next
;
1053 for (line
= t
->actions
; line
; line
= next
)
1057 free (line
->action
);
1065 int type
; /* 0 for absolute memory range, else basereg number */
1066 bfd_signed_vma start
;
1070 struct collection_list
1072 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1075 struct memrange
*list
;
1076 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1077 long next_aexpr_elt
;
1078 struct agent_expr
**aexpr_list
;
1081 tracepoint_list
, stepping_list
;
1083 /* MEMRANGE functions: */
1085 static int memrange_cmp
PARAMS ((const void *, const void *));
1087 /* compare memranges for qsort */
1089 memrange_cmp (va
, vb
)
1093 const struct memrange
*a
= va
, *b
= vb
;
1095 if (a
->type
< b
->type
)
1097 if (a
->type
> b
->type
)
1101 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
)
1103 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
)
1108 if (a
->start
< b
->start
)
1110 if (a
->start
> b
->start
)
1116 /* Sort the memrange list using qsort, and merge adjacent memranges */
1118 memrange_sortmerge (memranges
)
1119 struct collection_list
*memranges
;
1123 qsort (memranges
->list
, memranges
->next_memrange
,
1124 sizeof (struct memrange
), memrange_cmp
);
1125 if (memranges
->next_memrange
> 0)
1127 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1129 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1130 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1131 MAX_REGISTER_VIRTUAL_SIZE
)
1133 /* memrange b starts before memrange a ends; merge them. */
1134 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1135 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1136 continue; /* next b, same a */
1140 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1141 sizeof (struct memrange
));
1143 memranges
->next_memrange
= a
+ 1;
1147 /* Add a register to a collection list */
1149 add_register (collection
, regno
)
1150 struct collection_list
*collection
;
1151 unsigned long regno
;
1154 printf_filtered ("collect register %d\n", regno
);
1155 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1156 error ("Internal: register number %d too large for tracepoint",
1158 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1161 /* Add a memrange to a collection list */
1163 add_memrange (memranges
, type
, base
, len
)
1164 struct collection_list
*memranges
;
1166 bfd_signed_vma base
;
1170 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1171 /* type: 0 == memory, n == basereg */
1172 memranges
->list
[memranges
->next_memrange
].type
= type
;
1173 /* base: addr if memory, offset if reg relative. */
1174 memranges
->list
[memranges
->next_memrange
].start
= base
;
1175 /* len: we actually save end (base + len) for convenience */
1176 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1177 memranges
->next_memrange
++;
1178 if (memranges
->next_memrange
>= memranges
->listsize
)
1180 memranges
->listsize
*= 2;
1181 memranges
->list
= xrealloc (memranges
->list
,
1182 memranges
->listsize
);
1185 if (type
!= -1) /* better collect the base register! */
1186 add_register (memranges
, type
);
1189 /* Add a symbol to a collection list */
1191 collect_symbol (collect
, sym
, frame_regno
, frame_offset
)
1192 struct collection_list
*collect
;
1199 bfd_signed_vma offset
;
1201 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1202 switch (SYMBOL_CLASS (sym
))
1205 printf_filtered ("%s: don't know symbol class %d\n",
1206 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1209 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1210 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1213 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1215 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1216 SYMBOL_NAME (sym
), len
, offset
);
1217 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1221 reg
= SYMBOL_VALUE (sym
);
1223 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1224 add_register (collect
, reg
);
1225 /* check for doubles stored in two registers */
1226 /* FIXME: how about larger types stored in 3 or more regs? */
1227 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1228 len
> REGISTER_RAW_SIZE (reg
))
1229 add_register (collect
, reg
+ 1);
1232 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1233 printf_filtered (" (will not collect %s)\n",
1238 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1241 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1242 SYMBOL_NAME (sym
), len
);
1243 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1245 add_memrange (collect
, reg
, offset
, len
);
1247 case LOC_REGPARM_ADDR
:
1248 reg
= SYMBOL_VALUE (sym
);
1252 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
1253 SYMBOL_NAME (sym
), len
);
1254 printf_filtered (" %d from reg %d\n", offset
, reg
);
1256 add_memrange (collect
, reg
, offset
, len
);
1261 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1264 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1265 SYMBOL_NAME (sym
), len
);
1266 printf_filtered (" %d from frame ptr reg %d\n", offset
, reg
);
1268 add_memrange (collect
, reg
, offset
, len
);
1271 case LOC_BASEREG_ARG
:
1272 reg
= SYMBOL_BASEREG (sym
);
1273 offset
= SYMBOL_VALUE (sym
);
1276 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1277 SYMBOL_NAME (sym
), len
, offset
, reg
);
1279 add_memrange (collect
, reg
, offset
, len
);
1281 case LOC_UNRESOLVED
:
1282 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1284 case LOC_OPTIMIZED_OUT
:
1285 printf_filtered ("%s has been optimized out of existance.\n",
1291 /* Add all locals (or args) symbols to collection list */
1293 add_local_symbols (collect
, pc
, frame_regno
, frame_offset
, type
)
1294 struct collection_list
*collect
;
1301 struct block
*block
;
1302 int i
, nsyms
, count
= 0;
1304 block
= block_for_pc (pc
);
1307 QUIT
; /* allow user to bail out with ^C */
1308 nsyms
= BLOCK_NSYMS (block
);
1309 for (i
= 0; i
< nsyms
; i
++)
1311 sym
= BLOCK_SYM (block
, i
);
1312 switch (SYMBOL_CLASS (sym
))
1318 if (type
== 'L') /* collecting Locals */
1321 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1328 case LOC_REGPARM_ADDR
:
1329 case LOC_BASEREG_ARG
:
1330 if (type
== 'A') /* collecting Arguments */
1333 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1337 if (BLOCK_FUNCTION (block
))
1340 block
= BLOCK_SUPERBLOCK (block
);
1343 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1346 /* worker function */
1348 clear_collection_list (list
)
1349 struct collection_list
*list
;
1353 list
->next_memrange
= 0;
1354 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1356 free_agent_expr (list
->aexpr_list
[ndx
]);
1357 list
->aexpr_list
[ndx
] = NULL
;
1359 list
->next_aexpr_elt
= 0;
1360 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1363 /* reduce a collection list to string form (for gdb protocol) */
1365 stringify_collection_list (list
, string
)
1366 struct collection_list
*list
;
1369 char temp_buf
[2048];
1372 char *(*str_list
)[];
1376 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1377 str_list
= (char *(*)[]) xmalloc (count
* sizeof (char *));
1379 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1380 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1382 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1385 printf_filtered ("\nCollecting registers (mask): 0x");
1390 QUIT
; /* allow user to bail out with ^C */
1392 printf_filtered ("%02X", list
->regs_mask
[i
]);
1393 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1396 (*str_list
)[ndx
] = savestring (temp_buf
, end
- temp_buf
);
1400 printf_filtered ("\n");
1401 if (list
->next_memrange
> 0 && info_verbose
)
1402 printf_filtered ("Collecting memranges: \n");
1403 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1405 QUIT
; /* allow user to bail out with ^C */
1407 printf_filtered ("(%d, 0x%x, %d)\n",
1409 list
->list
[i
].start
,
1410 list
->list
[i
].end
- list
->list
[i
].start
);
1411 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1413 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1418 sprintf (end
, "M%X,%X,%X",
1420 list
->list
[i
].start
,
1421 list
->list
[i
].end
- list
->list
[i
].start
);
1422 count
+= strlen (end
);
1423 end
+= strlen (end
);
1426 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1428 QUIT
; /* allow user to bail out with ^C */
1429 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1431 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1436 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1437 end
+= 10; /* 'X' + 8 hex digits + ',' */
1440 end
= mem2hex (list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1441 count
+= 2 * list
->aexpr_list
[i
]->len
;
1446 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1451 (*str_list
)[ndx
] = NULL
;
1460 free_actions_list_cleanup_wrapper (al
)
1463 free_actions_list (al
);
1467 free_actions_list (actions_list
)
1468 char **actions_list
;
1472 if (actions_list
== 0)
1475 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1476 free (actions_list
[ndx
]);
1478 free (actions_list
);
1481 /* render all actions into gdb protocol */
1483 encode_actions (t
, tdp_actions
, stepping_actions
)
1484 struct tracepoint
*t
;
1485 char ***tdp_actions
;
1486 char ***stepping_actions
;
1488 static char tdp_buff
[2048], step_buff
[2048];
1490 struct expression
*exp
= NULL
;
1491 struct action_line
*action
;
1492 bfd_signed_vma offset
;
1495 struct collection_list
*collect
;
1496 struct cmd_list_element
*cmd
;
1497 struct agent_expr
*aexpr
;
1498 long frame_reg
, frame_offset
;
1501 clear_collection_list (&tracepoint_list
);
1502 clear_collection_list (&stepping_list
);
1503 collect
= &tracepoint_list
;
1505 *tdp_actions
= NULL
;
1506 *stepping_actions
= NULL
;
1508 TARGET_VIRTUAL_FRAME_POINTER (t
->address
, &frame_reg
, &frame_offset
);
1510 for (action
= t
->actions
; action
; action
= action
->next
)
1512 QUIT
; /* allow user to bail out with ^C */
1513 action_exp
= action
->action
;
1514 while (isspace (*action_exp
))
1517 if (*action_exp
== '#') /* comment line */
1520 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1522 error ("Bad action list item: %s", action_exp
);
1524 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1527 { /* repeat over a comma-separated list */
1528 QUIT
; /* allow user to bail out with ^C */
1529 while (isspace (*action_exp
))
1532 if (0 == strncasecmp ("$reg", action_exp
, 4))
1534 for (i
= 0; i
< NUM_REGS
; i
++)
1535 add_register (collect
, i
);
1536 action_exp
= strchr (action_exp
, ','); /* more? */
1538 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1540 add_local_symbols (collect
,
1545 action_exp
= strchr (action_exp
, ','); /* more? */
1547 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1549 add_local_symbols (collect
,
1554 action_exp
= strchr (action_exp
, ','); /* more? */
1558 unsigned long addr
, len
;
1559 struct cleanup
*old_chain
= NULL
;
1560 struct cleanup
*old_chain1
= NULL
;
1561 struct agent_reqs areqs
;
1563 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1564 old_chain
= make_cleanup ((make_cleanup_func
)
1565 free_current_contents
, &exp
);
1567 switch (exp
->elts
[0].opcode
)
1570 i
= exp
->elts
[1].longconst
;
1572 printf_filtered ("OP_REGISTER: ");
1573 add_register (collect
, i
);
1577 /* safe because we know it's a simple expression */
1578 tempval
= evaluate_expression (exp
);
1579 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1580 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1581 add_memrange (collect
, -1, addr
, len
);
1585 collect_symbol (collect
,
1586 exp
->elts
[2].symbol
,
1591 default: /* full-fledged expression */
1592 aexpr
= gen_trace_for_expr (t
->address
, exp
);
1594 old_chain1
= make_cleanup ((make_cleanup_func
)
1595 free_agent_expr
, aexpr
);
1597 ax_reqs (aexpr
, &areqs
);
1598 if (areqs
.flaw
!= agent_flaw_none
)
1599 error ("malformed expression");
1601 if (areqs
.min_height
< 0)
1602 error ("gdb: Internal error: expression has min height < 0");
1603 if (areqs
.max_height
> 20)
1604 error ("expression too complicated, try simplifying");
1606 discard_cleanups (old_chain1
);
1607 add_aexpr (collect
, aexpr
);
1609 /* take care of the registers */
1610 if (areqs
.reg_mask_len
> 0)
1615 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1617 QUIT
; /* allow user to bail out with ^C */
1618 if (areqs
.reg_mask
[ndx1
] != 0)
1620 /* assume chars have 8 bits */
1621 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1622 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1623 /* it's used -- record it */
1624 add_register (collect
, ndx1
* 8 + ndx2
);
1630 do_cleanups (old_chain
);
1633 while (action_exp
&& *action_exp
++ == ',');
1635 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1637 collect
= &stepping_list
;
1639 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1641 if (collect
== &stepping_list
) /* end stepping actions */
1642 collect
= &tracepoint_list
;
1644 break; /* end tracepoint actions */
1647 memrange_sortmerge (&tracepoint_list
);
1648 memrange_sortmerge (&stepping_list
);
1650 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1651 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1655 add_aexpr (collect
, aexpr
)
1656 struct collection_list
*collect
;
1657 struct agent_expr
*aexpr
;
1659 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1661 collect
->aexpr_list
=
1662 xrealloc (collect
->aexpr_list
,
1663 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1664 collect
->aexpr_listsize
*= 2;
1666 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1667 collect
->next_aexpr_elt
++;
1670 static char target_buf
[2048];
1672 /* Set "transparent" memory ranges
1674 Allow trace mechanism to treat text-like sections
1675 (and perhaps all read-only sections) transparently,
1676 i.e. don't reject memory requests from these address ranges
1677 just because they haven't been collected. */
1680 remote_set_transparent_ranges (void)
1682 extern bfd
*exec_bfd
;
1689 return; /* no information to give. */
1691 strcpy (target_buf
, "QTro");
1692 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1696 if ((s
->flags
& SEC_LOAD
) == 0 ||
1697 /* (s->flags & SEC_CODE) == 0 || */
1698 (s
->flags
& SEC_READONLY
) == 0)
1703 size
= bfd_get_section_size_before_reloc (s
);
1704 sprintf (tmp
, ":%x,%x", lma
, lma
+ size
);
1705 strcat (target_buf
, tmp
);
1709 putpkt (target_buf
);
1710 getpkt (target_buf
, 0);
1716 Tell target to clear any previous trace experiment.
1717 Walk the list of tracepoints, and send them (and their actions)
1718 to the target. If no errors,
1719 Tell target to start a new trace experiment. */
1722 trace_start_command (args
, from_tty
)
1725 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1726 struct tracepoint
*t
;
1729 char **stepping_actions
;
1731 struct cleanup
*old_chain
= NULL
;
1733 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1735 if (target_is_remote ())
1738 remote_get_noisy_reply (target_buf
);
1739 if (strcmp (target_buf
, "OK"))
1740 error ("Target does not support this command.");
1744 int ss_count
; /* if actions include singlestepping */
1745 int disable_mask
; /* ??? */
1746 int enable_mask
; /* ??? */
1748 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1749 t
->enabled
== enabled
? 'E' : 'D',
1750 t
->step_count
, t
->pass_count
);
1755 remote_get_noisy_reply (target_buf
);
1756 if (strcmp (target_buf
, "OK"))
1757 error ("Target does not support tracepoints.");
1761 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1762 old_chain
= make_cleanup (free_actions_list_cleanup_wrapper
,
1764 (void) make_cleanup (free_actions_list_cleanup_wrapper
,
1767 /* do_single_steps (t); */
1770 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1772 QUIT
; /* allow user to bail out with ^C */
1773 sprintf (buf
, "QTDP:-%x:%x:%s%c",
1774 t
->number
, t
->address
,
1776 ((tdp_actions
[ndx
+ 1] || stepping_actions
)
1779 remote_get_noisy_reply (target_buf
);
1780 if (strcmp (target_buf
, "OK"))
1781 error ("Error on target while setting tracepoints.");
1784 if (stepping_actions
)
1786 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1788 QUIT
; /* allow user to bail out with ^C */
1789 sprintf (buf
, "QTDP:-%x:%x:%s%s%s",
1790 t
->number
, t
->address
,
1791 ((ndx
== 0) ? "S" : ""),
1792 stepping_actions
[ndx
],
1793 (stepping_actions
[ndx
+ 1] ? "-" : ""));
1795 remote_get_noisy_reply (target_buf
);
1796 if (strcmp (target_buf
, "OK"))
1797 error ("Error on target while setting tracepoints.");
1801 do_cleanups (old_chain
);
1804 /* Tell target to treat text-like sections as transparent */
1805 remote_set_transparent_ranges ();
1806 /* Now insert traps and begin collecting data */
1808 remote_get_noisy_reply (target_buf
);
1809 if (strcmp (target_buf
, "OK"))
1810 error ("Bogus reply from target: %s", target_buf
);
1811 set_traceframe_num (-1); /* all old traceframes invalidated */
1812 set_tracepoint_num (-1);
1813 set_traceframe_context (-1);
1814 trace_running_p
= 1;
1815 if (trace_start_stop_hook
)
1816 trace_start_stop_hook (1, from_tty
);
1820 error ("Trace can only be run on remote targets.");
1825 trace_stop_command (args
, from_tty
)
1828 { /* STUB_COMM IS_IMPLEMENTED */
1829 if (target_is_remote ())
1832 remote_get_noisy_reply (target_buf
);
1833 if (strcmp (target_buf
, "OK"))
1834 error ("Bogus reply from target: %s", target_buf
);
1835 trace_running_p
= 0;
1836 if (trace_start_stop_hook
)
1837 trace_start_stop_hook (0, from_tty
);
1840 error ("Trace can only be run on remote targets.");
1843 unsigned long trace_running_p
;
1845 /* tstatus command */
1847 trace_status_command (args
, from_tty
)
1850 { /* STUB_COMM IS_IMPLEMENTED */
1851 if (target_is_remote ())
1853 putpkt ("qTStatus");
1854 remote_get_noisy_reply (target_buf
);
1856 if (target_buf
[0] != 'T' ||
1857 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1858 error ("Bogus reply from target: %s", target_buf
);
1860 /* exported for use by the GUI */
1861 trace_running_p
= (target_buf
[1] == '1');
1864 error ("Trace can only be run on remote targets.");
1867 /* Worker function for the various flavors of the tfind command */
1869 finish_tfind_command (msg
, from_tty
)
1873 int target_frameno
= -1, target_tracept
= -1;
1874 CORE_ADDR old_frame_addr
;
1875 struct symbol
*old_func
;
1878 old_frame_addr
= FRAME_FP (get_current_frame ());
1879 old_func
= find_pc_function (read_pc ());
1882 reply
= remote_get_noisy_reply (msg
);
1884 while (reply
&& *reply
)
1888 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1890 /* A request for a non-existant trace frame has failed.
1891 Our response will be different, depending on FROM_TTY:
1893 If FROM_TTY is true, meaning that this command was
1894 typed interactively by the user, then give an error
1895 and DO NOT change the state of traceframe_number etc.
1897 However if FROM_TTY is false, meaning that we're either
1898 in a script, a loop, or a user-defined command, then
1899 DON'T give an error, but DO change the state of
1900 traceframe_number etc. to invalid.
1902 The rationalle is that if you typed the command, you
1903 might just have committed a typo or something, and you'd
1904 like to NOT lose your current debugging state. However
1905 if you're in a user-defined command or especially in a
1906 loop, then you need a way to detect that the command
1907 failed WITHOUT aborting. This allows you to write
1908 scripts that search thru the trace buffer until the end,
1909 and then continue on to do something else. */
1912 error ("Target failed to find requested trace frame.");
1916 printf_filtered ("End of trace buffer.\n");
1917 /* The following will not recurse, since it's special-cased */
1918 trace_find_command ("-1", from_tty
);
1919 reply
= NULL
; /* break out of loop,
1920 (avoid recursive nonsense) */
1925 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1926 error ("Target failed to find requested trace frame.");
1928 case 'O': /* "OK"? */
1929 if (reply
[1] == 'K' && reply
[2] == '\0')
1932 error ("Bogus reply from target: %s", reply
);
1935 error ("Bogus reply from target: %s", reply
);
1938 flush_cached_frames ();
1939 registers_changed ();
1940 select_frame (get_current_frame (), 0);
1941 set_traceframe_num (target_frameno
);
1942 set_tracepoint_num (target_tracept
);
1943 if (target_frameno
== -1)
1944 set_traceframe_context (-1);
1946 set_traceframe_context (read_pc ());
1952 /* NOTE: in immitation of the step command, try to determine
1953 whether we have made a transition from one function to another.
1954 If so, we'll print the "stack frame" (ie. the new function and
1955 it's arguments) -- otherwise we'll just show the new source line.
1957 This determination is made by checking (1) whether the current
1958 function has changed, and (2) whether the current FP has changed.
1959 Hack: if the FP wasn't collected, either at the current or the
1960 previous frame, assume that the FP has NOT changed. */
1962 if (old_func
== find_pc_function (read_pc ()) &&
1963 (old_frame_addr
== 0 ||
1964 FRAME_FP (get_current_frame ()) == 0 ||
1965 old_frame_addr
== FRAME_FP (get_current_frame ())))
1970 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1975 /* trace_find_command takes a trace frame number n,
1976 sends "QTFrame:<n>" to the target,
1977 and accepts a reply that may contain several optional pieces
1978 of information: a frame number, a tracepoint number, and an
1979 indication of whether this is a trap frame or a stepping frame.
1981 The minimal response is just "OK" (which indicates that the
1982 target does not give us a frame number or a tracepoint number).
1983 Instead of that, the target may send us a string containing
1985 F<hexnum> (gives the selected frame number)
1986 T<hexnum> (gives the selected tracepoint number)
1991 trace_find_command (args
, from_tty
)
1994 { /* STUB_COMM PART_IMPLEMENTED */
1995 /* this should only be called with a numeric argument */
1999 if (target_is_remote ())
2001 if (trace_find_hook
)
2002 trace_find_hook (args
, from_tty
);
2004 if (args
== 0 || *args
== 0)
2005 { /* TFIND with no args means find NEXT trace frame. */
2006 if (traceframe_number
== -1)
2007 frameno
= 0; /* "next" is first one */
2009 frameno
= traceframe_number
+ 1;
2011 else if (0 == strcmp (args
, "-"))
2013 if (traceframe_number
== -1)
2014 error ("not debugging trace buffer");
2015 else if (from_tty
&& traceframe_number
== 0)
2016 error ("already at start of trace buffer");
2018 frameno
= traceframe_number
- 1;
2021 frameno
= parse_and_eval_address (args
);
2024 error ("invalid input (%d is less than zero)", frameno
);
2026 sprintf (target_buf
, "QTFrame:%x", frameno
);
2027 finish_tfind_command (target_buf
, from_tty
);
2030 error ("Trace can only be run on remote targets.");
2035 trace_find_end_command (args
, from_tty
)
2039 trace_find_command ("-1", from_tty
);
2044 trace_find_none_command (args
, from_tty
)
2048 trace_find_command ("-1", from_tty
);
2053 trace_find_start_command (args
, from_tty
)
2057 trace_find_command ("0", from_tty
);
2060 /* tfind pc command */
2062 trace_find_pc_command (args
, from_tty
)
2065 { /* STUB_COMM PART_IMPLEMENTED */
2069 if (target_is_remote ())
2071 if (args
== 0 || *args
== 0)
2072 pc
= read_pc (); /* default is current pc */
2074 pc
= parse_and_eval_address (args
);
2076 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
2077 finish_tfind_command (target_buf
, from_tty
);
2080 error ("Trace can only be run on remote targets.");
2083 /* tfind tracepoint command */
2085 trace_find_tracepoint_command (args
, from_tty
)
2088 { /* STUB_COMM PART_IMPLEMENTED */
2092 if (target_is_remote ())
2094 if (args
== 0 || *args
== 0)
2095 if (tracepoint_number
== -1)
2096 error ("No current tracepoint -- please supply an argument.");
2098 tdp
= tracepoint_number
; /* default is current TDP */
2100 tdp
= parse_and_eval_address (args
);
2102 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2103 finish_tfind_command (target_buf
, from_tty
);
2106 error ("Trace can only be run on remote targets.");
2109 /* TFIND LINE command:
2111 This command will take a sourceline for argument, just like BREAK
2112 or TRACE (ie. anything that "decode_line_1" can handle).
2114 With no argument, this command will find the next trace frame
2115 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2118 trace_find_line_command (args
, from_tty
)
2121 { /* STUB_COMM PART_IMPLEMENTED */
2122 static CORE_ADDR start_pc
, end_pc
;
2123 struct symtabs_and_lines sals
;
2124 struct symtab_and_line sal
;
2126 struct cleanup
*old_chain
;
2128 if (target_is_remote ())
2130 if (args
== 0 || *args
== 0)
2132 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2134 sals
.sals
= (struct symtab_and_line
*)
2135 xmalloc (sizeof (struct symtab_and_line
));
2140 sals
= decode_line_spec (args
, 1);
2144 old_chain
= make_cleanup (free
, sals
.sals
);
2145 if (sal
.symtab
== 0)
2147 printf_filtered ("TFIND: No line number information available");
2150 /* This is useful for "info line *0x7f34". If we can't tell the
2151 user about a source line, at least let them have the symbolic
2153 printf_filtered (" for address ");
2155 print_address (sal
.pc
, gdb_stdout
);
2156 printf_filtered (";\n -- will attempt to find by PC. \n");
2160 printf_filtered (".\n");
2161 return; /* no line, no PC; what can we do? */
2164 else if (sal
.line
> 0
2165 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2167 if (start_pc
== end_pc
)
2169 printf_filtered ("Line %d of \"%s\"",
2170 sal
.line
, sal
.symtab
->filename
);
2172 printf_filtered (" is at address ");
2173 print_address (start_pc
, gdb_stdout
);
2175 printf_filtered (" but contains no code.\n");
2176 sal
= find_pc_line (start_pc
, 0);
2178 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2180 printf_filtered ("Attempting to find line %d instead.\n",
2183 error ("Cannot find a good line.");
2187 /* Is there any case in which we get here, and have an address
2188 which the user would want to see? If we have debugging symbols
2189 and no line numbers? */
2190 error ("Line number %d is out of range for \"%s\".\n",
2191 sal
.line
, sal
.symtab
->filename
);
2193 if (args
&& *args
) /* find within range of stated line */
2194 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
2195 else /* find OUTSIDE OF range of CURRENT line */
2196 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
2197 finish_tfind_command (target_buf
, from_tty
);
2198 do_cleanups (old_chain
);
2201 error ("Trace can only be run on remote targets.");
2204 /* tfind range command */
2206 trace_find_range_command (args
, from_tty
)
2209 { /* STUB_COMM PART_IMPLEMENTED */
2210 static CORE_ADDR start
, stop
;
2213 if (target_is_remote ())
2215 if (args
== 0 || *args
== 0)
2216 { /* XXX FIXME: what should default behavior be? */
2217 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2221 if (0 != (tmp
= strchr (args
, ',')))
2223 *tmp
++ = '\0'; /* terminate start address */
2224 while (isspace (*tmp
))
2226 start
= parse_and_eval_address (args
);
2227 stop
= parse_and_eval_address (tmp
);
2230 { /* no explicit end address? */
2231 start
= parse_and_eval_address (args
);
2232 stop
= start
+ 1; /* ??? */
2235 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2236 finish_tfind_command (target_buf
, from_tty
);
2239 error ("Trace can only be run on remote targets.");
2242 /* tfind outside command */
2244 trace_find_outside_command (args
, from_tty
)
2247 { /* STUB_COMM PART_IMPLEMENTED */
2248 CORE_ADDR start
, stop
;
2251 if (target_is_remote ())
2253 if (args
== 0 || *args
== 0)
2254 { /* XXX FIXME: what should default behavior be? */
2255 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2259 if (0 != (tmp
= strchr (args
, ',')))
2261 *tmp
++ = '\0'; /* terminate start address */
2262 while (isspace (*tmp
))
2264 start
= parse_and_eval_address (args
);
2265 stop
= parse_and_eval_address (tmp
);
2268 { /* no explicit end address? */
2269 start
= parse_and_eval_address (args
);
2270 stop
= start
+ 1; /* ??? */
2273 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2274 finish_tfind_command (target_buf
, from_tty
);
2277 error ("Trace can only be run on remote targets.");
2280 /* save-tracepoints command */
2282 tracepoint_save_command (args
, from_tty
)
2286 struct tracepoint
*tp
;
2287 struct action_line
*line
;
2289 char *i1
= " ", *i2
= " ";
2290 char *indent
, *actionline
;
2292 if (args
== 0 || *args
== 0)
2293 error ("Argument required (file name in which to save tracepoints");
2295 if (tracepoint_chain
== 0)
2297 warning ("save-tracepoints: no tracepoints to save.\n");
2301 if (!(fp
= fopen (args
, "w")))
2302 error ("Unable to open file '%s' for saving tracepoints");
2304 ALL_TRACEPOINTS (tp
)
2306 if (tp
->addr_string
)
2307 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2309 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2312 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2316 fprintf (fp
, " actions\n");
2318 for (line
= tp
->actions
; line
; line
= line
->next
)
2320 struct cmd_list_element
*cmd
;
2322 QUIT
; /* allow user to bail out with ^C */
2323 actionline
= line
->action
;
2324 while (isspace (*actionline
))
2327 fprintf (fp
, "%s%s\n", indent
, actionline
);
2328 if (*actionline
!= '#') /* skip for comment lines */
2330 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2332 error ("Bad action list item: %s", actionline
);
2333 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2335 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2343 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2347 /* info scope command: list the locals for a scope. */
2349 scope_info (args
, from_tty
)
2353 struct symtab_and_line sal
;
2354 struct symtabs_and_lines sals
;
2356 struct minimal_symbol
*msym
;
2357 struct block
*block
;
2358 char **canonical
, *symname
, *save_args
= args
;
2359 int i
, j
, nsyms
, count
= 0;
2361 if (args
== 0 || *args
== 0)
2362 error ("requires an argument (function, line or *addr) to define a scope");
2364 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2365 if (sals
.nelts
== 0)
2366 return; /* presumably decode_line_1 has already warned */
2368 /* Resolve line numbers to PC */
2369 resolve_sal_pc (&sals
.sals
[0]);
2370 block
= block_for_pc (sals
.sals
[0].pc
);
2374 QUIT
; /* allow user to bail out with ^C */
2375 nsyms
= BLOCK_NSYMS (block
);
2376 for (i
= 0; i
< nsyms
; i
++)
2378 QUIT
; /* allow user to bail out with ^C */
2380 printf_filtered ("Scope for %s:\n", save_args
);
2382 sym
= BLOCK_SYM (block
, i
);
2383 symname
= SYMBOL_NAME (sym
);
2384 if (symname
== NULL
|| *symname
== '\0')
2385 continue; /* probably botched, certainly useless */
2387 printf_filtered ("Symbol %s is ", symname
);
2388 switch (SYMBOL_CLASS (sym
))
2391 case LOC_UNDEF
: /* messed up symbol? */
2392 printf_filtered ("a bogus symbol, class %d.\n",
2393 SYMBOL_CLASS (sym
));
2394 count
--; /* don't count this one */
2397 printf_filtered ("a constant with value %d (0x%x)",
2398 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2400 case LOC_CONST_BYTES
:
2401 printf_filtered ("constant bytes: ");
2402 if (SYMBOL_TYPE (sym
))
2403 for (j
= 0; j
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); j
++)
2404 fprintf_filtered (gdb_stdout
, " %02x",
2405 (unsigned) SYMBOL_VALUE_BYTES (sym
)[j
]);
2408 printf_filtered ("in static storage at address ");
2409 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2412 printf_filtered ("a local variable in register $%s",
2413 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2417 printf_filtered ("an argument at stack/frame offset %ld",
2418 SYMBOL_VALUE (sym
));
2421 printf_filtered ("a local variable at frame offset %ld",
2422 SYMBOL_VALUE (sym
));
2425 printf_filtered ("a reference argument at offset %ld",
2426 SYMBOL_VALUE (sym
));
2429 printf_filtered ("an argument in register $%s",
2430 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2432 case LOC_REGPARM_ADDR
:
2433 printf_filtered ("the address of an argument, in register $%s",
2434 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2437 printf_filtered ("a typedef.\n");
2440 printf_filtered ("a label at address ");
2441 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2444 printf_filtered ("a function at address ");
2445 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2449 printf_filtered ("a variable at offset %d from register $%s",
2451 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2453 case LOC_BASEREG_ARG
:
2454 printf_filtered ("an argument at offset %d from register $%s",
2456 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2458 case LOC_UNRESOLVED
:
2459 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2461 printf_filtered ("Unresolved Static");
2464 printf_filtered ("static storage at address ");
2465 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2469 case LOC_OPTIMIZED_OUT
:
2470 printf_filtered ("optimized out.\n");
2473 if (SYMBOL_TYPE (sym
))
2474 printf_filtered (", length %d.\n",
2475 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2477 if (BLOCK_FUNCTION (block
))
2480 block
= BLOCK_SUPERBLOCK (block
);
2483 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2487 /* worker function (cleanup) */
2489 replace_comma (comma
)
2497 trace_dump_command (args
, from_tty
)
2501 struct tracepoint
*t
;
2502 struct action_line
*action
;
2503 char *action_exp
, *next_comma
;
2504 struct cleanup
*old_cleanups
;
2505 int stepping_actions
= 0;
2506 int stepping_frame
= 0;
2508 if (!target_is_remote ())
2510 error ("Trace can only be run on remote targets.");
2514 if (tracepoint_number
== -1)
2516 warning ("No current trace frame.");
2521 if (t
->number
== tracepoint_number
)
2525 error ("No known tracepoint matches 'current' tracepoint #%d.",
2528 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2530 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2531 tracepoint_number
, traceframe_number
);
2533 /* The current frame is a trap frame if the frame PC is equal
2534 to the tracepoint PC. If not, then the current frame was
2535 collected during single-stepping. */
2537 stepping_frame
= (t
->address
!= read_pc ());
2539 for (action
= t
->actions
; action
; action
= action
->next
)
2541 struct cmd_list_element
*cmd
;
2543 QUIT
; /* allow user to bail out with ^C */
2544 action_exp
= action
->action
;
2545 while (isspace (*action_exp
))
2548 /* The collection actions to be done while stepping are
2549 bracketed by the commands "while-stepping" and "end". */
2551 if (*action_exp
== '#') /* comment line */
2554 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2556 error ("Bad action list item: %s", action_exp
);
2558 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2559 stepping_actions
= 1;
2560 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2561 stepping_actions
= 0;
2562 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2564 /* Display the collected data.
2565 For the trap frame, display only what was collected at the trap.
2566 Likewise for stepping frames, display only what was collected
2567 while stepping. This means that the two boolean variables,
2568 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2569 if (stepping_frame
== stepping_actions
)
2572 { /* repeat over a comma-separated list */
2573 QUIT
; /* allow user to bail out with ^C */
2574 if (*action_exp
== ',')
2576 while (isspace (*action_exp
))
2579 next_comma
= strchr (action_exp
, ',');
2581 if (0 == strncasecmp (action_exp
, "$reg", 4))
2582 registers_info (NULL
, from_tty
);
2583 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2584 locals_info (NULL
, from_tty
);
2585 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2586 args_info (NULL
, from_tty
);
2591 make_cleanup (replace_comma
, next_comma
);
2594 printf_filtered ("%s = ", action_exp
);
2595 output_command (action_exp
, from_tty
);
2596 printf_filtered ("\n");
2600 action_exp
= next_comma
;
2602 while (action_exp
&& *action_exp
== ',');
2606 discard_cleanups (old_cleanups
);
2609 /* Convert the memory pointed to by mem into hex, placing result in buf.
2610 * Return a pointer to the last char put in buf (null)
2611 * "stolen" from sparc-stub.c
2614 static const char hexchars
[] = "0123456789abcdef";
2616 static unsigned char *
2617 mem2hex (mem
, buf
, count
)
2628 *buf
++ = hexchars
[ch
>> 4];
2629 *buf
++ = hexchars
[ch
& 0xf];
2638 get_traceframe_number ()
2640 return traceframe_number
;
2644 /* module initialization */
2646 _initialize_tracepoint ()
2648 tracepoint_chain
= 0;
2649 tracepoint_count
= 0;
2650 traceframe_number
= -1;
2651 tracepoint_number
= -1;
2653 set_internalvar (lookup_internalvar ("tpnum"),
2654 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2655 set_internalvar (lookup_internalvar ("trace_frame"),
2656 value_from_longest (builtin_type_int
, (LONGEST
) - 1));
2658 if (tracepoint_list
.list
== NULL
)
2660 tracepoint_list
.listsize
= 128;
2661 tracepoint_list
.list
= xmalloc
2662 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2664 if (tracepoint_list
.aexpr_list
== NULL
)
2666 tracepoint_list
.aexpr_listsize
= 128;
2667 tracepoint_list
.aexpr_list
= xmalloc
2668 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2671 if (stepping_list
.list
== NULL
)
2673 stepping_list
.listsize
= 128;
2674 stepping_list
.list
= xmalloc
2675 (stepping_list
.listsize
* sizeof (struct memrange
));
2678 if (stepping_list
.aexpr_list
== NULL
)
2680 stepping_list
.aexpr_listsize
= 128;
2681 stepping_list
.aexpr_list
= xmalloc
2682 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2685 add_info ("scope", scope_info
,
2686 "List the variables local to a scope");
2688 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2689 "Tracing of program execution without stopping the program.",
2692 add_info ("tracepoints", tracepoints_info
,
2693 "Status of tracepoints, or tracepoint number NUMBER.\n\
2694 Convenience variable \"$tpnum\" contains the number of the\n\
2695 last tracepoint set.");
2697 add_info_alias ("tp", "tracepoints", 1);
2699 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2700 "Save current tracepoint definitions as a script.\n\
2701 Use the 'source' command in another debug session to restore them.");
2703 add_com ("tdump", class_trace
, trace_dump_command
,
2704 "Print everything collected at the current tracepoint.");
2706 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2707 "Select a trace frame;\n\
2708 No argument means forward by one frame; '-' meand backward by one frame.",
2709 &tfindlist
, "tfind ", 1, &cmdlist
);
2711 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2712 "Select a trace frame whose PC is outside the given \
2713 range.\nUsage: tfind outside addr1, addr2",
2716 add_cmd ("range", class_trace
, trace_find_range_command
,
2717 "Select a trace frame whose PC is in the given range.\n\
2718 Usage: tfind range addr1,addr2",
2721 add_cmd ("line", class_trace
, trace_find_line_command
,
2722 "Select a trace frame by source line.\n\
2723 Argument can be a line number (with optional source file), \n\
2724 a function name, or '*' followed by an address.\n\
2725 Default argument is 'the next source line that was traced'.",
2728 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2729 "Select a trace frame by tracepoint number.\n\
2730 Default is the tracepoint for the current trace frame.",
2733 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2734 "Select a trace frame by PC.\n\
2735 Default is the current PC, or the PC of the current trace frame.",
2738 add_cmd ("end", class_trace
, trace_find_end_command
,
2739 "Synonym for 'none'.\n\
2740 De-select any trace frame and resume 'live' debugging.",
2743 add_cmd ("none", class_trace
, trace_find_none_command
,
2744 "De-select any trace frame and resume 'live' debugging.",
2747 add_cmd ("start", class_trace
, trace_find_start_command
,
2748 "Select the first trace frame in the trace buffer.",
2751 add_com ("tstatus", class_trace
, trace_status_command
,
2752 "Display the status of the current trace data collection.");
2754 add_com ("tstop", class_trace
, trace_stop_command
,
2755 "Stop trace data collection.");
2757 add_com ("tstart", class_trace
, trace_start_command
,
2758 "Start trace data collection.");
2760 add_com ("passcount", class_trace
, trace_pass_command
,
2761 "Set the passcount for a tracepoint.\n\
2762 The trace will end when the tracepoint has been passed 'count' times.\n\
2763 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2764 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2766 add_com ("end", class_trace
, end_actions_pseudocommand
,
2767 "Ends a list of commands or actions.\n\
2768 Several GDB commands allow you to enter a list of commands or actions.\n\
2769 Entering \"end\" on a line by itself is the normal way to terminate\n\
2771 Note: the \"end\" command cannot be used at the gdb prompt.");
2773 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2774 "Specify single-stepping behavior at a tracepoint.\n\
2775 Argument is number of instructions to trace in single-step mode\n\
2776 following the tracepoint. This command is normally followed by\n\
2777 one or more \"collect\" commands, to specify what to collect\n\
2778 while single-stepping.\n\n\
2779 Note: this command can only be used in a tracepoint \"actions\" list.");
2781 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2782 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2784 add_com ("collect", class_trace
, collect_pseudocommand
,
2785 "Specify one or more data items to be collected at a tracepoint.\n\
2786 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2787 collect all data (variables, registers) referenced by that expression.\n\
2788 Also accepts the following special arguments:\n\
2789 $regs -- all registers.\n\
2790 $args -- all function arguments.\n\
2791 $locals -- all variables local to the block/function scope.\n\
2792 Note: this command can only be used in a tracepoint \"actions\" list.");
2794 add_com ("actions", class_trace
, trace_actions_command
,
2795 "Specify the actions to be taken at a tracepoint.\n\
2796 Tracepoint actions may include collecting of specified data, \n\
2797 single-stepping, or enabling/disabling other tracepoints, \n\
2798 depending on target's capabilities.");
2800 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2801 "Delete specified tracepoints.\n\
2802 Arguments are tracepoint numbers, separated by spaces.\n\
2803 No argument means delete all tracepoints.",
2806 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2807 "Disable specified tracepoints.\n\
2808 Arguments are tracepoint numbers, separated by spaces.\n\
2809 No argument means disable all tracepoints.",
2812 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2813 "Enable specified tracepoints.\n\
2814 Arguments are tracepoint numbers, separated by spaces.\n\
2815 No argument means enable all tracepoints.",
2818 add_com ("trace", class_trace
, trace_command
,
2819 "Set a tracepoint at a specified line or function or address.\n\
2820 Argument may be a line number, function name, or '*' plus an address.\n\
2821 For a line number or function, trace at the start of its code.\n\
2822 If an address is specified, trace at that exact address.\n\n\
2823 Do \"help tracepoints\" for info on other tracepoint commands.");
2825 add_com_alias ("tp", "trace", class_alias
, 0);
2826 add_com_alias ("tr", "trace", class_alias
, 1);
2827 add_com_alias ("tra", "trace", class_alias
, 1);
2828 add_com_alias ("trac", "trace", class_alias
, 1);