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));
48 /* If this definition isn't overridden by the header files, assume
49 that isatty and fileno exist on this system. */
51 #define ISATTY(FP) (isatty (fileno (FP)))
57 This module defines the following debugger commands:
58 trace : set a tracepoint on a function, line, or address.
59 info trace : list all debugger-defined tracepoints.
60 delete trace : delete one or more tracepoints.
61 enable trace : enable one or more tracepoints.
62 disable trace : disable one or more tracepoints.
63 actions : specify actions to be taken at a tracepoint.
64 passcount : specify a pass count for a tracepoint.
65 tstart : start a trace experiment.
66 tstop : stop a trace experiment.
67 tstatus : query the status of a trace experiment.
68 tfind : find a trace frame in the trace buffer.
69 tdump : print everything collected at the current tracepoint.
70 save-tracepoints : write tracepoint setup into a file.
72 This module defines the following user-visible debugger variables:
73 $trace_frame : sequence number of trace frame currently being debugged.
74 $trace_line : source line of trace frame currently being debugged.
75 $trace_file : source file of trace frame currently being debugged.
76 $tracepoint : tracepoint number of trace frame currently being debugged.
80 /* ======= Important global variables: ======= */
82 /* Chain of all tracepoints defined. */
83 struct tracepoint
*tracepoint_chain
;
85 /* Number of last tracepoint made. */
86 static int tracepoint_count
;
88 /* Number of last traceframe collected. */
89 static int traceframe_number
;
91 /* Tracepoint for last traceframe collected. */
92 static int tracepoint_number
;
94 /* Symbol for function for last traceframe collected */
95 static struct symbol
*traceframe_fun
;
97 /* Symtab and line for last traceframe collected */
98 static struct symtab_and_line traceframe_sal
;
100 /* Tracing command lists */
101 static struct cmd_list_element
*tfindlist
;
103 /* ======= Important command functions: ======= */
104 static void trace_command
PARAMS ((char *, int));
105 static void tracepoints_info
PARAMS ((char *, int));
106 static void delete_trace_command
PARAMS ((char *, int));
107 static void enable_trace_command
PARAMS ((char *, int));
108 static void disable_trace_command
PARAMS ((char *, int));
109 static void trace_pass_command
PARAMS ((char *, int));
110 static void trace_actions_command
PARAMS ((char *, int));
111 static void trace_start_command
PARAMS ((char *, int));
112 static void trace_stop_command
PARAMS ((char *, int));
113 static void trace_status_command
PARAMS ((char *, int));
114 static void trace_find_command
PARAMS ((char *, int));
115 static void trace_find_pc_command
PARAMS ((char *, int));
116 static void trace_find_tracepoint_command
PARAMS ((char *, int));
117 static void trace_find_line_command
PARAMS ((char *, int));
118 static void trace_find_range_command
PARAMS ((char *, int));
119 static void trace_find_outside_command
PARAMS ((char *, int));
120 static void tracepoint_save_command
PARAMS ((char *, int));
121 static void trace_dump_command
PARAMS ((char *, int));
124 /* Utility: returns true if "target remote" */
128 if (current_target
.to_shortname
&&
129 strcmp (current_target
.to_shortname
, "remote") == 0)
135 /* Utility: generate error from an incoming stub packet. */
141 return; /* not an error msg */
144 case '1': /* malformed packet error */
145 if (*++buf
== '0') /* general case: */
146 error ("tracepoint.c: error in outgoing packet.");
148 error ("tracepoint.c: error in outgoing packet at field #%d.",
149 strtol (buf
, NULL
, 16));
151 error ("trace API error 0x%s.", ++buf
);
153 error ("Target returns error code '%s'.", buf
);
157 /* Utility: wait for reply from stub, while accepting "O" packets */
159 remote_get_noisy_reply (buf
)
162 do /* loop on reply from remote stub */
166 error ("Target does not support this command.");
167 else if (buf
[0] == 'E')
169 else if (buf
[0] == 'O' &&
171 remote_console_output (buf
+ 1); /* 'O' message from stub */
173 return buf
; /* here's the actual reply */
177 /* Set tracepoint count to NUM. */
179 set_tracepoint_count (num
)
182 tracepoint_count
= num
;
183 set_internalvar (lookup_internalvar ("tpnum"),
184 value_from_longest (builtin_type_int
, (LONGEST
) num
));
187 /* Set traceframe number to NUM. */
189 set_traceframe_num (num
)
192 traceframe_number
= num
;
193 set_internalvar (lookup_internalvar ("trace_frame"),
194 value_from_longest (builtin_type_int
, (LONGEST
) num
));
197 /* Set tracepoint number to NUM. */
199 set_tracepoint_num (num
)
202 tracepoint_number
= num
;
203 set_internalvar (lookup_internalvar ("tracepoint"),
204 value_from_longest (builtin_type_int
, (LONGEST
) num
));
207 /* Set externally visible debug variables for querying/printing
208 the traceframe context (line, function, file) */
211 set_traceframe_context (trace_pc
)
214 static struct type
*func_string
, *file_string
;
215 static struct type
*func_range
, *file_range
;
216 static value_ptr func_val
, file_val
;
217 static struct type
*charstar
;
220 if (charstar
== (struct type
*) NULL
)
221 charstar
= lookup_pointer_type (builtin_type_char
);
223 if (trace_pc
== -1) /* cease debugging any trace buffers */
226 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
227 traceframe_sal
.symtab
= NULL
;
228 set_internalvar (lookup_internalvar ("trace_func"),
229 value_from_longest (charstar
, (LONGEST
) 0));
230 set_internalvar (lookup_internalvar ("trace_file"),
231 value_from_longest (charstar
, (LONGEST
) 0));
232 set_internalvar (lookup_internalvar ("trace_line"),
233 value_from_longest (builtin_type_int
, (LONGEST
) -1));
237 /* save as globals for internal use */
238 traceframe_sal
= find_pc_line (trace_pc
, 0);
239 traceframe_fun
= find_pc_function (trace_pc
);
241 /* save linenumber as "$trace_line", a debugger variable visible to users */
242 set_internalvar (lookup_internalvar ("trace_line"),
243 value_from_longest (builtin_type_int
,
244 (LONGEST
) traceframe_sal
.line
));
246 /* save func name as "$trace_func", a debugger variable visible to users */
247 if (traceframe_fun
== NULL
||
248 SYMBOL_NAME (traceframe_fun
) == NULL
)
249 set_internalvar (lookup_internalvar ("trace_func"),
250 value_from_longest (charstar
, (LONGEST
) 0));
253 len
= strlen (SYMBOL_NAME (traceframe_fun
));
254 func_range
= create_range_type (func_range
,
255 builtin_type_int
, 0, len
- 1);
256 func_string
= create_array_type (func_string
,
257 builtin_type_char
, func_range
);
258 func_val
= allocate_value (func_string
);
259 VALUE_TYPE (func_val
) = func_string
;
260 memcpy (VALUE_CONTENTS_RAW (func_val
),
261 SYMBOL_NAME (traceframe_fun
),
263 func_val
->modifiable
= 0;
264 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
267 /* save file name as "$trace_file", a debugger variable visible to users */
268 if (traceframe_sal
.symtab
== NULL
||
269 traceframe_sal
.symtab
->filename
== NULL
)
270 set_internalvar (lookup_internalvar ("trace_file"),
271 value_from_longest (charstar
, (LONGEST
) 0));
274 len
= strlen (traceframe_sal
.symtab
->filename
);
275 file_range
= create_range_type (file_range
,
276 builtin_type_int
, 0, len
- 1);
277 file_string
= create_array_type (file_string
,
278 builtin_type_char
, file_range
);
279 file_val
= allocate_value (file_string
);
280 VALUE_TYPE (file_val
) = file_string
;
281 memcpy (VALUE_CONTENTS_RAW (file_val
),
282 traceframe_sal
.symtab
->filename
,
284 file_val
->modifiable
= 0;
285 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
289 /* Low level routine to set a tracepoint.
290 Returns the tracepoint object so caller can set other things.
291 Does not set the tracepoint number!
292 Does not print anything.
294 ==> This routine should not be called if there is a chance of later
295 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
296 your arguments BEFORE calling this routine! */
298 static struct tracepoint
*
299 set_raw_tracepoint (sal
)
300 struct symtab_and_line sal
;
302 register struct tracepoint
*t
, *tc
;
303 struct cleanup
*old_chain
;
305 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
306 old_chain
= make_cleanup (free
, t
);
307 memset (t
, 0, sizeof (*t
));
309 if (sal
.symtab
== NULL
)
310 t
->source_file
= NULL
;
315 t
->source_file
= (char *) xmalloc (strlen (sal
.symtab
->filename
) +
316 strlen (sal
.symtab
->dirname
) + 2);
318 strcpy (t
->source_file
, sal
.symtab
->dirname
);
322 if (*(--p
) != '/') /* Will this work on Windows? */
323 strcat (t
->source_file
, "/");
324 strcat (t
->source_file
, sal
.symtab
->filename
);
327 t
->language
= current_language
->la_language
;
328 t
->input_radix
= input_radix
;
329 t
->line_number
= sal
.line
;
330 t
->enabled
= enabled
;
335 /* Add this tracepoint to the end of the chain
336 so that a list of tracepoints will come out in order
337 of increasing numbers. */
339 tc
= tracepoint_chain
;
341 tracepoint_chain
= t
;
348 discard_cleanups (old_chain
);
352 /* Set a tracepoint according to ARG (function, linenum or *address) */
354 trace_command (arg
, from_tty
)
358 char **canonical
= (char **)NULL
;
359 struct symtabs_and_lines sals
;
360 struct symtab_and_line sal
;
361 struct tracepoint
*t
;
362 char *addr_start
= 0, *addr_end
= 0, *cond_start
= 0, *cond_end
= 0;
366 error ("trace command requires an argument");
368 if (from_tty
&& info_verbose
)
369 printf_filtered ("TRACE %s\n", arg
);
377 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
380 return; /* ??? Presumably decode_line_1 has already warned? */
382 /* Resolve all line numbers to PC's */
383 for (i
= 0; i
< sals
.nelts
; i
++)
384 resolve_sal_pc (&sals
.sals
[i
]);
386 /* Now set all the tracepoints. */
387 for (i
= 0; i
< sals
.nelts
; i
++)
391 t
= set_raw_tracepoint (sal
);
392 set_tracepoint_count (tracepoint_count
+ 1);
393 t
->number
= tracepoint_count
;
395 /* If a canonical line spec is needed use that instead of the
397 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
398 t
->addr_string
= canonical
[i
];
400 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
402 t
->cond_string
= savestring (cond_start
, cond_end
- cond_start
);
404 /* Let the UI know of any additions */
405 if (create_tracepoint_hook
)
406 create_tracepoint_hook (t
);
411 printf_filtered ("Multiple tracepoints were set.\n");
412 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
416 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
419 tracepoints_info (tpnum_exp
, from_tty
)
423 struct tracepoint
*t
;
424 struct action_line
*action
;
425 int found_a_tracepoint
= 0;
426 char wrap_indent
[80];
430 char *i1
= "\t", *i2
= "\t ";
431 char *indent
, *actionline
;;
435 tpnum
= parse_and_eval_address (tpnum_exp
);
438 if (tpnum
== -1 || tpnum
== t
->number
)
440 extern int addressprint
; /* print machine addresses? */
442 if (!found_a_tracepoint
++)
444 printf_filtered ("Num Enb ");
446 printf_filtered ("Address ");
447 printf_filtered ("PassC StepC What\n");
449 strcpy (wrap_indent
, " ");
451 strcat (wrap_indent
, " ");
453 printf_filtered ("%-3d %-3s ", t
->number
,
454 t
->enabled
== enabled
? "y" : "n");
456 printf_filtered ("%s ",
457 local_hex_string_custom ((unsigned long) t
->address
,
459 printf_filtered ("%-5d %-5d ", t
->pass_count
, t
->step_count
);
463 sym
= find_pc_function (t
->address
);
466 fputs_filtered ("in ", gdb_stdout
);
467 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
468 wrap_here (wrap_indent
);
469 fputs_filtered (" at ", gdb_stdout
);
471 fputs_filtered (t
->source_file
, gdb_stdout
);
472 printf_filtered (":%d", t
->line_number
);
475 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
477 printf_filtered ("\n");
480 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
482 for (action
= t
->actions
; action
; action
= action
->next
)
485 actionline
= action
->action
;
486 while (isspace(*actionline
))
489 printf_filtered ("%s%s\n", indent
, actionline
);
490 if (0 == strncasecmp (actionline
, "while-stepping", 14))
492 else if (0 == strncasecmp (actionline
, "end", 3))
495 printf_filtered ("\t%s\n", action
->action
);
500 if (!found_a_tracepoint
)
503 printf_filtered ("No tracepoints.\n");
505 printf_filtered ("No tracepoint number %d.\n", tpnum
);
509 /* Optimization: the code to parse an enable, disable, or delete TP command
510 is virtually identical except for whether it performs an enable, disable,
511 or delete. Therefore I've combined them into one function with an opcode.
513 enum tracepoint_opcode
520 /* This function implements enable, disable and delete. */
522 tracepoint_operation (t
, from_tty
, opcode
)
523 struct tracepoint
*t
;
525 enum tracepoint_opcode opcode
;
527 struct tracepoint
*t2
;
528 struct action_line
*action
, *next
;
532 t
->enabled
= enabled
;
535 t
->enabled
= disabled
;
538 if (tracepoint_chain
== t
)
539 tracepoint_chain
= t
->next
;
548 /* Let the UI know of any deletions */
549 if (delete_tracepoint_hook
)
550 delete_tracepoint_hook (t
);
553 free (t
->cond_string
);
555 free (t
->addr_string
);
557 free (t
->source_file
);
558 for (action
= t
->actions
; action
; action
= next
)
562 free (action
->action
);
570 /* Utility: parse a tracepoint number and look it up in the list. */
572 get_tracepoint_by_number (arg
)
575 struct tracepoint
*t
;
581 error ("Bad tracepoint argument");
583 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
584 tpnum
= tracepoint_count
;
585 else if (**arg
== '$') /* handle convenience variable */
587 /* Make a copy of the name, so we can null-terminate it
588 to pass to lookup_internalvar(). */
590 while (isalnum(*end
) || *end
== '_')
592 copy
= (char *) alloca (end
- *arg
);
593 strncpy (copy
, *arg
+ 1, (end
- *arg
- 1));
594 copy
[end
- *arg
- 1] = '\0';
597 val
= value_of_internalvar (lookup_internalvar (copy
));
598 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
599 error ("Convenience variable must have integral type.");
600 tpnum
= (int) value_as_long (val
);
602 else /* handle tracepoint number */
604 tpnum
= strtol (*arg
, arg
, 10);
607 if (t
->number
== tpnum
)
611 warning ("No tracepoint number %d.\n", tpnum
);
615 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
617 map_args_over_tracepoints (args
, from_tty
, opcode
)
620 enum tracepoint_opcode opcode
;
622 struct tracepoint
*t
;
626 if (args
== 0 || *args
== 0) /* do them all */
628 tracepoint_operation (t
, from_tty
, opcode
);
632 if (t
= get_tracepoint_by_number (&args
))
633 tracepoint_operation (t
, from_tty
, opcode
);
634 while (*args
== ' ' || *args
== '\t')
639 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
641 enable_trace_command (args
, from_tty
)
646 map_args_over_tracepoints (args
, from_tty
, enable
);
649 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
651 disable_trace_command (args
, from_tty
)
656 map_args_over_tracepoints (args
, from_tty
, disable
);
659 /* Remove a tracepoint (or all if no argument) */
661 delete_trace_command (args
, from_tty
)
667 if (!query ("Delete all tracepoints? "))
670 map_args_over_tracepoints (args
, from_tty
, delete);
673 /* Set passcount for tracepoint.
675 First command argument is passcount, second is tracepoint number.
676 If tracepoint number omitted, apply to most recently defined.
677 Also accepts special argument "all". */
680 trace_pass_command (args
, from_tty
)
684 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
687 if (args
== 0 || *args
== 0)
688 error ("PASS command requires an argument (count + optional TP num)");
690 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
692 while (*args
&& isspace (*args
))
695 if (*args
&& strncasecmp (args
, "all", 3) == 0)
696 args
+= 3; /* skip special argument "all" */
698 t1
= get_tracepoint_by_number (&args
);
701 return; /* error, bad tracepoint number */
704 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
706 t2
->pass_count
= count
;
708 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
713 /* ACTIONS functions: */
715 /* Prototypes for action-parsing utility commands */
716 static void read_actions
PARAMS((struct tracepoint
*));
717 static void free_actions
PARAMS((struct tracepoint
*));
718 static char *parse_and_eval_memrange
PARAMS ((char *,
724 /* The three functions:
725 collect_pseudocommand,
726 while_stepping_pseudocommand, and
727 end_actions_pseudocommand
728 are placeholders for "commands" that are actually ONLY to be used
729 within a tracepoint action list. If the actual function is ever called,
730 it means that somebody issued the "command" at the top level,
731 which is always an error. */
734 end_actions_pseudocommand (args
, from_tty
)
736 error ("This command cannot be used at the top level.");
740 while_stepping_pseudocommand (args
, from_tty
)
742 error ("This command can only be used in a tracepoint actions list.");
746 collect_pseudocommand (args
, from_tty
)
748 error ("This command can only be used in a tracepoint actions list.");
751 /* Enter a list of actions for a tracepoint. */
753 trace_actions_command (args
, from_tty
)
757 struct tracepoint
*t
;
760 char *end_msg
= "End with a line saying just \"end\".";
762 if (t
= get_tracepoint_by_number (&args
))
764 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
767 if (readline_begin_hook
)
768 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
769 else if (from_tty
&& input_from_terminal_p ())
770 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
775 if (readline_end_hook
)
776 (*readline_end_hook
) ();
778 /* tracepoints_changed () */
780 /* else error, just return; */
791 static enum actionline_type validate_actionline
PARAMS((char *,
792 struct tracepoint
*));
794 /* worker function */
797 struct tracepoint
*t
;
800 char *prompt1
= "> ", *prompt2
= " > ";
801 char *prompt
= prompt1
;
802 enum actionline_type linetype
;
803 extern FILE *instream
;
804 struct action_line
*next
= NULL
, *temp
;
805 struct cleanup
*old_chain
;
807 /* Control-C quits instantly if typed while in this loop
808 since it should not wait until the user types a newline. */
812 signal (STOP_SIGNAL
, stop_sig
);
814 old_chain
= make_cleanup (free_actions
, (void *) t
);
817 /* Make sure that all output has been output. Some machines may let
818 you get away with leaving out some of the gdb_flush, but not all. */
820 gdb_flush (gdb_stdout
);
821 gdb_flush (gdb_stderr
);
823 if (readline_hook
&& instream
== NULL
)
824 line
= (*readline_hook
) (prompt
);
825 else if (instream
== stdin
&& ISATTY (instream
))
826 line
= readline (prompt
);
828 line
= gdb_readline (0);
830 linetype
= validate_actionline (line
, t
);
831 if (linetype
== BADLINE
)
832 continue; /* already warned -- collect another line */
834 temp
= xmalloc (sizeof (struct action_line
));
838 if (next
== NULL
) /* first action for this tracepoint? */
839 t
->actions
= next
= temp
;
846 if (linetype
== STEPPING
) /* begin "while-stepping" */
847 if (prompt
== prompt2
)
849 warning ("Already processing 'while-stepping'");
853 prompt
= prompt2
; /* change prompt for stepping actions */
854 else if (linetype
== END
)
855 if (prompt
== prompt2
)
856 prompt
= prompt1
; /* end of single-stepping actions */
858 break; /* end of actions */
862 signal (STOP_SIGNAL
, SIG_DFL
);
865 discard_cleanups (old_chain
);
868 /* worker function */
869 static enum actionline_type
870 validate_actionline (line
, t
)
872 struct tracepoint
*t
;
874 struct cmd_list_element
*c
;
875 struct expression
*exp
;
876 value_ptr temp
, temp2
;
879 for (p
= line
; isspace (*p
); )
882 /* symbol lookup etc. */
883 if (*p
== '\0') /* empty line: just prompt for another line. */
886 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
889 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
893 if (c
->function
.cfunc
== collect_pseudocommand
)
895 do { /* repeat over a comma-separated list */
899 if (*p
== '$') /* look for special pseudo-symbols */
902 bfd_signed_vma offset
;
904 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
905 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
906 (0 == strncasecmp ("loc", p
+ 1, 3)))
909 else if (p
[1] == '(') /* literal memrange */
910 p
= parse_and_eval_memrange (p
, t
->address
,
911 &typecode
, &offset
, &size
);
915 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
917 if (exp
->elts
[0].opcode
!= OP_VAR_VALUE
&&
918 /*exp->elts[0].opcode != OP_LONG && */
919 /*exp->elts[0].opcode != UNOP_CAST && */
920 exp
->elts
[0].opcode
!= OP_REGISTER
)
922 warning ("collect requires a variable or register name.\n");
925 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
926 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
928 warning ("%s is constant (value %d): will not be collected.",
929 SYMBOL_NAME (exp
->elts
[2].symbol
),
930 SYMBOL_VALUE (exp
->elts
[2].symbol
));
933 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
935 warning ("%s is optimized away and cannot be collected.",
936 SYMBOL_NAME (exp
->elts
[2].symbol
));
940 } while (p
&& *p
++ == ',');
943 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
945 char *steparg
; /* in case warning is necessary */
953 t
->step_count
= strtol (p
, &p
, 0);
954 if (t
->step_count
== 0)
956 warning ("'%s' evaluates to zero -- command ignored.");
964 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
968 warning ("'%s' is not a supported tracepoint action.", line
);
973 /* worker function */
976 struct tracepoint
*t
;
978 struct action_line
*line
, *next
;
980 for (line
= t
->actions
; line
; line
= next
)
989 int type
; /* 0 for absolute memory range, else basereg number */
990 bfd_signed_vma start
;
994 struct collection_list
{
995 unsigned char regs_mask
[8]; /* room for up to 256 regs */
998 struct memrange
*list
;
999 } tracepoint_list
, stepping_list
;
1001 /* MEMRANGE functions: */
1003 /* parse a memrange spec from command input */
1005 parse_and_eval_memrange (arg
, addr
, typecode
, offset
, size
)
1008 long *typecode
, *size
;
1009 bfd_signed_vma
*offset
;
1012 struct expression
*exp
;
1014 if (*arg
++ != '$' || *arg
++ != '(')
1015 error ("Internal: bad argument to validate_memrange: %s", start
);
1017 if (*arg
== '$') /* register for relative memrange? */
1019 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1020 if (exp
->elts
[0].opcode
!= OP_REGISTER
)
1021 error ("Bad register operand for memrange: %s", start
);
1023 error ("missing comma for memrange: %s", start
);
1024 *typecode
= exp
->elts
[1].longconst
;
1030 /* While attractive, this fails for a number of reasons:
1031 1) parse_and_eval_address does not deal with trailing commas,
1033 2) There is no safeguard against the user trying to use
1034 an out-of-scope variable in an address expression (for instance).
1035 2.5) If you are going to allow semi-arbitrary expressions, you
1036 would need to explain which expressions are allowed, and
1037 which are not (which would provoke endless questions).
1038 3) If you are going to allow semi-arbitrary expressions in the
1039 offset and size fields, then the leading "$" of a register
1040 name no longer disambiguates the typecode field.
1043 *offset
= parse_and_eval_address (arg
);
1044 if ((arg
= strchr (arg
, ',')) == NULL
)
1045 error ("missing comma for memrange: %s", start
);
1049 *size
= parse_and_eval_address (arg
);
1050 if ((arg
= strchr (arg
, ')')) == NULL
)
1051 error ("missing close-parenthesis for memrange: %s", start
);
1056 /* This, on the other hand, doesn't work because "-1" is an
1057 expression, not an OP_LONG! Fall back to using strtol for now. */
1059 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1060 if (exp
->elts
[0].opcode
!= OP_LONG
)
1061 error ("Bad offset operand for memrange: %s", start
);
1062 *offset
= exp
->elts
[2].longconst
;
1065 error ("missing comma for memrange: %s", start
);
1067 exp
= parse_exp_1 (&arg
, block_for_pc (addr
), 1);
1068 if (exp
->elts
[0].opcode
!= OP_LONG
)
1069 error ("Bad size operand for memrange: %s", start
);
1070 *size
= exp
->elts
[2].longconst
;
1073 error ("invalid size in memrange: %s", start
);
1076 error ("missing close-parenthesis for memrange: %s", start
);
1078 *offset
= strtol (arg
, &arg
, 0);
1080 error ("missing comma for memrange: %s", start
);
1081 *size
= strtol (arg
, &arg
, 0);
1083 error ("invalid size in memrange: %s", start
);
1085 error ("missing close-parenthesis for memrange: %s", start
);
1089 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1090 *typecode
, *offset
, *size
);
1095 /* compare memranges for qsort */
1098 struct memrange
*a
, *b
;
1100 if (a
->type
< b
->type
) return -1;
1101 if (a
->type
> b
->type
) return 1;
1104 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
1105 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
1109 if (a
->start
< b
->start
) return -1;
1110 if (a
->start
> b
->start
) return 1;
1115 /* Sort the memrange list using qsort, and merge adjacent memranges */
1117 memrange_sortmerge (memranges
)
1118 struct collection_list
*memranges
;
1122 qsort (memranges
->list
, memranges
->next_memrange
,
1123 sizeof (struct memrange
), memrange_cmp
);
1124 if (memranges
->next_memrange
> 0)
1126 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1128 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1129 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1130 MAX_REGISTER_VIRTUAL_SIZE
)
1132 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1133 continue; /* next b, same a */
1137 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1138 sizeof (struct memrange
));
1140 memranges
->next_memrange
= a
+ 1;
1144 /* Add a register to a collection list */
1146 add_register (collection
, regno
)
1147 struct collection_list
*collection
;
1148 unsigned long regno
;
1151 printf_filtered ("collect register %d\n", regno
);
1152 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1153 error ("Internal: register number %d too large for tracepoint",
1155 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1158 /* Add a memrange to a collection list */
1160 add_memrange (memranges
, type
, base
, len
)
1161 struct collection_list
*memranges
;
1163 bfd_signed_vma base
;
1167 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
1168 /* type: 0 == memory, n == basereg */
1169 memranges
->list
[memranges
->next_memrange
].type
= type
;
1170 /* base: addr if memory, offset if reg relative. */
1171 memranges
->list
[memranges
->next_memrange
].start
= base
;
1172 /* len: we actually save end (base + len) for convenience */
1173 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1174 memranges
->next_memrange
++;
1175 if (memranges
->next_memrange
>= memranges
->listsize
)
1177 memranges
->listsize
*= 2;
1178 memranges
->list
= xrealloc (memranges
->list
,
1179 memranges
->listsize
);
1182 if (type
!= 0) /* better collect the base register! */
1183 add_register (memranges
, type
);
1186 /* Add a symbol to a collection list */
1188 collect_symbol (collect
, sym
)
1189 struct collection_list
*collect
;
1194 bfd_signed_vma offset
;
1196 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1197 switch (SYMBOL_CLASS (sym
)) {
1199 printf_filtered ("%s: don't know symbol class %d\n",
1200 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1203 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1204 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1207 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1209 printf_filtered ("LOC_STATIC %s: collect %d bytes "
1211 SYMBOL_NAME (sym
), len
, offset
);
1212 add_memrange (collect
, 0, offset
, len
); /* 0 == memory */
1216 reg
= SYMBOL_VALUE (sym
);
1218 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1219 add_register (collect
, reg
);
1223 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1224 printf_filtered (" (will not collect %s)\n",
1227 case LOC_REGPARM_ADDR
:
1228 reg
= SYMBOL_VALUE (sym
);
1232 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1233 SYMBOL_NAME (sym
), len
, offset
, reg
);
1235 add_memrange (collect
, reg
, offset
, len
);
1239 offset
= SYMBOL_VALUE (sym
);
1243 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1244 SYMBOL_NAME (sym
), len
, offset
, reg
);
1246 add_memrange (collect
, reg
, offset
, len
);
1249 case LOC_BASEREG_ARG
:
1250 reg
= SYMBOL_BASEREG (sym
);
1251 offset
= SYMBOL_VALUE (sym
);
1254 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1255 SYMBOL_NAME (sym
), len
, offset
, reg
);
1257 add_memrange (collect
, reg
, offset
, len
);
1259 case LOC_UNRESOLVED
:
1260 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1262 case LOC_OPTIMIZED_OUT
:
1263 printf_filtered ("%s has been optimized out of existance.\n",
1269 /* Add all locals (or args) symbols to collection list */
1271 add_local_symbols (collect
, pc
, type
)
1272 struct collection_list
*collect
;
1277 struct block
*block
;
1278 int i
, nsyms
, count
= 0;
1280 block
= block_for_pc (pc
);
1283 nsyms
= BLOCK_NSYMS (block
);
1284 for (i
= 0; i
< nsyms
; i
++)
1286 sym
= BLOCK_SYM (block
, i
);
1287 switch (SYMBOL_CLASS (sym
)) {
1292 if (type
== 'L') /* collecting Locals */
1295 collect_symbol (collect
, sym
);
1302 case LOC_REGPARM_ADDR
:
1303 case LOC_BASEREG_ARG
:
1304 if (type
== 'A') /* collecting Arguments */
1307 collect_symbol (collect
, sym
);
1311 if (BLOCK_FUNCTION (block
))
1314 block
= BLOCK_SUPERBLOCK (block
);
1317 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1320 /* worker function */
1322 clear_collection_list (list
)
1323 struct collection_list
*list
;
1325 list
->next_memrange
= 0;
1326 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1329 /* reduce a collection list to string form (for gdb protocol) */
1331 stringify_collection_list (list
, string
)
1332 struct collection_list
*list
;
1338 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1339 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1341 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1344 printf_filtered ("\nCollecting registers (mask): 0x");
1349 printf_filtered ("%02X", list
->regs_mask
[i
]);
1350 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1355 printf_filtered ("\n");
1356 if (list
->next_memrange
> 0 && info_verbose
)
1357 printf_filtered ("Collecting memranges: \n");
1358 for (i
= 0; i
< list
->next_memrange
; i
++)
1361 printf_filtered ("(%d, 0x%x, %d)\n",
1363 list
->list
[i
].start
,
1364 list
->list
[i
].end
- list
->list
[i
].start
);
1365 sprintf (end
, "M%X,%X,%X",
1367 list
->list
[i
].start
,
1368 list
->list
[i
].end
- list
->list
[i
].start
);
1369 end
+= strlen (end
);
1377 /* render all actions into gdb protocol */
1379 encode_actions (t
, tdp_actions
, step_count
, stepping_actions
)
1380 struct tracepoint
*t
;
1382 unsigned long *step_count
;
1383 char **stepping_actions
;
1385 static char tdp_buff
[2048], step_buff
[2048];
1387 struct expression
*exp
;
1388 struct action_line
*action
;
1389 bfd_signed_vma offset
;
1391 struct collection_list
*collect
;
1392 struct cmd_list_element
*cmd
;
1394 clear_collection_list (&tracepoint_list
);
1395 clear_collection_list (&stepping_list
);
1396 collect
= &tracepoint_list
;
1398 *tdp_actions
= NULL
;
1399 *stepping_actions
= NULL
;
1401 for (action
= t
->actions
; action
; action
= action
->next
)
1403 action_exp
= action
->action
;
1404 while (isspace (*action_exp
))
1407 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1409 error ("Bad action list item: %s", action_exp
);
1411 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1413 do { /* repeat over a comma-separated list */
1414 while (isspace (*action_exp
))
1417 if (0 == strncasecmp ("$reg", action_exp
, 4))
1419 for (i
= 0; i
< NUM_REGS
; i
++)
1420 add_register (collect
, i
);
1421 action_exp
= strchr (action_exp
, ','); /* more? */
1423 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1425 add_local_symbols (collect
, t
->address
, 'A');
1426 action_exp
= strchr (action_exp
, ','); /* more? */
1428 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1430 add_local_symbols (collect
, t
->address
, 'L');
1431 action_exp
= strchr (action_exp
, ','); /* more? */
1433 else if (action_exp
[0] == '$' &&
1434 action_exp
[1] == '(') /* literal memrange */
1436 long typecode
, size
;
1437 bfd_signed_vma offset
;
1439 action_exp
= parse_and_eval_memrange (action_exp
,
1444 add_memrange (collect
, typecode
, offset
, size
);
1448 unsigned long addr
, len
;
1450 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1451 switch (exp
->elts
[0].opcode
) {
1453 i
= exp
->elts
[1].longconst
;
1455 printf_filtered ("OP_REGISTER: ");
1456 add_register (collect
, i
);
1459 collect_symbol (collect
, exp
->elts
[2].symbol
);
1463 addr
= exp
->elts
[2].longconst
;
1464 if (*action_exp
== ':')
1466 exp
= parse_exp_1 (&action_exp
,
1467 block_for_pc (t
->address
),
1469 if (exp
->elts
[0].opcode
== OP_LONG
)
1470 len
= exp
->elts
[2].longconst
;
1472 error ("length field requires a literal long const");
1477 add_memrange (collect
, 0, addr
, len
);
1482 } while (action_exp
&& *action_exp
++ == ',');
1484 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1486 collect
= &stepping_list
;
1488 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1490 if (collect
== &stepping_list
) /* end stepping actions */
1491 collect
= &tracepoint_list
;
1493 break; /* end tracepoint actions */
1496 memrange_sortmerge (&tracepoint_list
);
1497 memrange_sortmerge (&stepping_list
);
1499 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1500 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1503 static char target_buf
[2048];
1507 Tell target to lear any previous trace experiment.
1508 Walk the list of tracepoints, and send them (and their actions)
1509 to the target. If no errors,
1510 Tell target to start a new trace experiment. */
1513 trace_start_command (args
, from_tty
)
1516 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1517 struct tracepoint
*t
;
1520 char *stepping_actions
;
1521 unsigned long step_count
;
1523 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1525 if (target_is_remote ())
1528 remote_get_noisy_reply (target_buf
);
1529 if (strcmp (target_buf
, "OK"))
1530 error ("Target does not support this command.");
1534 int ss_count
; /* if actions include singlestepping */
1535 int disable_mask
; /* ??? */
1536 int enable_mask
; /* ??? */
1538 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1539 t
->enabled
== enabled
? 'E' : 'D',
1540 t
->step_count
, t
->pass_count
);
1543 encode_actions (t
, &tdp_actions
, &step_count
, &stepping_actions
);
1544 /* do_single_steps (t); */
1547 if (strlen (buf
) + strlen (tdp_actions
) >= sizeof (buf
))
1548 error ("Actions for tracepoint %d too complex; "
1549 "please simplify.", t
->number
);
1550 strcat (buf
, tdp_actions
);
1552 if (stepping_actions
)
1555 if (strlen (buf
) + strlen (stepping_actions
) >= sizeof (buf
))
1556 error ("Actions for tracepoint %d too complex; "
1557 "please simplify.", t
->number
);
1558 strcat (buf
, stepping_actions
);
1562 remote_get_noisy_reply (target_buf
);
1563 if (strcmp (target_buf
, "OK"))
1564 error ("Target does not support tracepoints.");
1567 remote_get_noisy_reply (target_buf
);
1568 if (strcmp (target_buf
, "OK"))
1569 error ("Bogus reply from target: %s", target_buf
);
1570 set_traceframe_num (-1); /* all old traceframes invalidated */
1571 set_tracepoint_num (-1);
1572 set_traceframe_context(-1);
1575 printf_filtered ("Trace can only be run on remote targets.\n");
1580 trace_stop_command (args
, from_tty
)
1583 { /* STUB_COMM IS_IMPLEMENTED */
1584 if (target_is_remote ())
1587 remote_get_noisy_reply (target_buf
);
1588 if (strcmp (target_buf
, "OK"))
1589 error ("Bogus reply from target: %s", target_buf
);
1592 error ("Trace can only be run on remote targets.");
1595 /* tstatus command */
1597 trace_status_command (args
, from_tty
)
1600 { /* STUB_COMM IS_IMPLEMENTED */
1601 if (target_is_remote ())
1603 putpkt ("qTStatus");
1604 remote_get_noisy_reply (target_buf
);
1605 if (strcmp (target_buf
, "OK"))
1606 error ("Bogus reply from target: %s", target_buf
);
1609 error ("Trace can only be run on remote targets.");
1612 /* Worker function for the various flavors of the tfind command */
1614 finish_tfind_command (msg
, from_tty
)
1618 int target_frameno
= -1, target_tracept
= -1;
1619 CORE_ADDR old_frame_addr
;
1620 struct symbol
*old_func
;
1623 old_frame_addr
= FRAME_FP (get_current_frame ());
1624 old_func
= find_pc_function (read_pc ());
1627 reply
= remote_get_noisy_reply (msg
);
1629 while (reply
&& *reply
)
1632 if ((target_frameno
= strtol (++reply
, &reply
, 16)) == -1)
1634 /* A request for a non-existant trace frame has failed.
1635 Our response will be different, depending on FROM_TTY:
1637 If FROM_TTY is true, meaning that this command was
1638 typed interactively by the user, then give an error
1639 and DO NOT change the state of traceframe_number etc.
1641 However if FROM_TTY is false, meaning that we're either
1642 in a script, a loop, or a user-defined command, then
1643 DON'T give an error, but DO change the state of
1644 traceframe_number etc. to invalid.
1646 The rationalle is that if you typed the command, you
1647 might just have committed a typo or something, and you'd
1648 like to NOT lose your current debugging state. However
1649 if you're in a user-defined command or especially in a
1650 loop, then you need a way to detect that the command
1651 failed WITHOUT aborting. This allows you to write
1652 scripts that search thru the trace buffer until the end,
1653 and then continue on to do something else. */
1656 error ("Target failed to find requested trace frame.");
1660 printf_filtered ("End of trace buffer.\n");
1661 /* The following will not recurse, since it's special-cased */
1662 trace_find_command ("-1", from_tty
);
1663 reply
= NULL
; /* break out of loop,
1664 (avoid recursive nonsense) */
1669 if ((target_tracept
= strtol (++reply
, &reply
, 16)) == -1)
1670 error ("Target failed to find requested trace frame.");
1672 case 'O': /* "OK"? */
1673 if (reply
[1] == 'K' && reply
[2] == '\0')
1676 error ("Bogus reply from target: %s", reply
);
1679 error ("Bogus reply from target: %s", reply
);
1682 flush_cached_frames ();
1683 registers_changed ();
1684 select_frame (get_current_frame (), 0);
1685 set_traceframe_num (target_frameno
);
1686 set_tracepoint_num (target_tracept
);
1687 if (target_frameno
== -1)
1688 set_traceframe_context (-1);
1690 set_traceframe_context (read_pc ());
1696 if (old_frame_addr
== FRAME_FP (get_current_frame ()) &&
1697 old_func
== find_pc_function (read_pc ()))
1702 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1707 /* trace_find_command takes a trace frame number n,
1708 sends "QTFrame:<n>" to the target,
1709 and accepts a reply that may contain several optional pieces
1710 of information: a frame number, a tracepoint number, and an
1711 indication of whether this is a trap frame or a stepping frame.
1713 The minimal response is just "OK" (which indicates that the
1714 target does not give us a frame number or a tracepoint number).
1715 Instead of that, the target may send us a string containing
1717 F<hexnum> (gives the selected frame number)
1718 T<hexnum> (gives the selected tracepoint number)
1723 trace_find_command (args
, from_tty
)
1726 { /* STUB_COMM PART_IMPLEMENTED */
1727 /* this should only be called with a numeric argument */
1729 int target_frameno
= -1, target_tracept
= -1, target_stepfrm
= 0;
1732 if (target_is_remote ())
1734 if (args
== 0 || *args
== 0)
1735 { /* TFIND with no args means find NEXT trace frame. */
1736 if (traceframe_number
== -1)
1737 frameno
= 0; /* "next" is first one */
1739 frameno
= traceframe_number
+ 1;
1741 else if (0 == strcmp (args
, "-"))
1743 if (traceframe_number
== -1)
1744 error ("not debugging trace buffer");
1745 else if (traceframe_number
== 0)
1746 error ("already at start of trace buffer");
1748 frameno
= traceframe_number
- 1;
1751 frameno
= parse_and_eval_address (args
);
1753 sprintf (target_buf
, "QTFrame:%x", frameno
);
1755 putpkt (target_buf
);
1756 tmp
= remote_get_noisy_reply (target_buf
);
1758 if (frameno
== -1) /* end trace debugging */
1759 { /* hopefully the stub has complied! */
1760 if (0 != strcmp (tmp
, "OK"))
1761 error ("Bogus response from target: %s", tmp
);
1763 finish_tfind_command (NULL
, from_tty
);
1766 finish_tfind_command (tmp
, from_tty
);
1768 finish_tfind_command (target_buf
, from_tty
);
1772 error ("Trace can only be run on remote targets.");
1777 trace_find_end_command (args
, from_tty
)
1781 trace_find_command ("-1", from_tty
);
1786 trace_find_none_command (args
, from_tty
)
1790 trace_find_command ("-1", from_tty
);
1795 trace_find_start_command (args
, from_tty
)
1799 trace_find_command ("0", from_tty
);
1802 /* tfind pc command */
1804 trace_find_pc_command (args
, from_tty
)
1807 { /* STUB_COMM PART_IMPLEMENTED */
1812 if (target_is_remote ())
1814 if (args
== 0 || *args
== 0)
1815 pc
= read_pc (); /* default is current pc */
1817 pc
= parse_and_eval_address (args
);
1819 sprintf (target_buf
, "QTFrame:pc:%x", pc
);
1821 putpkt (target_buf
);
1822 tmp
= remote_get_noisy_reply (target_buf
);
1824 finish_tfind_command (tmp
, from_tty
);
1826 finish_tfind_command (target_buf
, from_tty
);
1830 error ("Trace can only be run on remote targets.");
1833 /* tfind tracepoint command */
1835 trace_find_tracepoint_command (args
, from_tty
)
1838 { /* STUB_COMM PART_IMPLEMENTED */
1839 int target_frameno
, tdp
;
1842 if (target_is_remote ())
1844 if (args
== 0 || *args
== 0)
1845 if (tracepoint_number
== -1)
1846 error ("No current tracepoint -- please supply an argument.");
1848 tdp
= tracepoint_number
; /* default is current TDP */
1850 tdp
= parse_and_eval_address (args
);
1852 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
1854 putpkt (target_buf
);
1855 tmp
= remote_get_noisy_reply (target_buf
);
1857 finish_tfind_command (tmp
, from_tty
);
1859 finish_tfind_command (target_buf
, from_tty
);
1863 error ("Trace can only be run on remote targets.");
1866 /* TFIND LINE command:
1868 This command will take a sourceline for argument, just like BREAK
1869 or TRACE (ie. anything that "decode_line_1" can handle).
1871 With no argument, this command will find the next trace frame
1872 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1875 trace_find_line_command (args
, from_tty
)
1878 { /* STUB_COMM PART_IMPLEMENTED */
1879 static CORE_ADDR start_pc
, end_pc
;
1880 struct symtabs_and_lines sals
;
1881 struct symtab_and_line sal
;
1884 struct cleanup
*old_chain
;
1886 if (target_is_remote ())
1888 if (args
== 0 || *args
== 0)
1890 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
1892 sals
.sals
= (struct symtab_and_line
*)
1893 xmalloc (sizeof (struct symtab_and_line
));
1898 sals
= decode_line_spec (args
, 1);
1902 old_chain
= make_cleanup (free
, sals
.sals
);
1903 if (sal
.symtab
== 0)
1905 printf_filtered ("TFIND: No line number information available");
1908 /* This is useful for "info line *0x7f34". If we can't tell the
1909 user about a source line, at least let them have the symbolic
1911 printf_filtered (" for address ");
1913 print_address (sal
.pc
, gdb_stdout
);
1914 printf_filtered (";\n -- will attempt to find by PC. \n");
1918 printf_filtered (".\n");
1919 return; /* no line, no PC; what can we do? */
1922 else if (sal
.line
> 0
1923 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
1925 if (start_pc
== end_pc
)
1927 printf_filtered ("Line %d of \"%s\"",
1928 sal
.line
, sal
.symtab
->filename
);
1930 printf_filtered (" is at address ");
1931 print_address (start_pc
, gdb_stdout
);
1933 printf_filtered (" but contains no code.\n");
1934 sal
= find_pc_line (start_pc
, 0);
1936 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
1938 printf_filtered ("Attempting to find line %d instead.\n",
1941 error ("Cannot find a good line.");
1945 /* Is there any case in which we get here, and have an address
1946 which the user would want to see? If we have debugging symbols
1947 and no line numbers? */
1948 error ("Line number %d is out of range for \"%s\".\n",
1949 sal
.line
, sal
.symtab
->filename
);
1951 if (args
&& *args
) /* find within range of stated line */
1952 sprintf (target_buf
, "QTFrame:range:%x:%x", start_pc
, end_pc
- 1);
1953 else /* find OUTSIDE OF range of CURRENT line */
1954 sprintf (target_buf
, "QTFrame:outside:%x:%x", start_pc
, end_pc
- 1);
1956 putpkt (target_buf
);
1957 tmp
= remote_get_noisy_reply (target_buf
);
1959 finish_tfind_command (tmp
, from_tty
);
1961 finish_tfind_command (target_buf
, from_tty
);
1963 do_cleanups (old_chain
);
1966 error ("Trace can only be run on remote targets.");
1969 /* tfind range command */
1971 trace_find_range_command (args
, from_tty
)
1974 { /* STUB_COMM PART_IMPLEMENTED */
1975 static CORE_ADDR start
, stop
;
1979 if (target_is_remote ())
1981 if (args
== 0 || *args
== 0)
1982 { /* XXX FIXME: what should default behavior be? */
1983 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
1987 if (0 != (tmp
= strchr (args
, ',' )))
1989 *tmp
++ = '\0'; /* terminate start address */
1990 while (isspace (*tmp
))
1992 start
= parse_and_eval_address (args
);
1993 stop
= parse_and_eval_address (tmp
);
1996 { /* no explicit end address? */
1997 start
= parse_and_eval_address (args
);
1998 stop
= start
+ 1; /* ??? */
2001 sprintf (target_buf
, "QTFrame:range:%x:%x", start
, stop
);
2003 putpkt (target_buf
);
2004 tmp
= remote_get_noisy_reply (target_buf
);
2006 finish_tfind_command (tmp
, from_tty
);
2008 finish_tfind_command (target_buf
, from_tty
);
2012 error ("Trace can only be run on remote targets.");
2015 /* tfind outside command */
2017 trace_find_outside_command (args
, from_tty
)
2020 { /* STUB_COMM PART_IMPLEMENTED */
2021 CORE_ADDR start
, stop
;
2025 if (target_is_remote ())
2027 if (args
== 0 || *args
== 0)
2028 { /* XXX FIXME: what should default behavior be? */
2029 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2033 if (0 != (tmp
= strchr (args
, ',' )))
2035 *tmp
++ = '\0'; /* terminate start address */
2036 while (isspace (*tmp
))
2038 start
= parse_and_eval_address (args
);
2039 stop
= parse_and_eval_address (tmp
);
2042 { /* no explicit end address? */
2043 start
= parse_and_eval_address (args
);
2044 stop
= start
+ 1; /* ??? */
2047 sprintf (target_buf
, "QTFrame:outside:%x:%x", start
, stop
);
2049 putpkt (target_buf
);
2050 tmp
= remote_get_noisy_reply (target_buf
);
2052 finish_tfind_command (tmp
, from_tty
);
2054 finish_tfind_command (target_buf
, from_tty
);
2058 error ("Trace can only be run on remote targets.");
2061 /* save-tracepoints command */
2063 tracepoint_save_command (args
, from_tty
)
2067 struct tracepoint
*tp
;
2068 struct action_line
*line
;
2070 char *i1
= " ", *i2
= " ";
2071 char *indent
, *actionline
;
2073 if (args
== 0 || *args
== 0)
2074 error ("Argument required (file name in which to save tracepoints");
2076 if (tracepoint_chain
== 0)
2078 warning ("save-tracepoints: no tracepoints to save.\n");
2082 if (!(fp
= fopen (args
, "w")))
2083 error ("Unable to open file '%s' for saving tracepoints");
2085 ALL_TRACEPOINTS (tp
)
2087 if (tp
->addr_string
)
2088 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2090 fprintf (fp
, "trace *0x%x\n", tp
->address
);
2093 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2097 fprintf (fp
, " actions\n");
2099 for (line
= tp
->actions
; line
; line
= line
->next
)
2101 struct cmd_list_element
*cmd
;
2103 actionline
= line
->action
;
2104 while (isspace(*actionline
))
2107 fprintf (fp
, "%s%s\n", indent
, actionline
);
2108 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2110 error ("Bad action list item: %s", actionline
);
2111 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2113 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2120 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2124 /* info scope command: list the locals for a scope. */
2126 scope_info (args
, from_tty
)
2130 struct symtab_and_line sal
;
2131 struct symtabs_and_lines sals
;
2133 struct minimal_symbol
*msym
;
2134 struct block
*block
;
2135 char **canonical
, *symname
, *save_args
= args
;
2136 int i
, nsyms
, count
= 0;
2138 if (args
== 0 || *args
== 0)
2139 error ("requires an argument (function, line or *addr) to define a scope");
2141 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2142 if (sals
.nelts
== 0)
2143 return; /* presumably decode_line_1 has already warned */
2145 /* Resolve line numbers to PC */
2146 resolve_sal_pc (&sals
.sals
[0]);
2147 block
= block_for_pc (sals
.sals
[0].pc
);
2151 nsyms
= BLOCK_NSYMS (block
);
2152 for (i
= 0; i
< nsyms
; i
++)
2155 printf_filtered ("Scope for %s:\n", save_args
);
2157 sym
= BLOCK_SYM (block
, i
);
2158 symname
= SYMBOL_NAME (sym
);
2159 if (symname
== NULL
|| *symname
== '\0')
2160 continue; /* probably botched, certainly useless */
2162 printf_filtered ("Symbol %s is ", symname
);
2163 switch (SYMBOL_CLASS (sym
)) {
2165 case LOC_UNDEF
: /* messed up symbol? */
2166 printf_filtered ("a bogus symbol, class %d.\n",
2167 SYMBOL_CLASS (sym
));
2168 count
--; /* don't count this one */
2171 printf_filtered ("a constant with value %d (0x%x)",
2172 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2174 case LOC_CONST_BYTES
:
2175 printf_filtered ("constant bytes: ");
2176 if (SYMBOL_TYPE (sym
))
2177 for (i
= 0; i
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); i
++)
2178 fprintf_filtered (gdb_stdout
, " %02x",
2179 (unsigned) SYMBOL_VALUE_BYTES (sym
) [i
]);
2182 printf_filtered ("in static storage at address ");
2183 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2186 printf_filtered ("a local variable in register $%s",
2187 reg_names
[SYMBOL_VALUE (sym
)]);
2191 printf_filtered ("an argument at stack/frame offset %ld",
2192 SYMBOL_VALUE (sym
));
2195 printf_filtered ("a local variable at frame offset %ld",
2196 SYMBOL_VALUE (sym
));
2199 printf_filtered ("a reference argument at offset %ld",
2200 SYMBOL_VALUE (sym
));
2203 printf_filtered ("an argument in register $%s",
2204 reg_names
[SYMBOL_VALUE (sym
)]);
2206 case LOC_REGPARM_ADDR
:
2207 printf_filtered ("the address of an argument, in register $%s",
2208 reg_names
[SYMBOL_VALUE (sym
)]);
2211 printf_filtered ("a typedef.\n");
2214 printf_filtered ("a label at address ");
2215 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2218 printf_filtered ("a function at address ");
2219 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2223 printf_filtered ("a variable at offset %d from register $%s",
2225 reg_names
[SYMBOL_BASEREG (sym
)]);
2227 case LOC_BASEREG_ARG
:
2228 printf_filtered ("an argument at offset %d from register $%s",
2230 reg_names
[SYMBOL_BASEREG (sym
)]);
2232 case LOC_UNRESOLVED
:
2233 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2235 printf_filtered ("Unresolved Static");
2238 printf_filtered ("static storage at address ");
2239 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2243 case LOC_OPTIMIZED_OUT
:
2244 printf_filtered ("optimized out.\n");
2247 if (SYMBOL_TYPE (sym
))
2248 printf_filtered (", length %d.\n",
2249 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2251 if (BLOCK_FUNCTION (block
))
2254 block
= BLOCK_SUPERBLOCK (block
);
2257 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2261 /* worker function (cleanup) */
2263 replace_comma (comma
)
2271 trace_dump_command (args
, from_tty
)
2275 struct tracepoint
*t
;
2276 struct action_line
*action
;
2277 char *action_exp
, *next_comma
;
2278 struct cleanup
*old_cleanups
;
2279 int stepping_actions
= 0;
2280 int stepping_frame
= 0;
2282 if (tracepoint_number
== -1)
2284 warning ("No current trace frame.");
2289 if (t
->number
== tracepoint_number
)
2293 error ("No known tracepoint matches 'current' tracepoint #%d.",
2296 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2298 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2299 tracepoint_number
, traceframe_number
);
2301 /* The current frame is a trap frame if the frame PC is equal
2302 to the tracepoint PC. If not, then the current frame was
2303 collected during single-stepping. */
2305 stepping_frame
= (t
->address
!= read_pc());
2307 for (action
= t
->actions
; action
; action
= action
->next
)
2309 struct cmd_list_element
*cmd
;
2311 action_exp
= action
->action
;
2312 while (isspace (*action_exp
))
2315 /* The collection actions to be done while stepping are
2316 bracketed by the commands "while-stepping" and "end". */
2318 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2320 error ("Bad action list item: %s", action_exp
);
2322 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2323 stepping_actions
= 1;
2324 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2325 stepping_actions
= 0;
2326 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2328 /* Display the collected data.
2329 For the trap frame, display only what was collected at the trap.
2330 Likewise for stepping frames, display only what was collected
2331 while stepping. This means that the two boolean variables,
2332 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2333 if (stepping_frame
== stepping_actions
)
2335 do { /* repeat over a comma-separated list */
2337 if (*action_exp
== ',')
2339 while (isspace (*action_exp
))
2342 next_comma
= strchr (action_exp
, ',');
2344 if (0 == strncasecmp (action_exp
, "$reg", 4))
2345 registers_info (NULL
, from_tty
);
2346 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2347 locals_info (NULL
, from_tty
);
2348 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2349 args_info (NULL
, from_tty
);
2350 else if (action_exp
[0] == '$' && action_exp
[1] == '(')
2352 long typecode
, size
;
2353 bfd_signed_vma offset
;
2356 action_exp
= parse_and_eval_memrange (action_exp
,
2361 if (typecode
!= 0 && typecode
!= -1)
2362 offset
+= read_register (typecode
);
2363 sprintf (fmt
, "/%dxb 0x%x", size
, offset
);
2364 x_command (fmt
, from_tty
);
2365 next_comma
= strchr (action_exp
, ',');
2371 make_cleanup (replace_comma
, next_comma
);
2374 printf_filtered ("%s = ", action_exp
);
2375 output_command (action_exp
, from_tty
);
2376 printf_filtered ("\n");
2380 action_exp
= next_comma
;
2381 } while (action_exp
&& *action_exp
== ',');
2385 discard_cleanups (old_cleanups
);
2388 /* module initialization */
2390 _initialize_tracepoint ()
2392 tracepoint_chain
= 0;
2393 tracepoint_count
= 0;
2394 traceframe_number
= -1;
2395 tracepoint_number
= -1;
2397 set_internalvar (lookup_internalvar ("tpnum"),
2398 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2399 set_internalvar (lookup_internalvar ("trace_frame"),
2400 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2402 if (tracepoint_list
.list
== NULL
)
2404 tracepoint_list
.listsize
= 128;
2405 tracepoint_list
.list
= xmalloc
2406 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2408 if (stepping_list
.list
== NULL
)
2410 stepping_list
.listsize
= 128;
2411 stepping_list
.list
= xmalloc
2412 (stepping_list
.listsize
* sizeof (struct memrange
));
2415 add_info ("scope", scope_info
,
2416 "List the variables local to a scope");
2418 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2419 "Tracing of program execution without stopping the program.",
2422 add_info ("tracepoints", tracepoints_info
,
2423 "Status of tracepoints, or tracepoint number NUMBER.\n\
2424 Convenience variable \"$tpnum\" contains the number of the\n\
2425 last tracepoint set.");
2427 add_info_alias ("tp", "tracepoints", 1);
2429 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2430 "Save current tracepoint definitions as a script.\n\
2431 Use the 'source' command in another debug session to restore them.");
2433 add_com ("tdump", class_trace
, trace_dump_command
,
2434 "Print everything collected at the current tracepoint.");
2436 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2437 "Select a trace frame;\n\
2438 No argument means forward by one frame; '-' meand backward by one frame.",
2439 &tfindlist
, "tfind ", 1, &cmdlist
);
2441 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2442 "Select a trace frame whose PC is outside the given \
2443 range.\nUsage: tfind outside addr1, addr2",
2446 add_cmd ("range", class_trace
, trace_find_range_command
,
2447 "Select a trace frame whose PC is in the given range.\n\
2448 Usage: tfind range addr1,addr2",
2451 add_cmd ("line", class_trace
, trace_find_line_command
,
2452 "Select a trace frame by source line.\n\
2453 Argument can be a line number (with optional source file), \n\
2454 a function name, or '*' followed by an address.\n\
2455 Default argument is 'the next source line that was traced'.",
2458 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2459 "Select a trace frame by tracepoint number.\n\
2460 Default is the tracepoint for the current trace frame.",
2463 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2464 "Select a trace frame by PC.\n\
2465 Default is the current PC, or the PC of the current trace frame.",
2468 add_cmd ("end", class_trace
, trace_find_end_command
,
2469 "Synonym for 'none'.\n\
2470 De-select any trace frame and resume 'live' debugging.",
2473 add_cmd ("none", class_trace
, trace_find_none_command
,
2474 "De-select any trace frame and resume 'live' debugging.",
2477 add_cmd ("start", class_trace
, trace_find_start_command
,
2478 "Select the first trace frame in the trace buffer.",
2481 add_com ("tstatus", class_trace
, trace_status_command
,
2482 "Display the status of the current trace data collection.");
2484 add_com ("tstop", class_trace
, trace_stop_command
,
2485 "Stop trace data collection.");
2487 add_com ("tstart", class_trace
, trace_start_command
,
2488 "Start trace data collection.");
2490 add_com ("passcount", class_trace
, trace_pass_command
,
2491 "Set the passcount for a tracepoint.\n\
2492 The trace will end when the tracepoint has been passed 'count' times.\n\
2493 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2494 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2496 add_com ("end", class_trace
, end_actions_pseudocommand
,
2497 "Ends a list of commands or actions.\n\
2498 Several GDB commands allow you to enter a list of commands or actions.\n\
2499 Entering \"end\" on a line by itself is the normal way to terminate\n\
2501 Note: the \"end\" command cannot be used at the gdb prompt.");
2503 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2504 "Specify single-stepping behavior at a tracepoint.\n\
2505 Argument is number of instructions to trace in single-step mode\n\
2506 following the tracepoint. This command is normally followed by\n\
2507 one or more \"collect\" commands, to specify what to collect\n\
2508 while single-stepping.\n\n\
2509 Note: this command can only be used in a tracepoint \"actions\" list.");
2511 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2512 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2514 add_com ("collect", class_trace
, collect_pseudocommand
,
2515 "Specify one or more data items to be collected at a tracepoint.\n\
2516 Accepts a comma-separated list of (one or more) arguments.\n\
2517 Things that may be collected include registers, variables, plus\n\
2518 the following special arguments:\n\
2519 $regs -- all registers.\n\
2520 $args -- all function arguments.\n\
2521 $locals -- all variables local to the block/function scope.\n\
2522 $(addr,len) -- a literal memory range.\n\
2523 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2524 Note: this command can only be used in a tracepoint \"actions\" list.");
2526 add_com ("actions", class_trace
, trace_actions_command
,
2527 "Specify the actions to be taken at a tracepoint.\n\
2528 Tracepoint actions may include collecting of specified data, \n\
2529 single-stepping, or enabling/disabling other tracepoints, \n\
2530 depending on target's capabilities.");
2532 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2533 "Delete specified tracepoints.\n\
2534 Arguments are tracepoint numbers, separated by spaces.\n\
2535 No argument means delete all tracepoints.",
2538 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2539 "Disable specified tracepoints.\n\
2540 Arguments are tracepoint numbers, separated by spaces.\n\
2541 No argument means disable all tracepoints.",
2544 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2545 "Enable specified tracepoints.\n\
2546 Arguments are tracepoint numbers, separated by spaces.\n\
2547 No argument means enable all tracepoints.",
2550 add_com ("trace", class_trace
, trace_command
,
2551 "Set a tracepoint at a specified line or function or address.\n\
2552 Argument may be a line number, function name, or '*' plus an address.\n\
2553 For a line number or function, trace at the start of its code.\n\
2554 If an address is specified, trace at that exact address.\n\n\
2555 Do \"help tracepoints\" for info on other tracepoint commands.");
2557 add_com_alias ("tp", "trace", class_alias
, 0);
2558 add_com_alias ("tr", "trace", class_alias
, 1);
2559 add_com_alias ("tra", "trace", class_alias
, 1);
2560 add_com_alias ("trac", "trace", class_alias
, 1);