1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "tracepoint.h"
25 #include "expression.h"
30 #include "gdb_string.h"
32 /* readline include files */
36 /* readline defines this. */
43 extern int info_verbose
;
44 extern void (*readline_begin_hook
) PARAMS ((char *, ...));
45 extern char * (*readline_hook
) PARAMS ((char *));
46 extern void (*readline_end_hook
) PARAMS ((void));
47 extern void x_command
PARAMS ((char *, int));
49 /* If this definition isn't overridden by the header files, assume
50 that isatty and fileno exist on this system. */
52 #define ISATTY(FP) (isatty (fileno (FP)))
58 This module defines the following debugger commands:
59 trace : set a tracepoint on a function, line, or address.
60 info trace : list all debugger-defined tracepoints.
61 delete trace : delete one or more tracepoints.
62 enable trace : enable one or more tracepoints.
63 disable trace : disable one or more tracepoints.
64 actions : specify actions to be taken at a tracepoint.
65 passcount : specify a pass count for a tracepoint.
66 tstart : start a trace experiment.
67 tstop : stop a trace experiment.
68 tstatus : query the status of a trace experiment.
69 tfind : find a trace frame in the trace buffer.
70 tdump : print everything collected at the current tracepoint.
71 save-tracepoints : write tracepoint setup into a file.
73 This module defines the following user-visible debugger variables:
74 $trace_frame : sequence number of trace frame currently being debugged.
75 $trace_line : source line of trace frame currently being debugged.
76 $trace_file : source file of trace frame currently being debugged.
77 $tracepoint : tracepoint number of trace frame currently being debugged.
81 /* ======= Important global variables: ======= */
83 /* Chain of all tracepoints defined. */
84 struct tracepoint
*tracepoint_chain
;
86 /* Number of last tracepoint made. */
87 static int tracepoint_count
;
89 /* Number of last traceframe collected. */
90 static int traceframe_number
;
92 /* Tracepoint for last traceframe collected. */
93 static int tracepoint_number
;
95 /* Symbol for function for last traceframe collected */
96 static struct symbol
*traceframe_fun
;
98 /* Symtab and line for last traceframe collected */
99 static struct symtab_and_line traceframe_sal
;
101 /* Tracing command lists */
102 static struct cmd_list_element
*tfindlist
;
104 /* ======= Important command functions: ======= */
105 static void trace_command
PARAMS ((char *, int));
106 static void tracepoints_info
PARAMS ((char *, int));
107 static void delete_trace_command
PARAMS ((char *, int));
108 static void enable_trace_command
PARAMS ((char *, int));
109 static void disable_trace_command
PARAMS ((char *, int));
110 static void trace_pass_command
PARAMS ((char *, int));
111 static void trace_actions_command
PARAMS ((char *, int));
112 static void trace_start_command
PARAMS ((char *, int));
113 static void trace_stop_command
PARAMS ((char *, int));
114 static void trace_status_command
PARAMS ((char *, int));
115 static void trace_find_command
PARAMS ((char *, int));
116 static void trace_find_pc_command
PARAMS ((char *, int));
117 static void trace_find_tracepoint_command
PARAMS ((char *, int));
118 static void trace_find_line_command
PARAMS ((char *, int));
119 static void trace_find_range_command
PARAMS ((char *, int));
120 static void trace_find_outside_command
PARAMS ((char *, int));
121 static void tracepoint_save_command
PARAMS ((char *, int));
122 static void trace_dump_command
PARAMS ((char *, int));
125 /* Utility: returns true if "target remote" */
129 if (current_target
.to_shortname
&&
130 strcmp (current_target
.to_shortname
, "remote") == 0)
136 /* Utility: generate error from an incoming stub packet. */
142 return; /* not an error msg */
145 case '1': /* malformed packet error */
146 if (*++buf
== '0') /* general case: */
147 error ("tracepoint.c: error in outgoing packet.");
149 error ("tracepoint.c: error in outgoing packet at field #%d.",
150 strtol (buf
, NULL
, 16));
152 error ("trace API error 0x%s.", ++buf
);
154 error ("Target returns error code '%s'.", buf
);
158 /* Utility: wait for reply from stub, while accepting "O" packets */
160 remote_get_noisy_reply (buf
)
163 do /* loop on reply from remote stub */
167 error ("Target does not support this command.");
168 else if (buf
[0] == 'E')
170 else if (buf
[0] == 'O' &&
172 remote_console_output (buf
+ 1); /* 'O' message from stub */
174 return buf
; /* here's the actual reply */
178 /* Set tracepoint count to NUM. */
180 set_tracepoint_count (num
)
183 tracepoint_count
= num
;
184 set_internalvar (lookup_internalvar ("tpnum"),
185 value_from_longest (builtin_type_int
, (LONGEST
) num
));
188 /* Set traceframe number to NUM. */
190 set_traceframe_num (num
)
193 traceframe_number
= num
;
194 set_internalvar (lookup_internalvar ("trace_frame"),
195 value_from_longest (builtin_type_int
, (LONGEST
) num
));
198 /* Set tracepoint number to NUM. */
200 set_tracepoint_num (num
)
203 tracepoint_number
= num
;
204 set_internalvar (lookup_internalvar ("tracepoint"),
205 value_from_longest (builtin_type_int
, (LONGEST
) num
));
208 /* Set externally visible debug variables for querying/printing
209 the traceframe context (line, function, file) */
212 set_traceframe_context (trace_pc
)
215 static struct type
*func_string
, *file_string
;
216 static struct type
*func_range
, *file_range
;
217 static value_ptr func_val
, file_val
;
218 static struct type
*charstar
;
221 if (charstar
== (struct type
*) NULL
)
222 charstar
= lookup_pointer_type (builtin_type_char
);
224 if (trace_pc
== -1) /* cease debugging any trace buffers */
227 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
228 traceframe_sal
.symtab
= NULL
;
229 set_internalvar (lookup_internalvar ("trace_func"),
230 value_from_longest (charstar
, (LONGEST
) 0));
231 set_internalvar (lookup_internalvar ("trace_file"),
232 value_from_longest (charstar
, (LONGEST
) 0));
233 set_internalvar (lookup_internalvar ("trace_line"),
234 value_from_longest (builtin_type_int
, (LONGEST
) -1));
238 /* save as globals for internal use */
239 traceframe_sal
= find_pc_line (trace_pc
, 0);
240 traceframe_fun
= find_pc_function (trace_pc
);
242 /* save linenumber as "$trace_line", a debugger variable visible to users */
243 set_internalvar (lookup_internalvar ("trace_line"),
244 value_from_longest (builtin_type_int
,
245 (LONGEST
) traceframe_sal
.line
));
247 /* save func name as "$trace_func", a debugger variable visible to users */
248 if (traceframe_fun
== NULL
||
249 SYMBOL_NAME (traceframe_fun
) == NULL
)
250 set_internalvar (lookup_internalvar ("trace_func"),
251 value_from_longest (charstar
, (LONGEST
) 0));
254 len
= strlen (SYMBOL_NAME (traceframe_fun
));
255 func_range
= create_range_type (func_range
,
256 builtin_type_int
, 0, len
- 1);
257 func_string
= create_array_type (func_string
,
258 builtin_type_char
, func_range
);
259 func_val
= allocate_value (func_string
);
260 VALUE_TYPE (func_val
) = func_string
;
261 memcpy (VALUE_CONTENTS_RAW (func_val
),
262 SYMBOL_NAME (traceframe_fun
),
264 func_val
->modifiable
= 0;
265 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
268 /* save file name as "$trace_file", a debugger variable visible to users */
269 if (traceframe_sal
.symtab
== NULL
||
270 traceframe_sal
.symtab
->filename
== NULL
)
271 set_internalvar (lookup_internalvar ("trace_file"),
272 value_from_longest (charstar
, (LONGEST
) 0));
275 len
= strlen (traceframe_sal
.symtab
->filename
);
276 file_range
= create_range_type (file_range
,
277 builtin_type_int
, 0, len
- 1);
278 file_string
= create_array_type (file_string
,
279 builtin_type_char
, file_range
);
280 file_val
= allocate_value (file_string
);
281 VALUE_TYPE (file_val
) = file_string
;
282 memcpy (VALUE_CONTENTS_RAW (file_val
),
283 traceframe_sal
.symtab
->filename
,
285 file_val
->modifiable
= 0;
286 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
290 /* Low level routine to set a tracepoint.
291 Returns the tracepoint object so caller can set other things.
292 Does not set the tracepoint number!
293 Does not print anything.
295 ==> This routine should not be called if there is a chance of later
296 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
297 your arguments BEFORE calling this routine! */
299 static struct tracepoint
*
300 set_raw_tracepoint (sal
)
301 struct symtab_and_line sal
;
303 register struct tracepoint
*t
, *tc
;
304 struct cleanup
*old_chain
;
306 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
307 old_chain
= make_cleanup (free
, t
);
308 memset (t
, 0, sizeof (*t
));
310 if (sal
.symtab
== NULL
)
311 t
->source_file
= NULL
;
316 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) +
317 strlen (sal
.symtab
->dirname
) + 2);
319 strcpy (t
->source_file
, sal
.symtab
->dirname
);
323 if (*(--p
) != '/') /* Will this work on Windows? */
324 strcat (t
->source_file
, "/");
325 strcat (t
->source_file
, sal
.symtab
->filename
);
328 t
->language
= current_language
->la_language
;
329 t
->input_radix
= input_radix
;
330 t
->line_number
= sal
.line
;
331 t
->enabled
= enabled
;
336 /* Add this tracepoint to the end of the chain
337 so that a list of tracepoints will come out in order
338 of increasing numbers. */
340 tc
= tracepoint_chain
;
342 tracepoint_chain
= t
;
349 discard_cleanups (old_chain
);
353 /* Set a tracepoint according to ARG (function, linenum or *address) */
355 trace_command (arg
, from_tty
)
359 char **canonical
= (char **)NULL
;
360 struct symtabs_and_lines sals
;
361 struct symtab_and_line sal
;
362 struct tracepoint
*t
;
363 char *addr_start
= 0, *addr_end
= 0;
367 error ("trace command requires an argument");
369 if (from_tty
&& info_verbose
)
370 printf_filtered ("TRACE %s\n", arg
);
378 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
381 return; /* ??? Presumably decode_line_1 has already warned? */
383 /* Resolve all line numbers to PC's */
384 for (i
= 0; i
< sals
.nelts
; i
++)
385 resolve_sal_pc (&sals
.sals
[i
]);
387 /* Now set all the tracepoints. */
388 for (i
= 0; i
< sals
.nelts
; i
++)
392 t
= set_raw_tracepoint (sal
);
393 set_tracepoint_count (tracepoint_count
+ 1);
394 t
->number
= tracepoint_count
;
396 /* If a canonical line spec is needed use that instead of the
398 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
399 t
->addr_string
= canonical
[i
];
401 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
403 /* Let the UI know of any additions */
404 if (create_tracepoint_hook
)
405 create_tracepoint_hook (t
);
410 printf_filtered ("Multiple tracepoints were set.\n");
411 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
415 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
418 tracepoints_info (tpnum_exp
, from_tty
)
422 struct tracepoint
*t
;
423 struct action_line
*action
;
424 int found_a_tracepoint
= 0;
425 char wrap_indent
[80];
429 char *i1
= "\t", *i2
= "\t ";
430 char *indent
, *actionline
;;
434 tpnum
= parse_and_eval_address (tpnum_exp
);
437 if (tpnum
== -1 || tpnum
== t
->number
)
439 extern int addressprint
; /* print machine addresses? */
441 if (!found_a_tracepoint
++)
443 printf_filtered ("Num Enb ");
445 printf_filtered ("Address ");
446 printf_filtered ("PassC StepC What\n");
448 strcpy (wrap_indent
, " ");
450 strcat (wrap_indent
, " ");
452 printf_filtered ("%-3d %-3s ", t
->number
,
453 t
->enabled
== enabled
? "y" : "n");
455 printf_filtered ("%s ",
456 local_hex_string_custom ((unsigned long) t
->address
,
458 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
462 sym
= find_pc_function (t
->address
);
465 fputs_filtered ("in ", gdb_stdout
);
466 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
467 wrap_here (wrap_indent
);
468 fputs_filtered (" at ", gdb_stdout
);
470 fputs_filtered (t
->source_file
, gdb_stdout
);
471 printf_filtered (":%d", t
->line_number
);
474 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
476 printf_filtered ("\n");
479 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
481 for (action
= t
->actions
; action
; action
= action
->next
)
484 actionline
= action
->action
;
485 while (isspace(*actionline
))
488 printf_filtered ("%s%s\n", indent
, actionline
);
489 if (0 == strncasecmp (actionline
, "while-stepping", 14))
491 else if (0 == strncasecmp (actionline
, "end", 3))
494 printf_filtered ("\t%s\n", action
->action
);
499 if (!found_a_tracepoint
)
502 printf_filtered ("No tracepoints.\n");
504 printf_filtered ("No tracepoint number %d.\n", tpnum
);
508 /* Optimization: the code to parse an enable, disable, or delete TP command
509 is virtually identical except for whether it performs an enable, disable,
510 or delete. Therefore I've combined them into one function with an opcode.
512 enum tracepoint_opcode
519 /* This function implements enable, disable and delete. */
521 tracepoint_operation (t
, from_tty
, opcode
)
522 struct tracepoint
*t
;
524 enum tracepoint_opcode opcode
;
526 struct tracepoint
*t2
;
527 struct action_line
*action
, *next
;
531 t
->enabled
= enabled
;
534 t
->enabled
= disabled
;
537 if (tracepoint_chain
== t
)
538 tracepoint_chain
= t
->next
;
547 /* Let the UI know of any deletions */
548 if (delete_tracepoint_hook
)
549 delete_tracepoint_hook (t
);
552 free (t
->addr_string
);
554 free (t
->source_file
);
555 for (action
= t
->actions
; action
; action
= next
)
559 free (action
->action
);
567 /* Utility: parse a tracepoint number and look it up in the list. */
569 get_tracepoint_by_number (arg
)
572 struct tracepoint
*t
;
578 error ("Bad tracepoint argument");
580 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
581 tpnum
= tracepoint_count
;
582 else if (**arg
== '$') /* handle convenience variable */
584 /* Make a copy of the name, so we can null-terminate it
585 to pass to lookup_internalvar(). */
587 while (isalnum(*end
) || *end
== '_')
589 copy
= (char *) alloca (end
- *arg
);
590 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
591 copy
[end
- *arg
- 1] = '\0';
594 val
= value_of_internalvar (lookup_internalvar (copy
));
595 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
596 error ("Convenience variable must have integral type.");
597 tpnum
= (int) value_as_long (val
);
599 else /* handle tracepoint number */
601 tpnum
= strtol (*arg
, arg
, 10);
604 if (t
->number
== tpnum
)
608 warning ("No tracepoint number %d.\n", tpnum
);
612 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
614 map_args_over_tracepoints (args
, from_tty
, opcode
)
617 enum tracepoint_opcode opcode
;
619 struct tracepoint
*t
;
623 if (args
== 0 || *args
== 0) /* do them all */
625 tracepoint_operation (t
, from_tty
, opcode
);
629 if (t
= get_tracepoint_by_number (&args
))
630 tracepoint_operation (t
, from_tty
, opcode
);
631 while (*args
== ' ' || *args
== '\t')
636 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
638 enable_trace_command (args
, from_tty
)
643 map_args_over_tracepoints (args
, from_tty
, enable
);
646 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
648 disable_trace_command (args
, from_tty
)
653 map_args_over_tracepoints (args
, from_tty
, disable
);
656 /* Remove a tracepoint (or all if no argument) */
658 delete_trace_command (args
, from_tty
)
664 if (!query ("Delete all tracepoints? "))
667 map_args_over_tracepoints (args
, from_tty
, delete);
670 /* Set passcount for tracepoint.
672 First command argument is passcount, second is tracepoint number.
673 If tracepoint number omitted, apply to most recently defined.
674 Also accepts special argument "all". */
677 trace_pass_command (args
, from_tty
)
681 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
684 if (args
== 0 || *args
== 0)
685 error ("PASS command requires an argument (count + optional TP num)");
687 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
689 while (*args
&& isspace (*args
))
692 if (*args
&& strncasecmp (args
, "all", 3) == 0)
693 args
+= 3; /* skip special argument "all" */
695 t1
= get_tracepoint_by_number (&args
);
698 return; /* error, bad tracepoint number */
701 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
703 t2
->pass_count
= count
;
705 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
710 /* ACTIONS functions: */
712 /* Prototypes for action-parsing utility commands */
713 static void read_actions
PARAMS((struct tracepoint
*));
714 static void free_actions
PARAMS((struct tracepoint
*));
715 static char *parse_and_eval_memrange
PARAMS ((char *,
721 /* The three functions:
722 collect_pseudocommand,
723 while_stepping_pseudocommand, and
724 end_actions_pseudocommand
725 are placeholders for "commands" that are actually ONLY to be used
726 within a tracepoint action list. If the actual function is ever called,
727 it means that somebody issued the "command" at the top level,
728 which is always an error. */
731 end_actions_pseudocommand (args
, from_tty
)
735 error ("This command cannot be used at the top level.");
739 while_stepping_pseudocommand (args
, from_tty
)
743 error ("This command can only be used in a tracepoint actions list.");
747 collect_pseudocommand (args
, from_tty
)
751 error ("This command can only be used in a tracepoint actions list.");
754 /* Enter a list of actions for a tracepoint. */
756 trace_actions_command (args
, from_tty
)
760 struct tracepoint
*t
;
763 char *end_msg
= "End with a line saying just \"end\".";
765 if (t
= get_tracepoint_by_number (&args
))
767 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
770 if (readline_begin_hook
)
771 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
772 else if (from_tty
&& input_from_terminal_p ())
773 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
778 if (readline_end_hook
)
779 (*readline_end_hook
) ();
781 /* tracepoints_changed () */
783 /* else error, just return; */
794 static enum actionline_type validate_actionline
PARAMS((char *,
795 struct tracepoint
*));
797 /* worker function */
800 struct tracepoint
*t
;
803 char *prompt1
= "> ", *prompt2
= " > ";
804 char *prompt
= prompt1
;
805 enum actionline_type linetype
;
806 extern FILE *instream
;
807 struct action_line
*next
= NULL
, *temp
;
808 struct cleanup
*old_chain
;
810 /* Control-C quits instantly if typed while in this loop
811 since it should not wait until the user types a newline. */
815 signal (STOP_SIGNAL
, stop_sig
);
817 old_chain
= make_cleanup (free_actions
, (void *) t
);
820 /* Make sure that all output has been output. Some machines may let
821 you get away with leaving out some of the gdb_flush, but not all. */
823 gdb_flush (gdb_stdout
);
824 gdb_flush (gdb_stderr
);
826 if (readline_hook
&& instream
== NULL
)
827 line
= (*readline_hook
) (prompt
);
828 else if (instream
== stdin
&& ISATTY (instream
))
829 line
= readline (prompt
);
831 line
= gdb_readline (0);
833 linetype
= validate_actionline (line
, t
);
834 if (linetype
== BADLINE
)
835 continue; /* already warned -- collect another line */
837 temp
= xmalloc (sizeof (struct action_line
));
841 if (next
== NULL
) /* first action for this tracepoint? */
842 t
->actions
= next
= temp
;
849 if (linetype
== STEPPING
) /* begin "while-stepping" */
850 if (prompt
== prompt2
)
852 warning ("Already processing 'while-stepping'");
856 prompt
= prompt2
; /* change prompt for stepping actions */
857 else if (linetype
== END
)
858 if (prompt
== prompt2
)
859 prompt
= prompt1
; /* end of single-stepping actions */
861 break; /* end of actions */
865 signal (STOP_SIGNAL
, SIG_DFL
);
868 discard_cleanups (old_chain
);
871 /* worker function */
872 static enum actionline_type
873 validate_actionline (line
, t
)
875 struct tracepoint
*t
;
877 struct cmd_list_element
*c
;
878 struct expression
*exp
;
879 value_ptr temp
, temp2
;
882 for (p
= line
; isspace (*p
); )
885 /* symbol lookup etc. */
886 if (*p
== '\0') /* empty line: just prompt for another line. */
889 if (*p
== '#') /* comment line */
892 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
895 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
899 if (c
->function
.cfunc
== collect_pseudocommand
)
901 do { /* repeat over a comma-separated list */
905 if (*p
== '$') /* look for special pseudo-symbols */
908 bfd_signed_vma offset
;
910 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
911 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
912 (0 == strncasecmp ("loc", p
+ 1, 3)))
915 else if (p
[1] == '(') /* literal memrange */
916 p
= parse_and_eval_memrange (p
, t
->address
,
917 &typecode
, &offset
, &size
);
921 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
923 if (exp
->elts
[0].opcode
!= OP_VAR_VALUE
&&
924 /*exp->elts[0].opcode != OP_LONG && */
925 /*exp->elts[0].opcode != UNOP_CAST && */
926 exp
->elts
[0].opcode
!= OP_REGISTER
)
928 warning ("collect requires a variable or register name.\n");
931 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
932 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
934 warning ("%s is constant (value %d): will not be collected.",
935 SYMBOL_NAME (exp
->elts
[2].symbol
),
936 SYMBOL_VALUE (exp
->elts
[2].symbol
));
939 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
941 warning ("%s is optimized away and cannot be collected.",
942 SYMBOL_NAME (exp
->elts
[2].symbol
));
946 } while (p
&& *p
++ == ',');
949 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
951 char *steparg
; /* in case warning is necessary */
959 t
->step_count
= strtol (p
, &p
, 0);
960 if (t
->step_count
== 0)
962 warning ("'%s' evaluates to zero -- command ignored.");
970 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
974 warning ("'%s' is not a supported tracepoint action.", line
);
979 /* worker function */
982 struct tracepoint
*t
;
984 struct action_line
*line
, *next
;
986 for (line
= t
->actions
; line
; line
= next
)
995 int type
; /* 0 for absolute memory range, else basereg number */
996 bfd_signed_vma start
;
1000 struct collection_list
{
1001 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1004 struct memrange
*list
;
1005 } tracepoint_list
, stepping_list
;
1007 /* MEMRANGE functions: */
1009 /* parse a memrange spec from command input */
1011 parse_and_eval_memrange (arg
, addr
, typecode
, offset
, size
)
1014 long *typecode
, *size
;
1015 bfd_signed_vma
*offset
;
1018 struct expression
*exp
;
1020 if (*arg
++ != '$' || *arg
++ != '(')
1021 error ("Internal: bad argument to validate_memrange: %s", start
);
1023 if (*arg
== '$') /* register for relative memrange? */
1025 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1026 if (exp
->elts
[0].opcode
!= OP_REGISTER
)
1027 error ("Bad register operand for memrange: %s", start
);
1029 error ("missing comma for memrange: %s", start
);
1030 *typecode
= exp
->elts
[1].longconst
;
1036 /* While attractive, this fails for a number of reasons:
1037 1) parse_and_eval_address does not deal with trailing commas,
1039 2) There is no safeguard against the user trying to use
1040 an out-of-scope variable in an address expression (for instance).
1041 2.5) If you are going to allow semi-arbitrary expressions, you
1042 would need to explain which expressions are allowed, and
1043 which are not (which would provoke endless questions).
1044 3) If you are going to allow semi-arbitrary expressions in the
1045 offset and size fields, then the leading "$" of a register
1046 name no longer disambiguates the typecode field.
1049 *offset
= parse_and_eval_address (arg
);
1050 if ((arg
= strchr (arg
, ',')) == NULL
)
1051 error ("missing comma for memrange: %s", start
);
1055 *size
= parse_and_eval_address (arg
);
1056 if ((arg
= strchr (arg
, ')')) == NULL
)
1057 error ("missing close-parenthesis for memrange: %s", start
);
1062 /* This, on the other hand, doesn't work because "-1" is an
1063 expression, not an OP_LONG! Fall back to using strtol for now. */
1065 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1066 if (exp
->elts
[0].opcode
!= OP_LONG
)
1067 error ("Bad offset operand for memrange: %s", start
);
1068 *offset
= exp
->elts
[2].longconst
;
1071 error ("missing comma for memrange: %s", start
);
1073 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1074 if (exp
->elts
[0].opcode
!= OP_LONG
)
1075 error ("Bad size operand for memrange: %s", start
);
1076 *size
= exp
->elts
[2].longconst
;
1079 error ("invalid size in memrange: %s", start
);
1082 error ("missing close-parenthesis for memrange: %s", start
);
1084 *offset
= strtol (arg
, &arg
, 0);
1086 error ("missing comma for memrange: %s", start
);
1087 *size
= strtol (arg
, &arg
, 0);
1089 error ("invalid size in memrange: %s", start
);
1091 error ("missing close-parenthesis for memrange: %s", start
);
1095 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1096 *typecode
, *offset
, *size
);
1101 /* compare memranges for qsort */
1104 struct memrange
*a
, *b
;
1106 if (a
->type
< b
->type
) return -1;
1107 if (a
->type
> b
->type
) return 1;
1110 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1111 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1115 if (a
->start
< b
->start
) return -1;
1116 if (a
->start
> b
->start
) return 1;
1121 /* Sort the memrange list using qsort, and merge adjacent memranges */
1123 memrange_sortmerge (memranges
)
1124 struct collection_list
*memranges
;
1128 qsort (memranges
->list
, memranges
->next_memrange
,
1129 sizeof (struct memrange
), memrange_cmp
);
1130 if (memranges
->next_memrange
> 0)
1132 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1134 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1135 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1136 MAX_REGISTER_VIRTUAL_SIZE
)
1138 /* memrange b starts before memrange a ends; merge them. */
1139 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1140 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1141 continue; /* next b, same a */
1145 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1146 sizeof (struct memrange
));
1148 memranges
->next_memrange
= a
+ 1;
1152 /* Add a register to a collection list */
1154 add_register (collection
, regno
)
1155 struct collection_list
*collection
;
1156 unsigned long regno
;
1159 printf_filtered ("collect register %d\n", regno
);
1160 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1161 error ("Internal: register number %d too large for tracepoint",
1163 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1166 /* Add a memrange to a collection list */
1168 add_memrange (memranges
, type
, base
, len
)
1169 struct collection_list
*memranges
;
1171 bfd_signed_vma base
;
1175 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1176 /* type: 0 == memory, n == basereg */
1177 memranges
->list
[memranges
->next_memrange
].type
= type
;
1178 /* base: addr if memory, offset if reg relative. */
1179 memranges
->list
[memranges
->next_memrange
].start
= base
;
1180 /* len: we actually save end (base + len) for convenience */
1181 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1182 memranges
->next_memrange
++;
1183 if (memranges
->next_memrange
>= memranges
->listsize
)
1185 memranges
->listsize
*= 2;
1186 memranges
->list
= xrealloc (memranges
->list
,
1187 memranges
->listsize
);
1190 if (type
!= 0) /* better collect the base register! */
1191 add_register (memranges
, type
);
1194 /* Add a symbol to a collection list */
1196 collect_symbol (collect
, sym
)
1197 struct collection_list
*collect
;
1202 bfd_signed_vma offset
;
1204 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1205 switch (SYMBOL_CLASS (sym
)) {
1207 printf_filtered ("%s: don't know symbol class %d\n",
1208 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1211 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1212 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1215 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1217 printf_filtered ("LOC_STATIC %s: collect %d bytes "
1219 SYMBOL_NAME (sym
), len
, offset
);
1220 add_memrange (collect
, 0, offset
, len
); /* 0 == memory */
1224 reg
= SYMBOL_VALUE (sym
);
1226 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1227 add_register (collect
, reg
);
1231 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1232 printf_filtered (" (will not collect %s)\n",
1235 case LOC_REGPARM_ADDR
:
1236 reg
= SYMBOL_VALUE (sym
);
1240 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1241 SYMBOL_NAME (sym
), len
, offset
, reg
);
1243 add_memrange (collect
, reg
, offset
, len
);
1247 offset
= SYMBOL_VALUE (sym
);
1251 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1252 SYMBOL_NAME (sym
), len
, offset
, reg
);
1254 add_memrange (collect
, reg
, offset
, len
);
1257 case LOC_BASEREG_ARG
:
1258 reg
= SYMBOL_BASEREG (sym
);
1259 offset
= SYMBOL_VALUE (sym
);
1262 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1263 SYMBOL_NAME (sym
), len
, offset
, reg
);
1265 add_memrange (collect
, reg
, offset
, len
);
1267 case LOC_UNRESOLVED
:
1268 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1270 case LOC_OPTIMIZED_OUT
:
1271 printf_filtered ("%s has been optimized out of existance.\n",
1277 /* Add all locals (or args) symbols to collection list */
1279 add_local_symbols (collect
, pc
, type
)
1280 struct collection_list
*collect
;
1285 struct block
*block
;
1286 int i
, nsyms
, count
= 0;
1288 block
= block_for_pc (pc
);
1291 nsyms
= BLOCK_NSYMS (block
);
1292 for (i
= 0; i
< nsyms
; i
++)
1294 sym
= BLOCK_SYM (block
, i
);
1295 switch (SYMBOL_CLASS (sym
)) {
1300 if (type
== 'L') /* collecting Locals */
1303 collect_symbol (collect
, sym
);
1310 case LOC_REGPARM_ADDR
:
1311 case LOC_BASEREG_ARG
:
1312 if (type
== 'A') /* collecting Arguments */
1315 collect_symbol (collect
, sym
);
1319 if (BLOCK_FUNCTION (block
))
1322 block
= BLOCK_SUPERBLOCK (block
);
1325 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1328 /* worker function */
1330 clear_collection_list (list
)
1331 struct collection_list
*list
;
1333 list
->next_memrange
= 0;
1334 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1337 /* reduce a collection list to string form (for gdb protocol) */
1339 stringify_collection_list (list
, string
)
1340 struct collection_list
*list
;
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 printf_filtered ("%02X", list
->regs_mask
[i
]);
1358 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1363 printf_filtered ("\n");
1364 if (list
->next_memrange
> 0 && info_verbose
)
1365 printf_filtered ("Collecting memranges: \n");
1366 for (i
= 0; i
< list
->next_memrange
; i
++)
1369 printf_filtered ("(%d, 0x%x, %d)\n",
1371 list
->list
[i
].start
,
1372 list
->list
[i
].end
- list
->list
[i
].start
);
1373 sprintf (end
, "M%X,%X,%X",
1375 list
->list
[i
].start
,
1376 list
->list
[i
].end
- list
->list
[i
].start
);
1377 end
+= strlen (end
);
1385 /* render all actions into gdb protocol */
1387 encode_actions (t
, tdp_actions
, step_count
, stepping_actions
)
1388 struct tracepoint
*t
;
1390 unsigned long *step_count
;
1391 char **stepping_actions
;
1393 static char tdp_buff
[2048], step_buff
[2048];
1395 struct expression
*exp
;
1396 struct action_line
*action
;
1397 bfd_signed_vma offset
;
1399 struct collection_list
*collect
;
1400 struct cmd_list_element
*cmd
;
1402 clear_collection_list (&tracepoint_list
);
1403 clear_collection_list (&stepping_list
);
1404 collect
= &tracepoint_list
;
1406 *tdp_actions
= NULL
;
1407 *stepping_actions
= NULL
;
1409 for (action
= t
->actions
; action
; action
= action
->next
)
1411 action_exp
= action
->action
;
1412 while (isspace (*action_exp
))
1415 if (*action_exp
== '#') /* comment line */
1418 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1420 error ("Bad action list item: %s", action_exp
);
1422 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1424 do { /* repeat over a comma-separated list */
1425 while (isspace (*action_exp
))
1428 if (0 == strncasecmp ("$reg", action_exp
, 4))
1430 for (i
= 0; i
< NUM_REGS
; i
++)
1431 add_register (collect
, i
);
1432 action_exp
= strchr (action_exp
, ','); /* more? */
1434 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1436 add_local_symbols (collect
, t
->address
, 'A');
1437 action_exp
= strchr (action_exp
, ','); /* more? */
1439 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1441 add_local_symbols (collect
, t
->address
, 'L');
1442 action_exp
= strchr (action_exp
, ','); /* more? */
1444 else if (action_exp
[0] == '$' &&
1445 action_exp
[1] == '(') /* literal memrange */
1447 long typecode
, size
;
1448 bfd_signed_vma offset
;
1450 action_exp
= parse_and_eval_memrange (action_exp
,
1455 add_memrange (collect
, typecode
, offset
, size
);
1459 unsigned long addr
, len
;
1461 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1462 switch (exp
->elts
[0].opcode
) {
1464 i
= exp
->elts
[1].longconst
;
1466 printf_filtered ("OP_REGISTER: ");
1467 add_register (collect
, i
);
1470 collect_symbol (collect
, exp
->elts
[2].symbol
);
1474 addr
= exp
->elts
[2].longconst
;
1475 if (*action_exp
== ':')
1477 exp
= parse_exp_1 (&action_exp
,
1478 block_for_pc (t
->address
),
1480 if (exp
->elts
[0].opcode
== OP_LONG
)
1481 len
= exp
->elts
[2].longconst
;
1483 error ("length field requires a literal long const");
1488 add_memrange (collect
, 0, addr
, len
);
1493 } while (action_exp
&& *action_exp
++ == ',');
1495 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1497 collect
= &stepping_list
;
1499 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1501 if (collect
== &stepping_list
) /* end stepping actions */
1502 collect
= &tracepoint_list
;
1504 break; /* end tracepoint actions */
1507 memrange_sortmerge (&tracepoint_list
);
1508 memrange_sortmerge (&stepping_list
);
1510 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1511 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1514 static char target_buf
[2048];
1518 Tell target to lear any previous trace experiment.
1519 Walk the list of tracepoints, and send them (and their actions)
1520 to the target. If no errors,
1521 Tell target to start a new trace experiment. */
1524 trace_start_command (args
, from_tty
)
1527 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1528 struct tracepoint
*t
;
1531 char *stepping_actions
;
1532 unsigned long step_count
;
1534 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1536 if (target_is_remote ())
1539 remote_get_noisy_reply (target_buf
);
1540 if (strcmp (target_buf
, "OK"))
1541 error ("Target does not support this command.");
1545 int ss_count
; /* if actions include singlestepping */
1546 int disable_mask
; /* ??? */
1547 int enable_mask
; /* ??? */
1549 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1550 t
->enabled
== enabled
? 'E' : 'D',
1551 t
->step_count
, t
->pass_count
);
1554 encode_actions (t
, &tdp_actions
, &step_count
, &stepping_actions
);
1555 /* do_single_steps (t); */
1558 if (strlen (buf
) + strlen (tdp_actions
) >= sizeof (buf
))
1559 error ("Actions for tracepoint %d too complex; "
1560 "please simplify.", t
->number
);
1561 strcat (buf
, tdp_actions
);
1563 if (stepping_actions
)
1566 if (strlen (buf
) + strlen (stepping_actions
) >= sizeof (buf
))
1567 error ("Actions for tracepoint %d too complex; "
1568 "please simplify.", t
->number
);
1569 strcat (buf
, stepping_actions
);
1573 remote_get_noisy_reply (target_buf
);
1574 if (strcmp (target_buf
, "OK"))
1575 error ("Target does not support tracepoints.");
1578 remote_get_noisy_reply (target_buf
);
1579 if (strcmp (target_buf
, "OK"))
1580 error ("Bogus reply from target: %s", target_buf
);
1581 set_traceframe_num (-1); /* all old traceframes invalidated */
1582 set_tracepoint_num (-1);
1583 set_traceframe_context(-1);
1586 printf_filtered ("Trace can only be run on remote targets.\n");
1591 trace_stop_command (args
, from_tty
)
1594 { /* STUB_COMM IS_IMPLEMENTED */
1595 if (target_is_remote ())
1598 remote_get_noisy_reply (target_buf
);
1599 if (strcmp (target_buf
, "OK"))
1600 error ("Bogus reply from target: %s", target_buf
);
1603 error ("Trace can only be run on remote targets.");
1606 /* tstatus command */
1608 trace_status_command (args
, from_tty
)
1611 { /* STUB_COMM IS_IMPLEMENTED */
1612 if (target_is_remote ())
1614 putpkt ("qTStatus");
1615 remote_get_noisy_reply (target_buf
);
1616 if (strcmp (target_buf
, "OK"))
1617 error ("Bogus reply from target: %s", target_buf
);
1620 error ("Trace can only be run on remote targets.");
1623 /* Worker function for the various flavors of the tfind command */
1625 finish_tfind_command (msg
, from_tty
)
1629 int target_frameno
= -1, target_tracept
= -1;
1630 CORE_ADDR old_frame_addr
;
1631 struct symbol
*old_func
;
1634 old_frame_addr
= FRAME_FP (get_current_frame ());
1635 old_func
= find_pc_function (read_pc ());
1638 reply
= remote_get_noisy_reply (msg
);
1640 while (reply
&& *reply
)
1643 if ((target_frameno
= strtol (++reply
, &reply
, 16)) == -1)
1645 /* A request for a non-existant trace frame has failed.
1646 Our response will be different, depending on FROM_TTY:
1648 If FROM_TTY is true, meaning that this command was
1649 typed interactively by the user, then give an error
1650 and DO NOT change the state of traceframe_number etc.
1652 However if FROM_TTY is false, meaning that we're either
1653 in a script, a loop, or a user-defined command, then
1654 DON'T give an error, but DO change the state of
1655 traceframe_number etc. to invalid.
1657 The rationalle is that if you typed the command, you
1658 might just have committed a typo or something, and you'd
1659 like to NOT lose your current debugging state. However
1660 if you're in a user-defined command or especially in a
1661 loop, then you need a way to detect that the command
1662 failed WITHOUT aborting. This allows you to write
1663 scripts that search thru the trace buffer until the end,
1664 and then continue on to do something else. */
1667 error ("Target failed to find requested trace frame.");
1671 printf_filtered ("End of trace buffer.\n");
1672 /* The following will not recurse, since it's special-cased */
1673 trace_find_command ("-1", from_tty
);
1674 reply
= NULL
; /* break out of loop,
1675 (avoid recursive nonsense) */
1680 if ((target_tracept
= strtol (++reply
, &reply
, 16)) == -1)
1681 error ("Target failed to find requested trace frame.");
1683 case 'O': /* "OK"? */
1684 if (reply
[1] == 'K' && reply
[2] == '\0')
1687 error ("Bogus reply from target: %s", reply
);
1690 error ("Bogus reply from target: %s", reply
);
1693 flush_cached_frames ();
1694 registers_changed ();
1695 select_frame (get_current_frame (), 0);
1696 set_traceframe_num (target_frameno
);
1697 set_tracepoint_num (target_tracept
);
1698 if (target_frameno
== -1)
1699 set_traceframe_context (-1);
1701 set_traceframe_context (read_pc ());
1707 if (old_frame_addr
== FRAME_FP (get_current_frame ()) &&
1708 old_func
== find_pc_function (read_pc ()))
1713 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1718 /* trace_find_command takes a trace frame number n,
1719 sends "QTFrame:<n>" to the target,
1720 and accepts a reply that may contain several optional pieces
1721 of information: a frame number, a tracepoint number, and an
1722 indication of whether this is a trap frame or a stepping frame.
1724 The minimal response is just "OK" (which indicates that the
1725 target does not give us a frame number or a tracepoint number).
1726 Instead of that, the target may send us a string containing
1728 F<hexnum> (gives the selected frame number)
1729 T<hexnum> (gives the selected tracepoint number)
1734 trace_find_command (args
, from_tty
)
1737 { /* STUB_COMM PART_IMPLEMENTED */
1738 /* this should only be called with a numeric argument */
1740 int target_frameno
= -1, target_tracept
= -1, target_stepfrm
= 0;
1743 if (target_is_remote ())
1745 if (args
== 0 || *args
== 0)
1746 { /* TFIND with no args means find NEXT trace frame. */
1747 if (traceframe_number
== -1)
1748 frameno
= 0; /* "next" is first one */
1750 frameno
= traceframe_number
+ 1;
1752 else if (0 == strcmp (args
, "-"))
1754 if (traceframe_number
== -1)
1755 error ("not debugging trace buffer");
1756 else if (from_tty
&& traceframe_number
== 0)
1757 error ("already at start of trace buffer");
1759 frameno
= traceframe_number
- 1;
1762 frameno
= parse_and_eval_address (args
);
1764 sprintf (target_buf
, "QTFrame:%x", frameno
);
1766 putpkt (target_buf
);
1767 tmp
= remote_get_noisy_reply (target_buf
);
1769 if (frameno
== -1) /* end trace debugging */
1770 { /* hopefully the stub has complied! */
1771 if (0 != strcmp (tmp
, "OK"))
1772 error ("Bogus response from target: %s", tmp
);
1774 finish_tfind_command (NULL
, from_tty
);
1777 finish_tfind_command (tmp
, from_tty
);
1779 finish_tfind_command (target_buf
, from_tty
);
1783 error ("Trace can only be run on remote targets.");
1788 trace_find_end_command (args
, from_tty
)
1792 trace_find_command ("-1", from_tty
);
1797 trace_find_none_command (args
, from_tty
)
1801 trace_find_command ("-1", from_tty
);
1806 trace_find_start_command (args
, from_tty
)
1810 trace_find_command ("0", from_tty
);
1813 /* tfind pc command */
1815 trace_find_pc_command (args
, from_tty
)
1818 { /* STUB_COMM PART_IMPLEMENTED */
1823 if (target_is_remote ())
1825 if (args
== 0 || *args
== 0)
1826 pc
= read_pc (); /* default is current pc */
1828 pc
= parse_and_eval_address (args
);
1830 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
1832 putpkt (target_buf
);
1833 tmp
= remote_get_noisy_reply (target_buf
);
1835 finish_tfind_command (tmp
, from_tty
);
1837 finish_tfind_command (target_buf
, from_tty
);
1841 error ("Trace can only be run on remote targets.");
1844 /* tfind tracepoint command */
1846 trace_find_tracepoint_command (args
, from_tty
)
1849 { /* STUB_COMM PART_IMPLEMENTED */
1850 int target_frameno
, tdp
;
1853 if (target_is_remote ())
1855 if (args
== 0 || *args
== 0)
1856 if (tracepoint_number
== -1)
1857 error ("No current tracepoint -- please supply an argument.");
1859 tdp
= tracepoint_number
; /* default is current TDP */
1861 tdp
= parse_and_eval_address (args
);
1863 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
1865 putpkt (target_buf
);
1866 tmp
= remote_get_noisy_reply (target_buf
);
1868 finish_tfind_command (tmp
, from_tty
);
1870 finish_tfind_command (target_buf
, from_tty
);
1874 error ("Trace can only be run on remote targets.");
1877 /* TFIND LINE command:
1879 This command will take a sourceline for argument, just like BREAK
1880 or TRACE (ie. anything that "decode_line_1" can handle).
1882 With no argument, this command will find the next trace frame
1883 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1886 trace_find_line_command (args
, from_tty
)
1889 { /* STUB_COMM PART_IMPLEMENTED */
1890 static CORE_ADDR start_pc
, end_pc
;
1891 struct symtabs_and_lines sals
;
1892 struct symtab_and_line sal
;
1895 struct cleanup
*old_chain
;
1897 if (target_is_remote ())
1899 if (args
== 0 || *args
== 0)
1901 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
1903 sals
.sals
= (struct symtab_and_line
*)
1904 xmalloc (sizeof (struct symtab_and_line
));
1909 sals
= decode_line_spec (args
, 1);
1913 old_chain
= make_cleanup (free
, sals
.sals
);
1914 if (sal
.symtab
== 0)
1916 printf_filtered ("TFIND: No line number information available");
1919 /* This is useful for "info line *0x7f34". If we can't tell the
1920 user about a source line, at least let them have the symbolic
1922 printf_filtered (" for address ");
1924 print_address (sal
.pc
, gdb_stdout
);
1925 printf_filtered (";\n -- will attempt to find by PC. \n");
1929 printf_filtered (".\n");
1930 return; /* no line, no PC; what can we do? */
1933 else if (sal
.line
> 0
1934 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
1936 if (start_pc
== end_pc
)
1938 printf_filtered ("Line %d of \"%s\"",
1939 sal
.line
, sal
.symtab
->filename
);
1941 printf_filtered (" is at address ");
1942 print_address (start_pc
, gdb_stdout
);
1944 printf_filtered (" but contains no code.\n");
1945 sal
= find_pc_line (start_pc
, 0);
1947 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
1949 printf_filtered ("Attempting to find line %d instead.\n",
1952 error ("Cannot find a good line.");
1956 /* Is there any case in which we get here, and have an address
1957 which the user would want to see? If we have debugging symbols
1958 and no line numbers? */
1959 error ("Line number %d is out of range for \"%s\".\n",
1960 sal
.line
, sal
.symtab
->filename
);
1962 if (args
&& *args
) /* find within range of stated line */
1963 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
1964 else /* find OUTSIDE OF range of CURRENT line */
1965 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
1967 putpkt (target_buf
);
1968 tmp
= remote_get_noisy_reply (target_buf
);
1970 finish_tfind_command (tmp
, from_tty
);
1972 finish_tfind_command (target_buf
, from_tty
);
1974 do_cleanups (old_chain
);
1977 error ("Trace can only be run on remote targets.");
1980 /* tfind range command */
1982 trace_find_range_command (args
, from_tty
)
1985 { /* STUB_COMM PART_IMPLEMENTED */
1986 static CORE_ADDR start
, stop
;
1990 if (target_is_remote ())
1992 if (args
== 0 || *args
== 0)
1993 { /* XXX FIXME: what should default behavior be? */
1994 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
1998 if (0 != (tmp
= strchr (args
, ',' )))
2000 *tmp
++ = '\0'; /* terminate start address */
2001 while (isspace (*tmp
))
2003 start
= parse_and_eval_address (args
);
2004 stop
= parse_and_eval_address (tmp
);
2007 { /* no explicit end address? */
2008 start
= parse_and_eval_address (args
);
2009 stop
= start
+ 1; /* ??? */
2012 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2014 putpkt (target_buf
);
2015 tmp
= remote_get_noisy_reply (target_buf
);
2017 finish_tfind_command (tmp
, from_tty
);
2019 finish_tfind_command (target_buf
, from_tty
);
2023 error ("Trace can only be run on remote targets.");
2026 /* tfind outside command */
2028 trace_find_outside_command (args
, from_tty
)
2031 { /* STUB_COMM PART_IMPLEMENTED */
2032 CORE_ADDR start
, stop
;
2036 if (target_is_remote ())
2038 if (args
== 0 || *args
== 0)
2039 { /* XXX FIXME: what should default behavior be? */
2040 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2044 if (0 != (tmp
= strchr (args
, ',' )))
2046 *tmp
++ = '\0'; /* terminate start address */
2047 while (isspace (*tmp
))
2049 start
= parse_and_eval_address (args
);
2050 stop
= parse_and_eval_address (tmp
);
2053 { /* no explicit end address? */
2054 start
= parse_and_eval_address (args
);
2055 stop
= start
+ 1; /* ??? */
2058 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2060 putpkt (target_buf
);
2061 tmp
= remote_get_noisy_reply (target_buf
);
2063 finish_tfind_command (tmp
, from_tty
);
2065 finish_tfind_command (target_buf
, from_tty
);
2069 error ("Trace can only be run on remote targets.");
2072 /* save-tracepoints command */
2074 tracepoint_save_command (args
, from_tty
)
2078 struct tracepoint
*tp
;
2079 struct action_line
*line
;
2081 char *i1
= " ", *i2
= " ";
2082 char *indent
, *actionline
;
2084 if (args
== 0 || *args
== 0)
2085 error ("Argument required (file name in which to save tracepoints");
2087 if (tracepoint_chain
== 0)
2089 warning ("save-tracepoints: no tracepoints to save.\n");
2093 if (!(fp
= fopen (args
, "w")))
2094 error ("Unable to open file '%s' for saving tracepoints");
2096 ALL_TRACEPOINTS (tp
)
2098 if (tp
->addr_string
)
2099 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2101 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2104 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2108 fprintf (fp
, " actions\n");
2110 for (line
= tp
->actions
; line
; line
= line
->next
)
2112 struct cmd_list_element
*cmd
;
2114 actionline
= line
->action
;
2115 while (isspace(*actionline
))
2118 fprintf (fp
, "%s%s\n", indent
, actionline
);
2119 if (*actionline
!= '#') /* skip for comment lines */
2121 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2123 error ("Bad action list item: %s", actionline
);
2124 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2126 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2134 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2138 /* info scope command: list the locals for a scope. */
2140 scope_info (args
, from_tty
)
2144 struct symtab_and_line sal
;
2145 struct symtabs_and_lines sals
;
2147 struct minimal_symbol
*msym
;
2148 struct block
*block
;
2149 char **canonical
, *symname
, *save_args
= args
;
2150 int i
, nsyms
, count
= 0;
2152 if (args
== 0 || *args
== 0)
2153 error ("requires an argument (function, line or *addr) to define a scope");
2155 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2156 if (sals
.nelts
== 0)
2157 return; /* presumably decode_line_1 has already warned */
2159 /* Resolve line numbers to PC */
2160 resolve_sal_pc (&sals
.sals
[0]);
2161 block
= block_for_pc (sals
.sals
[0].pc
);
2165 nsyms
= BLOCK_NSYMS (block
);
2166 for (i
= 0; i
< nsyms
; i
++)
2169 printf_filtered ("Scope for %s:\n", save_args
);
2171 sym
= BLOCK_SYM (block
, i
);
2172 symname
= SYMBOL_NAME (sym
);
2173 if (symname
== NULL
|| *symname
== '\0')
2174 continue; /* probably botched, certainly useless */
2176 printf_filtered ("Symbol %s is ", symname
);
2177 switch (SYMBOL_CLASS (sym
)) {
2179 case LOC_UNDEF
: /* messed up symbol? */
2180 printf_filtered ("a bogus symbol, class %d.\n",
2181 SYMBOL_CLASS (sym
));
2182 count
--; /* don't count this one */
2185 printf_filtered ("a constant with value %d (0x%x)",
2186 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2188 case LOC_CONST_BYTES
:
2189 printf_filtered ("constant bytes: ");
2190 if (SYMBOL_TYPE (sym
))
2191 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2192 fprintf_filtered (gdb_stdout
, " %02x",
2193 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2196 printf_filtered ("in static storage at address ");
2197 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2200 printf_filtered ("a local variable in register $%s",
2201 reg_names
[SYMBOL_VALUE (sym
)]);
2205 printf_filtered ("an argument at stack/frame offset %ld",
2206 SYMBOL_VALUE (sym
));
2209 printf_filtered ("a local variable at frame offset %ld",
2210 SYMBOL_VALUE (sym
));
2213 printf_filtered ("a reference argument at offset %ld",
2214 SYMBOL_VALUE (sym
));
2217 printf_filtered ("an argument in register $%s",
2218 reg_names
[SYMBOL_VALUE (sym
)]);
2220 case LOC_REGPARM_ADDR
:
2221 printf_filtered ("the address of an argument, in register $%s",
2222 reg_names
[SYMBOL_VALUE (sym
)]);
2225 printf_filtered ("a typedef.\n");
2228 printf_filtered ("a label at address ");
2229 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2232 printf_filtered ("a function at address ");
2233 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2237 printf_filtered ("a variable at offset %d from register $%s",
2239 reg_names
[SYMBOL_BASEREG (sym
)]);
2241 case LOC_BASEREG_ARG
:
2242 printf_filtered ("an argument at offset %d from register $%s",
2244 reg_names
[SYMBOL_BASEREG (sym
)]);
2246 case LOC_UNRESOLVED
:
2247 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2249 printf_filtered ("Unresolved Static");
2252 printf_filtered ("static storage at address ");
2253 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2257 case LOC_OPTIMIZED_OUT
:
2258 printf_filtered ("optimized out.\n");
2261 if (SYMBOL_TYPE (sym
))
2262 printf_filtered (", length %d.\n",
2263 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2265 if (BLOCK_FUNCTION (block
))
2268 block
= BLOCK_SUPERBLOCK (block
);
2271 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2275 /* worker function (cleanup) */
2277 replace_comma (comma
)
2285 trace_dump_command (args
, from_tty
)
2289 struct tracepoint
*t
;
2290 struct action_line
*action
;
2291 char *action_exp
, *next_comma
;
2292 struct cleanup
*old_cleanups
;
2293 int stepping_actions
= 0;
2294 int stepping_frame
= 0;
2296 if (tracepoint_number
== -1)
2298 warning ("No current trace frame.");
2303 if (t
->number
== tracepoint_number
)
2307 error ("No known tracepoint matches 'current' tracepoint #%d.",
2310 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2312 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2313 tracepoint_number
, traceframe_number
);
2315 /* The current frame is a trap frame if the frame PC is equal
2316 to the tracepoint PC. If not, then the current frame was
2317 collected during single-stepping. */
2319 stepping_frame
= (t
->address
!= read_pc());
2321 for (action
= t
->actions
; action
; action
= action
->next
)
2323 struct cmd_list_element
*cmd
;
2325 action_exp
= action
->action
;
2326 while (isspace (*action_exp
))
2329 /* The collection actions to be done while stepping are
2330 bracketed by the commands "while-stepping" and "end". */
2332 if (*action_exp
== '#') /* comment line */
2335 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2337 error ("Bad action list item: %s", action_exp
);
2339 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2340 stepping_actions
= 1;
2341 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2342 stepping_actions
= 0;
2343 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2345 /* Display the collected data.
2346 For the trap frame, display only what was collected at the trap.
2347 Likewise for stepping frames, display only what was collected
2348 while stepping. This means that the two boolean variables,
2349 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2350 if (stepping_frame
== stepping_actions
)
2352 do { /* repeat over a comma-separated list */
2354 if (*action_exp
== ',')
2356 while (isspace (*action_exp
))
2359 next_comma
= strchr (action_exp
, ',');
2361 if (0 == strncasecmp (action_exp
, "$reg", 4))
2362 registers_info (NULL
, from_tty
);
2363 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2364 locals_info (NULL
, from_tty
);
2365 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2366 args_info (NULL
, from_tty
);
2367 else if (action_exp
[0] == '$' && action_exp
[1] == '(')
2369 long typecode
, size
;
2370 bfd_signed_vma offset
;
2373 action_exp
= parse_and_eval_memrange (action_exp
,
2378 if (typecode
!= 0 && typecode
!= -1)
2379 offset
+= read_register (typecode
);
2380 sprintf (fmt
, "/%dxb 0x%x", size
, offset
);
2381 x_command (fmt
, from_tty
);
2382 next_comma
= strchr (action_exp
, ',');
2388 make_cleanup (replace_comma
, next_comma
);
2391 printf_filtered ("%s = ", action_exp
);
2392 output_command (action_exp
, from_tty
);
2393 printf_filtered ("\n");
2397 action_exp
= next_comma
;
2398 } while (action_exp
&& *action_exp
== ',');
2402 discard_cleanups (old_cleanups
);
2405 /* module initialization */
2407 _initialize_tracepoint ()
2409 tracepoint_chain
= 0;
2410 tracepoint_count
= 0;
2411 traceframe_number
= -1;
2412 tracepoint_number
= -1;
2414 set_internalvar (lookup_internalvar ("tpnum"),
2415 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2416 set_internalvar (lookup_internalvar ("trace_frame"),
2417 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2419 if (tracepoint_list
.list
== NULL
)
2421 tracepoint_list
.listsize
= 128;
2422 tracepoint_list
.list
= xmalloc
2423 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2425 if (stepping_list
.list
== NULL
)
2427 stepping_list
.listsize
= 128;
2428 stepping_list
.list
= xmalloc
2429 (stepping_list
.listsize
* sizeof (struct memrange
));
2432 add_info ("scope", scope_info
,
2433 "List the variables local to a scope");
2435 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2436 "Tracing of program execution without stopping the program.",
2439 add_info ("tracepoints", tracepoints_info
,
2440 "Status of tracepoints, or tracepoint number NUMBER.\n\
2441 Convenience variable \"$tpnum\" contains the number of the\n\
2442 last tracepoint set.");
2444 add_info_alias ("tp", "tracepoints", 1);
2446 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2447 "Save current tracepoint definitions as a script.\n\
2448 Use the 'source' command in another debug session to restore them.");
2450 add_com ("tdump", class_trace
, trace_dump_command
,
2451 "Print everything collected at the current tracepoint.");
2453 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2454 "Select a trace frame;\n\
2455 No argument means forward by one frame; '-' meand backward by one frame.",
2456 &tfindlist
, "tfind ", 1, &cmdlist
);
2458 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2459 "Select a trace frame whose PC is outside the given \
2460 range.\nUsage: tfind outside addr1, addr2",
2463 add_cmd ("range", class_trace
, trace_find_range_command
,
2464 "Select a trace frame whose PC is in the given range.\n\
2465 Usage: tfind range addr1,addr2",
2468 add_cmd ("line", class_trace
, trace_find_line_command
,
2469 "Select a trace frame by source line.\n\
2470 Argument can be a line number (with optional source file), \n\
2471 a function name, or '*' followed by an address.\n\
2472 Default argument is 'the next source line that was traced'.",
2475 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2476 "Select a trace frame by tracepoint number.\n\
2477 Default is the tracepoint for the current trace frame.",
2480 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2481 "Select a trace frame by PC.\n\
2482 Default is the current PC, or the PC of the current trace frame.",
2485 add_cmd ("end", class_trace
, trace_find_end_command
,
2486 "Synonym for 'none'.\n\
2487 De-select any trace frame and resume 'live' debugging.",
2490 add_cmd ("none", class_trace
, trace_find_none_command
,
2491 "De-select any trace frame and resume 'live' debugging.",
2494 add_cmd ("start", class_trace
, trace_find_start_command
,
2495 "Select the first trace frame in the trace buffer.",
2498 add_com ("tstatus", class_trace
, trace_status_command
,
2499 "Display the status of the current trace data collection.");
2501 add_com ("tstop", class_trace
, trace_stop_command
,
2502 "Stop trace data collection.");
2504 add_com ("tstart", class_trace
, trace_start_command
,
2505 "Start trace data collection.");
2507 add_com ("passcount", class_trace
, trace_pass_command
,
2508 "Set the passcount for a tracepoint.\n\
2509 The trace will end when the tracepoint has been passed 'count' times.\n\
2510 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2511 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2513 add_com ("end", class_trace
, end_actions_pseudocommand
,
2514 "Ends a list of commands or actions.\n\
2515 Several GDB commands allow you to enter a list of commands or actions.\n\
2516 Entering \"end\" on a line by itself is the normal way to terminate\n\
2518 Note: the \"end\" command cannot be used at the gdb prompt.");
2520 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2521 "Specify single-stepping behavior at a tracepoint.\n\
2522 Argument is number of instructions to trace in single-step mode\n\
2523 following the tracepoint. This command is normally followed by\n\
2524 one or more \"collect\" commands, to specify what to collect\n\
2525 while single-stepping.\n\n\
2526 Note: this command can only be used in a tracepoint \"actions\" list.");
2528 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2529 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2531 add_com ("collect", class_trace
, collect_pseudocommand
,
2532 "Specify one or more data items to be collected at a tracepoint.\n\
2533 Accepts a comma-separated list of (one or more) arguments.\n\
2534 Things that may be collected include registers, variables, plus\n\
2535 the following special arguments:\n\
2536 $regs -- all registers.\n\
2537 $args -- all function arguments.\n\
2538 $locals -- all variables local to the block/function scope.\n\
2539 $(addr,len) -- a literal memory range.\n\
2540 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2541 Note: this command can only be used in a tracepoint \"actions\" list.");
2543 add_com ("actions", class_trace
, trace_actions_command
,
2544 "Specify the actions to be taken at a tracepoint.\n\
2545 Tracepoint actions may include collecting of specified data, \n\
2546 single-stepping, or enabling/disabling other tracepoints, \n\
2547 depending on target's capabilities.");
2549 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2550 "Delete specified tracepoints.\n\
2551 Arguments are tracepoint numbers, separated by spaces.\n\
2552 No argument means delete all tracepoints.",
2555 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2556 "Disable specified tracepoints.\n\
2557 Arguments are tracepoint numbers, separated by spaces.\n\
2558 No argument means disable all tracepoints.",
2561 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2562 "Enable specified tracepoints.\n\
2563 Arguments are tracepoint numbers, separated by spaces.\n\
2564 No argument means enable all tracepoints.",
2567 add_com ("trace", class_trace
, trace_command
,
2568 "Set a tracepoint at a specified line or function or address.\n\
2569 Argument may be a line number, function name, or '*' plus an address.\n\
2570 For a line number or function, trace at the start of its code.\n\
2571 If an address is specified, trace at that exact address.\n\n\
2572 Do \"help tracepoints\" for info on other tracepoint commands.");
2574 add_com_alias ("tp", "trace", class_alias
, 0);
2575 add_com_alias ("tr", "trace", class_alias
, 1);
2576 add_com_alias ("tra", "trace", class_alias
, 1);
2577 add_com_alias ("trac", "trace", class_alias
, 1);