1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997, 1998 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include "expression.h"
30 #include "gdb_string.h"
32 #include "tracepoint.h"
38 /* readline include files */
39 #include <readline/readline.h>
40 #include <readline/history.h>
42 /* readline defines this. */
49 /* maximum length of an agent aexpression.
50 this accounts for the fact that packets are limited to 400 bytes
51 (which includes everything -- including the checksum), and assumes
52 the worst case of maximum length for each of the pieces of a
55 NOTE: expressions get mem2hex'ed otherwise this would be twice as
56 large. (400 - 31)/2 == 184 */
57 #define MAX_AGENT_EXPR_LEN 184
60 extern int info_verbose
;
61 extern void (*readline_begin_hook
) (char *, ...);
62 extern char *(*readline_hook
) (char *);
63 extern void (*readline_end_hook
) (void);
64 extern void x_command (char *, int);
65 extern int addressprint
; /* Print machine addresses? */
67 /* GDB commands implemented in other modules:
70 extern void output_command (char *, int);
71 extern void registers_info (char *, int);
72 extern void args_info (char *, int);
73 extern void locals_info (char *, int);
76 /* If this definition isn't overridden by the header files, assume
77 that isatty and fileno exist on this system. */
79 #define ISATTY(FP) (isatty (fileno (FP)))
85 This module defines the following debugger commands:
86 trace : set a tracepoint on a function, line, or address.
87 info trace : list all debugger-defined tracepoints.
88 delete trace : delete one or more tracepoints.
89 enable trace : enable one or more tracepoints.
90 disable trace : disable one or more tracepoints.
91 actions : specify actions to be taken at a tracepoint.
92 passcount : specify a pass count for a tracepoint.
93 tstart : start a trace experiment.
94 tstop : stop a trace experiment.
95 tstatus : query the status of a trace experiment.
96 tfind : find a trace frame in the trace buffer.
97 tdump : print everything collected at the current tracepoint.
98 save-tracepoints : write tracepoint setup into a file.
100 This module defines the following user-visible debugger variables:
101 $trace_frame : sequence number of trace frame currently being debugged.
102 $trace_line : source line of trace frame currently being debugged.
103 $trace_file : source file of trace frame currently being debugged.
104 $tracepoint : tracepoint number of trace frame currently being debugged.
108 /* ======= Important global variables: ======= */
110 /* Chain of all tracepoints defined. */
111 struct tracepoint
*tracepoint_chain
;
113 /* Number of last tracepoint made. */
114 static int tracepoint_count
;
116 /* Number of last traceframe collected. */
117 static int traceframe_number
;
119 /* Tracepoint for last traceframe collected. */
120 static int tracepoint_number
;
122 /* Symbol for function for last traceframe collected */
123 static struct symbol
*traceframe_fun
;
125 /* Symtab and line for last traceframe collected */
126 static struct symtab_and_line traceframe_sal
;
128 /* Tracing command lists */
129 static struct cmd_list_element
*tfindlist
;
131 /* ======= Important command functions: ======= */
132 static void trace_command (char *, int);
133 static void tracepoints_info (char *, int);
134 static void delete_trace_command (char *, int);
135 static void enable_trace_command (char *, int);
136 static void disable_trace_command (char *, int);
137 static void trace_pass_command (char *, int);
138 static void trace_actions_command (char *, int);
139 static void trace_start_command (char *, int);
140 static void trace_stop_command (char *, int);
141 static void trace_status_command (char *, int);
142 static void trace_find_command (char *, int);
143 static void trace_find_pc_command (char *, int);
144 static void trace_find_tracepoint_command (char *, int);
145 static void trace_find_line_command (char *, int);
146 static void trace_find_range_command (char *, int);
147 static void trace_find_outside_command (char *, int);
148 static void tracepoint_save_command (char *, int);
149 static void trace_dump_command (char *, int);
151 /* support routines */
152 static void trace_mention (struct tracepoint
*);
154 struct collection_list
;
155 static void add_aexpr (struct collection_list
*, struct agent_expr
*);
156 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
157 static void add_register (struct collection_list
*collection
,
159 static struct cleanup
*make_cleanup_free_actions (struct tracepoint
*t
);
160 static void free_actions_list (char **actions_list
);
161 static void free_actions_list_cleanup_wrapper (void *);
163 extern void _initialize_tracepoint (void);
165 /* Utility: returns true if "target remote" */
169 if (current_target
.to_shortname
&&
170 strcmp (current_target
.to_shortname
, "remote") == 0)
176 /* Utility: generate error from an incoming stub packet. */
182 return; /* not an error msg */
185 case '1': /* malformed packet error */
186 if (*++buf
== '0') /* general case: */
187 error ("tracepoint.c: error in outgoing packet.");
189 error ("tracepoint.c: error in outgoing packet at field #%d.",
190 strtol (buf
, NULL
, 16));
192 error ("trace API error 0x%s.", ++buf
);
194 error ("Target returns error code '%s'.", buf
);
198 /* Utility: wait for reply from stub, while accepting "O" packets */
200 remote_get_noisy_reply (char *buf
,
203 do /* loop on reply from remote stub */
205 QUIT
; /* allow user to bail out with ^C */
206 getpkt (buf
, sizeof_buf
, 0);
208 error ("Target does not support this command.");
209 else if (buf
[0] == 'E')
211 else if (buf
[0] == 'O' &&
213 remote_console_output (buf
+ 1); /* 'O' message from stub */
215 return buf
; /* here's the actual reply */
220 /* Set tracepoint count to NUM. */
222 set_tracepoint_count (num
)
225 tracepoint_count
= num
;
226 set_internalvar (lookup_internalvar ("tpnum"),
227 value_from_longest (builtin_type_int
, (LONGEST
) num
));
230 /* Set traceframe number to NUM. */
232 set_traceframe_num (num
)
235 traceframe_number
= num
;
236 set_internalvar (lookup_internalvar ("trace_frame"),
237 value_from_longest (builtin_type_int
, (LONGEST
) num
));
240 /* Set tracepoint number to NUM. */
242 set_tracepoint_num (num
)
245 tracepoint_number
= num
;
246 set_internalvar (lookup_internalvar ("tracepoint"),
247 value_from_longest (builtin_type_int
, (LONGEST
) num
));
250 /* Set externally visible debug variables for querying/printing
251 the traceframe context (line, function, file) */
254 set_traceframe_context (trace_pc
)
257 static struct type
*func_string
, *file_string
;
258 static struct type
*func_range
, *file_range
;
259 static value_ptr func_val
, file_val
;
260 static struct type
*charstar
;
263 if (charstar
== (struct type
*) NULL
)
264 charstar
= lookup_pointer_type (builtin_type_char
);
266 if (trace_pc
== -1) /* cease debugging any trace buffers */
269 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
270 traceframe_sal
.symtab
= NULL
;
271 set_internalvar (lookup_internalvar ("trace_func"),
272 value_from_pointer (charstar
, (LONGEST
) 0));
273 set_internalvar (lookup_internalvar ("trace_file"),
274 value_from_pointer (charstar
, (LONGEST
) 0));
275 set_internalvar (lookup_internalvar ("trace_line"),
276 value_from_pointer (builtin_type_int
, (LONGEST
) - 1));
280 /* save as globals for internal use */
281 traceframe_sal
= find_pc_line (trace_pc
, 0);
282 traceframe_fun
= find_pc_function (trace_pc
);
284 /* save linenumber as "$trace_line", a debugger variable visible to users */
285 set_internalvar (lookup_internalvar ("trace_line"),
286 value_from_longest (builtin_type_int
,
287 (LONGEST
) traceframe_sal
.line
));
289 /* save func name as "$trace_func", a debugger variable visible to users */
290 if (traceframe_fun
== NULL
||
291 SYMBOL_NAME (traceframe_fun
) == NULL
)
292 set_internalvar (lookup_internalvar ("trace_func"),
293 value_from_pointer (charstar
, (LONGEST
) 0));
296 len
= strlen (SYMBOL_NAME (traceframe_fun
));
297 func_range
= create_range_type (func_range
,
298 builtin_type_int
, 0, len
- 1);
299 func_string
= create_array_type (func_string
,
300 builtin_type_char
, func_range
);
301 func_val
= allocate_value (func_string
);
302 VALUE_TYPE (func_val
) = func_string
;
303 memcpy (VALUE_CONTENTS_RAW (func_val
),
304 SYMBOL_NAME (traceframe_fun
),
306 func_val
->modifiable
= 0;
307 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
310 /* save file name as "$trace_file", a debugger variable visible to users */
311 if (traceframe_sal
.symtab
== NULL
||
312 traceframe_sal
.symtab
->filename
== NULL
)
313 set_internalvar (lookup_internalvar ("trace_file"),
314 value_from_pointer (charstar
, (LONGEST
) 0));
317 len
= strlen (traceframe_sal
.symtab
->filename
);
318 file_range
= create_range_type (file_range
,
319 builtin_type_int
, 0, len
- 1);
320 file_string
= create_array_type (file_string
,
321 builtin_type_char
, file_range
);
322 file_val
= allocate_value (file_string
);
323 VALUE_TYPE (file_val
) = file_string
;
324 memcpy (VALUE_CONTENTS_RAW (file_val
),
325 traceframe_sal
.symtab
->filename
,
327 file_val
->modifiable
= 0;
328 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
332 /* Low level routine to set a tracepoint.
333 Returns the tracepoint object so caller can set other things.
334 Does not set the tracepoint number!
335 Does not print anything.
337 ==> This routine should not be called if there is a chance of later
338 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
339 your arguments BEFORE calling this routine! */
341 static struct tracepoint
*
342 set_raw_tracepoint (sal
)
343 struct symtab_and_line sal
;
345 register struct tracepoint
*t
, *tc
;
346 struct cleanup
*old_chain
;
348 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
349 old_chain
= make_cleanup (free
, t
);
350 memset (t
, 0, sizeof (*t
));
352 if (sal
.symtab
== NULL
)
353 t
->source_file
= NULL
;
355 t
->source_file
= savestring (sal
.symtab
->filename
,
356 strlen (sal
.symtab
->filename
));
358 t
->section
= sal
.section
;
359 t
->language
= current_language
->la_language
;
360 t
->input_radix
= input_radix
;
361 t
->line_number
= sal
.line
;
362 t
->enabled
= enabled
;
366 t
->addr_string
= NULL
;
368 /* Add this tracepoint to the end of the chain
369 so that a list of tracepoints will come out in order
370 of increasing numbers. */
372 tc
= tracepoint_chain
;
374 tracepoint_chain
= t
;
381 discard_cleanups (old_chain
);
385 /* Set a tracepoint according to ARG (function, linenum or *address) */
387 trace_command (arg
, from_tty
)
391 char **canonical
= (char **) NULL
;
392 struct symtabs_and_lines sals
;
393 struct symtab_and_line sal
;
394 struct tracepoint
*t
;
395 char *addr_start
= 0, *addr_end
= 0;
399 error ("trace command requires an argument");
401 if (from_tty
&& info_verbose
)
402 printf_filtered ("TRACE %s\n", arg
);
405 sals
= decode_line_1 (&arg
, 1, (struct symtab
*) NULL
, 0, &canonical
);
408 return; /* ??? Presumably decode_line_1 has already warned? */
410 /* Resolve all line numbers to PC's */
411 for (i
= 0; i
< sals
.nelts
; i
++)
412 resolve_sal_pc (&sals
.sals
[i
]);
414 /* Now set all the tracepoints. */
415 for (i
= 0; i
< sals
.nelts
; i
++)
419 t
= set_raw_tracepoint (sal
);
420 set_tracepoint_count (tracepoint_count
+ 1);
421 t
->number
= tracepoint_count
;
423 /* If a canonical line spec is needed use that instead of the
425 if (canonical
!= (char **) NULL
&& canonical
[i
] != NULL
)
426 t
->addr_string
= canonical
[i
];
428 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
432 /* Let the UI know of any additions */
433 if (create_tracepoint_hook
)
434 create_tracepoint_hook (t
);
439 printf_filtered ("Multiple tracepoints were set.\n");
440 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
444 /* Tell the user we have just set a tracepoint TP. */
448 struct tracepoint
*tp
;
450 printf_filtered ("Tracepoint %d", tp
->number
);
452 if (addressprint
|| (tp
->source_file
== NULL
))
454 printf_filtered (" at ");
455 print_address_numeric (tp
->address
, 1, gdb_stdout
);
458 printf_filtered (": file %s, line %d.",
459 tp
->source_file
, tp
->line_number
);
461 printf_filtered ("\n");
464 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
467 tracepoints_info (tpnum_exp
, from_tty
)
471 struct tracepoint
*t
;
472 struct action_line
*action
;
473 int found_a_tracepoint
= 0;
474 char wrap_indent
[80];
479 tpnum
= parse_and_eval_address (tpnum_exp
);
482 if (tpnum
== -1 || tpnum
== t
->number
)
484 extern int addressprint
; /* print machine addresses? */
486 if (!found_a_tracepoint
++)
488 printf_filtered ("Num Enb ");
490 printf_filtered ("Address ");
491 printf_filtered ("PassC StepC What\n");
493 strcpy (wrap_indent
, " ");
495 strcat (wrap_indent
, " ");
497 printf_filtered ("%-3d %-3s ", t
->number
,
498 t
->enabled
== enabled
? "y" : "n");
500 printf_filtered ("%s ",
501 local_hex_string_custom ((unsigned long) t
->address
,
503 printf_filtered ("%-5d %-5ld ", t
->pass_count
, t
->step_count
);
507 sym
= find_pc_sect_function (t
->address
, t
->section
);
510 fputs_filtered ("in ", gdb_stdout
);
511 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
512 wrap_here (wrap_indent
);
513 fputs_filtered (" at ", gdb_stdout
);
515 fputs_filtered (t
->source_file
, gdb_stdout
);
516 printf_filtered (":%d", t
->line_number
);
519 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
521 printf_filtered ("\n");
524 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
525 for (action
= t
->actions
; action
; action
= action
->next
)
527 printf_filtered ("\t%s\n", action
->action
);
531 if (!found_a_tracepoint
)
534 printf_filtered ("No tracepoints.\n");
536 printf_filtered ("No tracepoint number %d.\n", tpnum
);
540 /* Optimization: the code to parse an enable, disable, or delete TP command
541 is virtually identical except for whether it performs an enable, disable,
542 or delete. Therefore I've combined them into one function with an opcode.
544 enum tracepoint_opcode
551 /* This function implements enable, disable and delete commands. */
553 tracepoint_operation (t
, from_tty
, opcode
)
554 struct tracepoint
*t
;
556 enum tracepoint_opcode opcode
;
558 struct tracepoint
*t2
;
560 if (t
== NULL
) /* no tracepoint operand */
566 t
->enabled
= enabled
;
567 if (modify_tracepoint_hook
)
568 modify_tracepoint_hook (t
);
571 t
->enabled
= disabled
;
572 if (modify_tracepoint_hook
)
573 modify_tracepoint_hook (t
);
576 if (tracepoint_chain
== t
)
577 tracepoint_chain
= t
->next
;
586 /* Let the UI know of any deletions */
587 if (delete_tracepoint_hook
)
588 delete_tracepoint_hook (t
);
591 free (t
->addr_string
);
593 free (t
->source_file
);
602 /* Utility: parse a tracepoint number and look it up in the list.
603 If MULTI_P is true, there might be a range of tracepoints in ARG.
604 if OPTIONAL_P is true, then if the argument is missing, the most
605 recent tracepoint (tracepoint_count) is returned. */
607 get_tracepoint_by_number (arg
, multi_p
, optional_p
)
609 int multi_p
, optional_p
;
611 struct tracepoint
*t
;
613 char *instring
= arg
== NULL
? NULL
: *arg
;
615 if (arg
== NULL
|| *arg
== NULL
|| ! **arg
)
618 tpnum
= tracepoint_count
;
620 error_no_arg ("tracepoint number");
623 tpnum
= multi_p
? get_number_or_range (arg
) : get_number (arg
);
627 if (instring
&& *instring
)
628 printf_filtered ("bad tracepoint number at or near '%s'\n", instring
);
630 printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
635 if (t
->number
== tpnum
)
640 /* FIXME: if we are in the middle of a range we don't want to give
641 a message. The current interface to get_number_or_range doesn't
642 allow us to discover this. */
643 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
647 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
649 map_args_over_tracepoints (args
, from_tty
, opcode
)
652 enum tracepoint_opcode opcode
;
654 struct tracepoint
*t
, *tmp
;
656 if (args
== 0 || *args
== 0) /* do them all */
657 ALL_TRACEPOINTS_SAFE (t
, tmp
)
658 tracepoint_operation (t
, from_tty
, opcode
);
662 QUIT
; /* give user option to bail out with ^C */
663 t
= get_tracepoint_by_number (&args
, 1, 0);
664 tracepoint_operation (t
, from_tty
, opcode
);
665 while (*args
== ' ' || *args
== '\t')
670 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
672 enable_trace_command (args
, from_tty
)
677 map_args_over_tracepoints (args
, from_tty
, enable_op
);
680 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
682 disable_trace_command (args
, from_tty
)
687 map_args_over_tracepoints (args
, from_tty
, disable_op
);
690 /* Remove a tracepoint (or all if no argument) */
692 delete_trace_command (args
, from_tty
)
697 if (!args
|| !*args
) /* No args implies all tracepoints; */
698 if (from_tty
) /* confirm only if from_tty... */
699 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
700 if (!query ("Delete all tracepoints? "))
703 map_args_over_tracepoints (args
, from_tty
, delete_op
);
706 /* Set passcount for tracepoint.
708 First command argument is passcount, second is tracepoint number.
709 If tracepoint number omitted, apply to most recently defined.
710 Also accepts special argument "all". */
713 trace_pass_command (args
, from_tty
)
717 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
721 if (args
== 0 || *args
== 0)
722 error ("passcount command requires an argument (count + optional TP num)");
724 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
726 while (*args
&& isspace ((int) *args
))
729 if (*args
&& strncasecmp (args
, "all", 3) == 0)
731 args
+= 3; /* skip special argument "all" */
734 error ("Junk at end of arguments.");
737 t1
= get_tracepoint_by_number (&args
, 1, 1);
744 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
746 t2
->pass_count
= count
;
747 if (modify_tracepoint_hook
)
748 modify_tracepoint_hook (t2
);
750 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
754 t1
= get_tracepoint_by_number (&args
, 1, 0);
760 /* ACTIONS functions: */
762 /* Prototypes for action-parsing utility commands */
763 static void read_actions (struct tracepoint
*);
765 /* The three functions:
766 collect_pseudocommand,
767 while_stepping_pseudocommand, and
768 end_actions_pseudocommand
769 are placeholders for "commands" that are actually ONLY to be used
770 within a tracepoint action list. If the actual function is ever called,
771 it means that somebody issued the "command" at the top level,
772 which is always an error. */
775 end_actions_pseudocommand (args
, from_tty
)
779 error ("This command cannot be used at the top level.");
783 while_stepping_pseudocommand (args
, from_tty
)
787 error ("This command can only be used in a tracepoint actions list.");
791 collect_pseudocommand (args
, from_tty
)
795 error ("This command can only be used in a tracepoint actions list.");
798 /* Enter a list of actions for a tracepoint. */
800 trace_actions_command (args
, from_tty
)
804 struct tracepoint
*t
;
806 char *end_msg
= "End with a line saying just \"end\".";
808 t
= get_tracepoint_by_number (&args
, 0, 1);
811 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
816 if (readline_begin_hook
)
817 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
818 else if (input_from_terminal_p ())
819 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
823 t
->step_count
= 0; /* read_actions may set this */
826 if (readline_end_hook
)
827 (*readline_end_hook
) ();
828 /* tracepoints_changed () */
830 /* else just return */
833 /* worker function */
836 struct tracepoint
*t
;
839 char *prompt1
= "> ", *prompt2
= " > ";
840 char *prompt
= prompt1
;
841 enum actionline_type linetype
;
842 extern FILE *instream
;
843 struct action_line
*next
= NULL
, *temp
;
844 struct cleanup
*old_chain
;
846 /* Control-C quits instantly if typed while in this loop
847 since it should not wait until the user types a newline. */
853 signal (STOP_SIGNAL
, handle_stop_sig
);
855 signal (STOP_SIGNAL
, stop_sig
);
858 old_chain
= make_cleanup_free_actions (t
);
861 /* Make sure that all output has been output. Some machines may let
862 you get away with leaving out some of the gdb_flush, but not all. */
864 gdb_flush (gdb_stdout
);
865 gdb_flush (gdb_stderr
);
867 if (readline_hook
&& instream
== NULL
)
868 line
= (*readline_hook
) (prompt
);
869 else if (instream
== stdin
&& ISATTY (instream
))
871 line
= readline (prompt
);
872 if (line
&& *line
) /* add it to command history */
876 line
= gdb_readline (0);
878 linetype
= validate_actionline (&line
, t
);
879 if (linetype
== BADLINE
)
880 continue; /* already warned -- collect another line */
882 temp
= xmalloc (sizeof (struct action_line
));
886 if (next
== NULL
) /* first action for this tracepoint? */
887 t
->actions
= next
= temp
;
894 if (linetype
== STEPPING
) /* begin "while-stepping" */
896 if (prompt
== prompt2
)
898 warning ("Already processing 'while-stepping'");
902 prompt
= prompt2
; /* change prompt for stepping actions */
904 else if (linetype
== END
)
906 if (prompt
== prompt2
)
908 prompt
= prompt1
; /* end of single-stepping actions */
911 { /* end of actions */
912 if (t
->actions
->next
== NULL
)
914 /* an "end" all by itself with no other actions means
915 this tracepoint has no actions. Discard empty list. */
924 signal (STOP_SIGNAL
, SIG_DFL
);
927 discard_cleanups (old_chain
);
930 /* worker function */
932 validate_actionline (line
, t
)
934 struct tracepoint
*t
;
936 struct cmd_list_element
*c
;
937 struct expression
*exp
= NULL
;
938 struct cleanup
*old_chain
= NULL
;
941 for (p
= *line
; isspace ((int) *p
);)
944 /* symbol lookup etc. */
945 if (*p
== '\0') /* empty line: just prompt for another line. */
948 if (*p
== '#') /* comment line */
951 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
954 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
958 if (c
->function
.cfunc
== collect_pseudocommand
)
960 struct agent_expr
*aexpr
;
961 struct agent_reqs areqs
;
964 { /* repeat over a comma-separated list */
965 QUIT
; /* allow user to bail out with ^C */
966 while (isspace ((int) *p
))
969 if (*p
== '$') /* look for special pseudo-symbols */
971 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
972 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
973 (0 == strncasecmp ("loc", p
+ 1, 3)))
978 /* else fall thru, treat p as an expression and parse it! */
980 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
981 old_chain
= make_cleanup (free_current_contents
, &exp
);
983 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
985 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
987 warning ("constant %s (value %ld) will not be collected.",
988 SYMBOL_NAME (exp
->elts
[2].symbol
),
989 SYMBOL_VALUE (exp
->elts
[2].symbol
));
992 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
994 warning ("%s is optimized away and cannot be collected.",
995 SYMBOL_NAME (exp
->elts
[2].symbol
));
1000 /* we have something to collect, make sure that the expr to
1001 bytecode translator can handle it and that it's not too long */
1002 aexpr
= gen_trace_for_expr (t
->address
, exp
);
1003 make_cleanup_free_agent_expr (aexpr
);
1005 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
1006 error ("expression too complicated, try simplifying");
1008 ax_reqs (aexpr
, &areqs
);
1009 (void) make_cleanup (free
, areqs
.reg_mask
);
1011 if (areqs
.flaw
!= agent_flaw_none
)
1012 error ("malformed expression");
1014 if (areqs
.min_height
< 0)
1015 error ("gdb: Internal error: expression has min height < 0");
1017 if (areqs
.max_height
> 20)
1018 error ("expression too complicated, try simplifying");
1020 do_cleanups (old_chain
);
1022 while (p
&& *p
++ == ',');
1025 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
1027 char *steparg
; /* in case warning is necessary */
1029 while (isspace ((int) *p
))
1034 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1036 warning ("'%s': bad step-count; command ignored.", *line
);
1041 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1045 warning ("'%s' is not a supported tracepoint action.", *line
);
1050 /* worker function */
1053 struct tracepoint
*t
;
1055 struct action_line
*line
, *next
;
1057 for (line
= t
->actions
; line
; line
= next
)
1061 free (line
->action
);
1068 do_free_actions_cleanup (void *t
)
1073 static struct cleanup
*
1074 make_cleanup_free_actions (struct tracepoint
*t
)
1076 return make_cleanup (do_free_actions_cleanup
, t
);
1081 int type
; /* 0 for absolute memory range, else basereg number */
1082 bfd_signed_vma start
;
1086 struct collection_list
1088 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1091 struct memrange
*list
;
1092 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1093 long next_aexpr_elt
;
1094 struct agent_expr
**aexpr_list
;
1097 tracepoint_list
, stepping_list
;
1099 /* MEMRANGE functions: */
1101 static int memrange_cmp (const void *, const void *);
1103 /* compare memranges for qsort */
1105 memrange_cmp (va
, vb
)
1109 const struct memrange
*a
= va
, *b
= vb
;
1111 if (a
->type
< b
->type
)
1113 if (a
->type
> b
->type
)
1117 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
)
1119 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
)
1124 if (a
->start
< b
->start
)
1126 if (a
->start
> b
->start
)
1132 /* Sort the memrange list using qsort, and merge adjacent memranges */
1134 memrange_sortmerge (memranges
)
1135 struct collection_list
*memranges
;
1139 qsort (memranges
->list
, memranges
->next_memrange
,
1140 sizeof (struct memrange
), memrange_cmp
);
1141 if (memranges
->next_memrange
> 0)
1143 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1145 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1146 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1147 MAX_REGISTER_VIRTUAL_SIZE
)
1149 /* memrange b starts before memrange a ends; merge them. */
1150 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1151 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1152 continue; /* next b, same a */
1156 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1157 sizeof (struct memrange
));
1159 memranges
->next_memrange
= a
+ 1;
1163 /* Add a register to a collection list */
1165 add_register (collection
, regno
)
1166 struct collection_list
*collection
;
1170 printf_filtered ("collect register %d\n", regno
);
1171 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1172 error ("Internal: register number %d too large for tracepoint",
1174 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1177 /* Add a memrange to a collection list */
1179 add_memrange (memranges
, type
, base
, len
)
1180 struct collection_list
*memranges
;
1182 bfd_signed_vma base
;
1187 printf_filtered ("(%d,", type
);
1189 printf_filtered (",%ld)\n", len
);
1192 /* type: 0 == memory, n == basereg */
1193 memranges
->list
[memranges
->next_memrange
].type
= type
;
1194 /* base: addr if memory, offset if reg relative. */
1195 memranges
->list
[memranges
->next_memrange
].start
= base
;
1196 /* len: we actually save end (base + len) for convenience */
1197 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1198 memranges
->next_memrange
++;
1199 if (memranges
->next_memrange
>= memranges
->listsize
)
1201 memranges
->listsize
*= 2;
1202 memranges
->list
= xrealloc (memranges
->list
,
1203 memranges
->listsize
);
1206 if (type
!= -1) /* better collect the base register! */
1207 add_register (memranges
, type
);
1210 /* Add a symbol to a collection list */
1212 collect_symbol (collect
, sym
, frame_regno
, frame_offset
)
1213 struct collection_list
*collect
;
1220 bfd_signed_vma offset
;
1222 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1223 switch (SYMBOL_CLASS (sym
))
1226 printf_filtered ("%s: don't know symbol class %d\n",
1227 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1230 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1231 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1234 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1239 sprintf_vma (tmp
, offset
);
1240 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1241 SYMBOL_NAME (sym
), len
, tmp
/* address */);
1243 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1247 reg
= SYMBOL_VALUE (sym
);
1249 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1250 add_register (collect
, reg
);
1251 /* check for doubles stored in two registers */
1252 /* FIXME: how about larger types stored in 3 or more regs? */
1253 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1254 len
> REGISTER_RAW_SIZE (reg
))
1255 add_register (collect
, reg
+ 1);
1258 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1259 printf_filtered (" (will not collect %s)\n",
1264 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1267 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1268 SYMBOL_NAME (sym
), len
);
1269 printf_vma (offset
);
1270 printf_filtered (" from frame ptr reg %d\n", reg
);
1272 add_memrange (collect
, reg
, offset
, len
);
1274 case LOC_REGPARM_ADDR
:
1275 reg
= SYMBOL_VALUE (sym
);
1279 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1280 SYMBOL_NAME (sym
), len
);
1281 printf_vma (offset
);
1282 printf_filtered (" from reg %d\n", reg
);
1284 add_memrange (collect
, reg
, offset
, len
);
1289 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1292 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1293 SYMBOL_NAME (sym
), len
);
1294 printf_vma (offset
);
1295 printf_filtered (" from frame ptr reg %d\n", reg
);
1297 add_memrange (collect
, reg
, offset
, len
);
1300 case LOC_BASEREG_ARG
:
1301 reg
= SYMBOL_BASEREG (sym
);
1302 offset
= SYMBOL_VALUE (sym
);
1305 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1306 SYMBOL_NAME (sym
), len
);
1307 printf_vma (offset
);
1308 printf_filtered (" from basereg %d\n", reg
);
1310 add_memrange (collect
, reg
, offset
, len
);
1312 case LOC_UNRESOLVED
:
1313 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1315 case LOC_OPTIMIZED_OUT
:
1316 printf_filtered ("%s has been optimized out of existance.\n",
1322 /* Add all locals (or args) symbols to collection list */
1324 add_local_symbols (collect
, pc
, frame_regno
, frame_offset
, type
)
1325 struct collection_list
*collect
;
1332 struct block
*block
;
1333 int i
, nsyms
, count
= 0;
1335 block
= block_for_pc (pc
);
1338 QUIT
; /* allow user to bail out with ^C */
1339 nsyms
= BLOCK_NSYMS (block
);
1340 for (i
= 0; i
< nsyms
; i
++)
1342 sym
= BLOCK_SYM (block
, i
);
1343 switch (SYMBOL_CLASS (sym
))
1346 warning ("don't know how to trace local symbol %s",
1352 if (type
== 'L') /* collecting Locals */
1355 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1362 case LOC_REGPARM_ADDR
:
1363 case LOC_BASEREG_ARG
:
1364 if (type
== 'A') /* collecting Arguments */
1367 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1371 if (BLOCK_FUNCTION (block
))
1374 block
= BLOCK_SUPERBLOCK (block
);
1377 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1380 /* worker function */
1382 clear_collection_list (list
)
1383 struct collection_list
*list
;
1387 list
->next_memrange
= 0;
1388 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1390 free_agent_expr (list
->aexpr_list
[ndx
]);
1391 list
->aexpr_list
[ndx
] = NULL
;
1393 list
->next_aexpr_elt
= 0;
1394 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1397 /* reduce a collection list to string form (for gdb protocol) */
1399 stringify_collection_list (list
, string
)
1400 struct collection_list
*list
;
1403 char temp_buf
[2048];
1407 char *(*str_list
)[];
1411 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1412 str_list
= (char *(*)[]) xmalloc (count
* sizeof (char *));
1414 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1415 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1417 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1420 printf_filtered ("\nCollecting registers (mask): 0x");
1425 QUIT
; /* allow user to bail out with ^C */
1427 printf_filtered ("%02X", list
->regs_mask
[i
]);
1428 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1431 (*str_list
)[ndx
] = savestring (temp_buf
, end
- temp_buf
);
1435 printf_filtered ("\n");
1436 if (list
->next_memrange
> 0 && info_verbose
)
1437 printf_filtered ("Collecting memranges: \n");
1438 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1440 QUIT
; /* allow user to bail out with ^C */
1441 sprintf_vma (tmp2
, list
->list
[i
].start
);
1444 printf_filtered ("(%d, %s, %ld)\n",
1447 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1449 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1451 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1457 sprintf (end
, "M%X,%s,%lX",
1460 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1462 count
+= strlen (end
);
1466 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1468 QUIT
; /* allow user to bail out with ^C */
1469 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1471 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1476 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1477 end
+= 10; /* 'X' + 8 hex digits + ',' */
1480 end
= mem2hex (list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1481 count
+= 2 * list
->aexpr_list
[i
]->len
;
1486 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1491 (*str_list
)[ndx
] = NULL
;
1500 free_actions_list_cleanup_wrapper (al
)
1503 free_actions_list (al
);
1507 free_actions_list (actions_list
)
1508 char **actions_list
;
1512 if (actions_list
== 0)
1515 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1516 free (actions_list
[ndx
]);
1518 free (actions_list
);
1521 /* render all actions into gdb protocol */
1523 encode_actions (t
, tdp_actions
, stepping_actions
)
1524 struct tracepoint
*t
;
1525 char ***tdp_actions
;
1526 char ***stepping_actions
;
1528 static char tdp_buff
[2048], step_buff
[2048];
1530 struct expression
*exp
= NULL
;
1531 struct action_line
*action
;
1534 struct collection_list
*collect
;
1535 struct cmd_list_element
*cmd
;
1536 struct agent_expr
*aexpr
;
1537 long frame_reg
, frame_offset
;
1540 clear_collection_list (&tracepoint_list
);
1541 clear_collection_list (&stepping_list
);
1542 collect
= &tracepoint_list
;
1544 *tdp_actions
= NULL
;
1545 *stepping_actions
= NULL
;
1547 TARGET_VIRTUAL_FRAME_POINTER (t
->address
, &frame_reg
, &frame_offset
);
1549 for (action
= t
->actions
; action
; action
= action
->next
)
1551 QUIT
; /* allow user to bail out with ^C */
1552 action_exp
= action
->action
;
1553 while (isspace ((int) *action_exp
))
1556 if (*action_exp
== '#') /* comment line */
1559 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1561 error ("Bad action list item: %s", action_exp
);
1563 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1566 { /* repeat over a comma-separated list */
1567 QUIT
; /* allow user to bail out with ^C */
1568 while (isspace ((int) *action_exp
))
1571 if (0 == strncasecmp ("$reg", action_exp
, 4))
1573 for (i
= 0; i
< NUM_REGS
; i
++)
1574 add_register (collect
, i
);
1575 action_exp
= strchr (action_exp
, ','); /* more? */
1577 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1579 add_local_symbols (collect
,
1584 action_exp
= strchr (action_exp
, ','); /* more? */
1586 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1588 add_local_symbols (collect
,
1593 action_exp
= strchr (action_exp
, ','); /* more? */
1597 unsigned long addr
, len
;
1598 struct cleanup
*old_chain
= NULL
;
1599 struct cleanup
*old_chain1
= NULL
;
1600 struct agent_reqs areqs
;
1602 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1603 old_chain
= make_cleanup (free_current_contents
, &exp
);
1605 switch (exp
->elts
[0].opcode
)
1608 i
= exp
->elts
[1].longconst
;
1610 printf_filtered ("OP_REGISTER: ");
1611 add_register (collect
, i
);
1615 /* safe because we know it's a simple expression */
1616 tempval
= evaluate_expression (exp
);
1617 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1618 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1619 add_memrange (collect
, -1, addr
, len
);
1623 collect_symbol (collect
,
1624 exp
->elts
[2].symbol
,
1629 default: /* full-fledged expression */
1630 aexpr
= gen_trace_for_expr (t
->address
, exp
);
1632 old_chain1
= make_cleanup_free_agent_expr (aexpr
);
1634 ax_reqs (aexpr
, &areqs
);
1635 if (areqs
.flaw
!= agent_flaw_none
)
1636 error ("malformed expression");
1638 if (areqs
.min_height
< 0)
1639 error ("gdb: Internal error: expression has min height < 0");
1640 if (areqs
.max_height
> 20)
1641 error ("expression too complicated, try simplifying");
1643 discard_cleanups (old_chain1
);
1644 add_aexpr (collect
, aexpr
);
1646 /* take care of the registers */
1647 if (areqs
.reg_mask_len
> 0)
1652 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1654 QUIT
; /* allow user to bail out with ^C */
1655 if (areqs
.reg_mask
[ndx1
] != 0)
1657 /* assume chars have 8 bits */
1658 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1659 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1660 /* it's used -- record it */
1661 add_register (collect
, ndx1
* 8 + ndx2
);
1667 do_cleanups (old_chain
);
1670 while (action_exp
&& *action_exp
++ == ',');
1672 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1674 collect
= &stepping_list
;
1676 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1678 if (collect
== &stepping_list
) /* end stepping actions */
1679 collect
= &tracepoint_list
;
1681 break; /* end tracepoint actions */
1684 memrange_sortmerge (&tracepoint_list
);
1685 memrange_sortmerge (&stepping_list
);
1687 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1688 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1692 add_aexpr (collect
, aexpr
)
1693 struct collection_list
*collect
;
1694 struct agent_expr
*aexpr
;
1696 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1698 collect
->aexpr_list
=
1699 xrealloc (collect
->aexpr_list
,
1700 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1701 collect
->aexpr_listsize
*= 2;
1703 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1704 collect
->next_aexpr_elt
++;
1707 static char target_buf
[2048];
1709 /* Set "transparent" memory ranges
1711 Allow trace mechanism to treat text-like sections
1712 (and perhaps all read-only sections) transparently,
1713 i.e. don't reject memory requests from these address ranges
1714 just because they haven't been collected. */
1717 remote_set_transparent_ranges (void)
1719 extern bfd
*exec_bfd
;
1726 return; /* no information to give. */
1728 strcpy (target_buf
, "QTro");
1729 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1731 char tmp1
[40], tmp2
[40];
1733 if ((s
->flags
& SEC_LOAD
) == 0 ||
1734 /* (s->flags & SEC_CODE) == 0 || */
1735 (s
->flags
& SEC_READONLY
) == 0)
1740 size
= bfd_get_section_size_before_reloc (s
);
1741 sprintf_vma (tmp1
, lma
);
1742 sprintf_vma (tmp2
, lma
+ size
);
1743 sprintf (target_buf
+ strlen (target_buf
),
1744 ":%s,%s", tmp1
, tmp2
);
1748 putpkt (target_buf
);
1749 getpkt (target_buf
, sizeof (target_buf
), 0);
1755 Tell target to clear any previous trace experiment.
1756 Walk the list of tracepoints, and send them (and their actions)
1757 to the target. If no errors,
1758 Tell target to start a new trace experiment. */
1761 trace_start_command (args
, from_tty
)
1764 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1765 struct tracepoint
*t
;
1768 char **stepping_actions
;
1770 struct cleanup
*old_chain
= NULL
;
1772 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1774 if (target_is_remote ())
1777 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1778 if (strcmp (target_buf
, "OK"))
1779 error ("Target does not support this command.");
1785 sprintf_vma (tmp
, t
->address
);
1786 sprintf (buf
, "QTDP:%x:%s:%c:%lx:%x", t
->number
, tmp
, /* address */
1787 t
->enabled
== enabled
? 'E' : 'D',
1788 t
->step_count
, t
->pass_count
);
1793 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1794 if (strcmp (target_buf
, "OK"))
1795 error ("Target does not support tracepoints.");
1799 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1800 old_chain
= make_cleanup (free_actions_list_cleanup_wrapper
,
1802 (void) make_cleanup (free_actions_list_cleanup_wrapper
,
1805 /* do_single_steps (t); */
1808 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1810 QUIT
; /* allow user to bail out with ^C */
1811 sprintf (buf
, "QTDP:-%x:%s:%s%c",
1812 t
->number
, tmp
, /* address */
1814 ((tdp_actions
[ndx
+ 1] || stepping_actions
)
1817 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1818 if (strcmp (target_buf
, "OK"))
1819 error ("Error on target while setting tracepoints.");
1822 if (stepping_actions
)
1824 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1826 QUIT
; /* allow user to bail out with ^C */
1827 sprintf (buf
, "QTDP:-%x:%s:%s%s%s",
1828 t
->number
, tmp
, /* address */
1829 ((ndx
== 0) ? "S" : ""),
1830 stepping_actions
[ndx
],
1831 (stepping_actions
[ndx
+ 1] ? "-" : ""));
1833 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1834 if (strcmp (target_buf
, "OK"))
1835 error ("Error on target while setting tracepoints.");
1839 do_cleanups (old_chain
);
1842 /* Tell target to treat text-like sections as transparent */
1843 remote_set_transparent_ranges ();
1844 /* Now insert traps and begin collecting data */
1846 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1847 if (strcmp (target_buf
, "OK"))
1848 error ("Bogus reply from target: %s", target_buf
);
1849 set_traceframe_num (-1); /* all old traceframes invalidated */
1850 set_tracepoint_num (-1);
1851 set_traceframe_context (-1);
1852 trace_running_p
= 1;
1853 if (trace_start_stop_hook
)
1854 trace_start_stop_hook (1, from_tty
);
1858 error ("Trace can only be run on remote targets.");
1863 trace_stop_command (args
, from_tty
)
1866 { /* STUB_COMM IS_IMPLEMENTED */
1867 if (target_is_remote ())
1870 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1871 if (strcmp (target_buf
, "OK"))
1872 error ("Bogus reply from target: %s", target_buf
);
1873 trace_running_p
= 0;
1874 if (trace_start_stop_hook
)
1875 trace_start_stop_hook (0, from_tty
);
1878 error ("Trace can only be run on remote targets.");
1881 unsigned long trace_running_p
;
1883 /* tstatus command */
1885 trace_status_command (args
, from_tty
)
1888 { /* STUB_COMM IS_IMPLEMENTED */
1889 if (target_is_remote ())
1891 putpkt ("qTStatus");
1892 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1894 if (target_buf
[0] != 'T' ||
1895 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1896 error ("Bogus reply from target: %s", target_buf
);
1898 /* exported for use by the GUI */
1899 trace_running_p
= (target_buf
[1] == '1');
1902 error ("Trace can only be run on remote targets.");
1905 /* Worker function for the various flavors of the tfind command */
1907 finish_tfind_command (char *msg
,
1911 int target_frameno
= -1, target_tracept
= -1;
1912 CORE_ADDR old_frame_addr
;
1913 struct symbol
*old_func
;
1916 old_frame_addr
= FRAME_FP (get_current_frame ());
1917 old_func
= find_pc_function (read_pc ());
1920 reply
= remote_get_noisy_reply (msg
, sizeof_msg
);
1922 while (reply
&& *reply
)
1926 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1928 /* A request for a non-existant trace frame has failed.
1929 Our response will be different, depending on FROM_TTY:
1931 If FROM_TTY is true, meaning that this command was
1932 typed interactively by the user, then give an error
1933 and DO NOT change the state of traceframe_number etc.
1935 However if FROM_TTY is false, meaning that we're either
1936 in a script, a loop, or a user-defined command, then
1937 DON'T give an error, but DO change the state of
1938 traceframe_number etc. to invalid.
1940 The rationalle is that if you typed the command, you
1941 might just have committed a typo or something, and you'd
1942 like to NOT lose your current debugging state. However
1943 if you're in a user-defined command or especially in a
1944 loop, then you need a way to detect that the command
1945 failed WITHOUT aborting. This allows you to write
1946 scripts that search thru the trace buffer until the end,
1947 and then continue on to do something else. */
1950 error ("Target failed to find requested trace frame.");
1954 printf_filtered ("End of trace buffer.\n");
1955 /* The following will not recurse, since it's special-cased */
1956 trace_find_command ("-1", from_tty
);
1957 reply
= NULL
; /* break out of loop,
1958 (avoid recursive nonsense) */
1963 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1964 error ("Target failed to find requested trace frame.");
1966 case 'O': /* "OK"? */
1967 if (reply
[1] == 'K' && reply
[2] == '\0')
1970 error ("Bogus reply from target: %s", reply
);
1973 error ("Bogus reply from target: %s", reply
);
1976 flush_cached_frames ();
1977 registers_changed ();
1978 select_frame (get_current_frame (), 0);
1979 set_traceframe_num (target_frameno
);
1980 set_tracepoint_num (target_tracept
);
1981 if (target_frameno
== -1)
1982 set_traceframe_context (-1);
1984 set_traceframe_context (read_pc ());
1990 /* NOTE: in immitation of the step command, try to determine
1991 whether we have made a transition from one function to another.
1992 If so, we'll print the "stack frame" (ie. the new function and
1993 it's arguments) -- otherwise we'll just show the new source line.
1995 This determination is made by checking (1) whether the current
1996 function has changed, and (2) whether the current FP has changed.
1997 Hack: if the FP wasn't collected, either at the current or the
1998 previous frame, assume that the FP has NOT changed. */
2000 if (old_func
== find_pc_function (read_pc ()) &&
2001 (old_frame_addr
== 0 ||
2002 FRAME_FP (get_current_frame ()) == 0 ||
2003 old_frame_addr
== FRAME_FP (get_current_frame ())))
2008 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
2013 /* trace_find_command takes a trace frame number n,
2014 sends "QTFrame:<n>" to the target,
2015 and accepts a reply that may contain several optional pieces
2016 of information: a frame number, a tracepoint number, and an
2017 indication of whether this is a trap frame or a stepping frame.
2019 The minimal response is just "OK" (which indicates that the
2020 target does not give us a frame number or a tracepoint number).
2021 Instead of that, the target may send us a string containing
2023 F<hexnum> (gives the selected frame number)
2024 T<hexnum> (gives the selected tracepoint number)
2029 trace_find_command (args
, from_tty
)
2032 { /* STUB_COMM PART_IMPLEMENTED */
2033 /* this should only be called with a numeric argument */
2036 if (target_is_remote ())
2038 if (trace_find_hook
)
2039 trace_find_hook (args
, from_tty
);
2041 if (args
== 0 || *args
== 0)
2042 { /* TFIND with no args means find NEXT trace frame. */
2043 if (traceframe_number
== -1)
2044 frameno
= 0; /* "next" is first one */
2046 frameno
= traceframe_number
+ 1;
2048 else if (0 == strcmp (args
, "-"))
2050 if (traceframe_number
== -1)
2051 error ("not debugging trace buffer");
2052 else if (from_tty
&& traceframe_number
== 0)
2053 error ("already at start of trace buffer");
2055 frameno
= traceframe_number
- 1;
2058 frameno
= parse_and_eval_address (args
);
2061 error ("invalid input (%d is less than zero)", frameno
);
2063 sprintf (target_buf
, "QTFrame:%x", frameno
);
2064 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2067 error ("Trace can only be run on remote targets.");
2072 trace_find_end_command (args
, from_tty
)
2076 trace_find_command ("-1", from_tty
);
2081 trace_find_none_command (args
, from_tty
)
2085 trace_find_command ("-1", from_tty
);
2090 trace_find_start_command (args
, from_tty
)
2094 trace_find_command ("0", from_tty
);
2097 /* tfind pc command */
2099 trace_find_pc_command (args
, from_tty
)
2102 { /* STUB_COMM PART_IMPLEMENTED */
2106 if (target_is_remote ())
2108 if (args
== 0 || *args
== 0)
2109 pc
= read_pc (); /* default is current pc */
2111 pc
= parse_and_eval_address (args
);
2113 sprintf_vma (tmp
, pc
);
2114 sprintf (target_buf
, "QTFrame:pc:%s", tmp
);
2115 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2118 error ("Trace can only be run on remote targets.");
2121 /* tfind tracepoint command */
2123 trace_find_tracepoint_command (args
, from_tty
)
2126 { /* STUB_COMM PART_IMPLEMENTED */
2129 if (target_is_remote ())
2131 if (args
== 0 || *args
== 0)
2132 if (tracepoint_number
== -1)
2133 error ("No current tracepoint -- please supply an argument.");
2135 tdp
= tracepoint_number
; /* default is current TDP */
2137 tdp
= parse_and_eval_address (args
);
2139 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2140 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2143 error ("Trace can only be run on remote targets.");
2146 /* TFIND LINE command:
2148 This command will take a sourceline for argument, just like BREAK
2149 or TRACE (ie. anything that "decode_line_1" can handle).
2151 With no argument, this command will find the next trace frame
2152 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2155 trace_find_line_command (args
, from_tty
)
2158 { /* STUB_COMM PART_IMPLEMENTED */
2159 static CORE_ADDR start_pc
, end_pc
;
2160 struct symtabs_and_lines sals
;
2161 struct symtab_and_line sal
;
2162 struct cleanup
*old_chain
;
2163 char startpc_str
[40], endpc_str
[40];
2165 if (target_is_remote ())
2167 if (args
== 0 || *args
== 0)
2169 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2171 sals
.sals
= (struct symtab_and_line
*)
2172 xmalloc (sizeof (struct symtab_and_line
));
2177 sals
= decode_line_spec (args
, 1);
2181 old_chain
= make_cleanup (free
, sals
.sals
);
2182 if (sal
.symtab
== 0)
2184 printf_filtered ("TFIND: No line number information available");
2187 /* This is useful for "info line *0x7f34". If we can't tell the
2188 user about a source line, at least let them have the symbolic
2190 printf_filtered (" for address ");
2192 print_address (sal
.pc
, gdb_stdout
);
2193 printf_filtered (";\n -- will attempt to find by PC. \n");
2197 printf_filtered (".\n");
2198 return; /* no line, no PC; what can we do? */
2201 else if (sal
.line
> 0
2202 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2204 if (start_pc
== end_pc
)
2206 printf_filtered ("Line %d of \"%s\"",
2207 sal
.line
, sal
.symtab
->filename
);
2209 printf_filtered (" is at address ");
2210 print_address (start_pc
, gdb_stdout
);
2212 printf_filtered (" but contains no code.\n");
2213 sal
= find_pc_line (start_pc
, 0);
2215 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2217 printf_filtered ("Attempting to find line %d instead.\n",
2220 error ("Cannot find a good line.");
2224 /* Is there any case in which we get here, and have an address
2225 which the user would want to see? If we have debugging symbols
2226 and no line numbers? */
2227 error ("Line number %d is out of range for \"%s\".\n",
2228 sal
.line
, sal
.symtab
->filename
);
2230 sprintf_vma (startpc_str
, start_pc
);
2231 sprintf_vma (endpc_str
, end_pc
- 1);
2232 if (args
&& *args
) /* find within range of stated line */
2233 sprintf (target_buf
, "QTFrame:range:%s:%s", startpc_str
, endpc_str
);
2234 else /* find OUTSIDE OF range of CURRENT line */
2235 sprintf (target_buf
, "QTFrame:outside:%s:%s", startpc_str
, endpc_str
);
2236 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2237 do_cleanups (old_chain
);
2240 error ("Trace can only be run on remote targets.");
2243 /* tfind range command */
2245 trace_find_range_command (args
, from_tty
)
2249 static CORE_ADDR start
, stop
;
2250 char start_str
[40], stop_str
[40];
2253 if (target_is_remote ())
2255 if (args
== 0 || *args
== 0)
2256 { /* XXX FIXME: what should default behavior be? */
2257 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2261 if (0 != (tmp
= strchr (args
, ',')))
2263 *tmp
++ = '\0'; /* terminate start address */
2264 while (isspace ((int) *tmp
))
2266 start
= parse_and_eval_address (args
);
2267 stop
= parse_and_eval_address (tmp
);
2270 { /* no explicit end address? */
2271 start
= parse_and_eval_address (args
);
2272 stop
= start
+ 1; /* ??? */
2275 sprintf_vma (start_str
, start
);
2276 sprintf_vma (stop_str
, stop
);
2277 sprintf (target_buf
, "QTFrame:range:%s:%s", start_str
, stop_str
);
2278 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2281 error ("Trace can only be run on remote targets.");
2284 /* tfind outside command */
2286 trace_find_outside_command (args
, from_tty
)
2290 CORE_ADDR start
, stop
;
2291 char start_str
[40], stop_str
[40];
2294 if (target_is_remote ())
2296 if (args
== 0 || *args
== 0)
2297 { /* XXX FIXME: what should default behavior be? */
2298 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2302 if (0 != (tmp
= strchr (args
, ',')))
2304 *tmp
++ = '\0'; /* terminate start address */
2305 while (isspace ((int) *tmp
))
2307 start
= parse_and_eval_address (args
);
2308 stop
= parse_and_eval_address (tmp
);
2311 { /* no explicit end address? */
2312 start
= parse_and_eval_address (args
);
2313 stop
= start
+ 1; /* ??? */
2316 sprintf_vma (start_str
, start
);
2317 sprintf_vma (stop_str
, stop
);
2318 sprintf (target_buf
, "QTFrame:outside:%s:%s", start_str
, stop_str
);
2319 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2322 error ("Trace can only be run on remote targets.");
2325 /* save-tracepoints command */
2327 tracepoint_save_command (args
, from_tty
)
2331 struct tracepoint
*tp
;
2332 struct action_line
*line
;
2334 char *i1
= " ", *i2
= " ";
2335 char *indent
, *actionline
;
2338 if (args
== 0 || *args
== 0)
2339 error ("Argument required (file name in which to save tracepoints");
2341 if (tracepoint_chain
== 0)
2343 warning ("save-tracepoints: no tracepoints to save.\n");
2347 if (!(fp
= fopen (args
, "w")))
2348 error ("Unable to open file '%s' for saving tracepoints");
2350 ALL_TRACEPOINTS (tp
)
2352 if (tp
->addr_string
)
2353 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2356 sprintf_vma (tmp
, tp
->address
);
2357 fprintf (fp
, "trace *0x%s\n", tmp
);
2361 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2365 fprintf (fp
, " actions\n");
2367 for (line
= tp
->actions
; line
; line
= line
->next
)
2369 struct cmd_list_element
*cmd
;
2371 QUIT
; /* allow user to bail out with ^C */
2372 actionline
= line
->action
;
2373 while (isspace ((int) *actionline
))
2376 fprintf (fp
, "%s%s\n", indent
, actionline
);
2377 if (*actionline
!= '#') /* skip for comment lines */
2379 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2381 error ("Bad action list item: %s", actionline
);
2382 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2384 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2392 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2396 /* info scope command: list the locals for a scope. */
2398 scope_info (args
, from_tty
)
2402 struct symtabs_and_lines sals
;
2404 struct minimal_symbol
*msym
;
2405 struct block
*block
;
2406 char **canonical
, *symname
, *save_args
= args
;
2407 int i
, j
, nsyms
, count
= 0;
2409 if (args
== 0 || *args
== 0)
2410 error ("requires an argument (function, line or *addr) to define a scope");
2412 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2413 if (sals
.nelts
== 0)
2414 return; /* presumably decode_line_1 has already warned */
2416 /* Resolve line numbers to PC */
2417 resolve_sal_pc (&sals
.sals
[0]);
2418 block
= block_for_pc (sals
.sals
[0].pc
);
2422 QUIT
; /* allow user to bail out with ^C */
2423 nsyms
= BLOCK_NSYMS (block
);
2424 for (i
= 0; i
< nsyms
; i
++)
2426 QUIT
; /* allow user to bail out with ^C */
2428 printf_filtered ("Scope for %s:\n", save_args
);
2430 sym
= BLOCK_SYM (block
, i
);
2431 symname
= SYMBOL_NAME (sym
);
2432 if (symname
== NULL
|| *symname
== '\0')
2433 continue; /* probably botched, certainly useless */
2435 printf_filtered ("Symbol %s is ", symname
);
2436 switch (SYMBOL_CLASS (sym
))
2439 case LOC_UNDEF
: /* messed up symbol? */
2440 printf_filtered ("a bogus symbol, class %d.\n",
2441 SYMBOL_CLASS (sym
));
2442 count
--; /* don't count this one */
2445 printf_filtered ("a constant with value %ld (0x%lx)",
2446 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2448 case LOC_CONST_BYTES
:
2449 printf_filtered ("constant bytes: ");
2450 if (SYMBOL_TYPE (sym
))
2451 for (j
= 0; j
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); j
++)
2452 fprintf_filtered (gdb_stdout
, " %02x",
2453 (unsigned) SYMBOL_VALUE_BYTES (sym
)[j
]);
2456 printf_filtered ("in static storage at address ");
2457 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2460 printf_filtered ("a local variable in register $%s",
2461 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2465 printf_filtered ("an argument at stack/frame offset %ld",
2466 SYMBOL_VALUE (sym
));
2469 printf_filtered ("a local variable at frame offset %ld",
2470 SYMBOL_VALUE (sym
));
2473 printf_filtered ("a reference argument at offset %ld",
2474 SYMBOL_VALUE (sym
));
2477 printf_filtered ("an argument in register $%s",
2478 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2480 case LOC_REGPARM_ADDR
:
2481 printf_filtered ("the address of an argument, in register $%s",
2482 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2485 printf_filtered ("a typedef.\n");
2488 printf_filtered ("a label at address ");
2489 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2492 printf_filtered ("a function at address ");
2493 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2497 printf_filtered ("a variable at offset %ld from register $%s",
2499 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2501 case LOC_BASEREG_ARG
:
2502 printf_filtered ("an argument at offset %ld from register $%s",
2504 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2506 case LOC_UNRESOLVED
:
2507 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2509 printf_filtered ("Unresolved Static");
2512 printf_filtered ("static storage at address ");
2513 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2517 case LOC_OPTIMIZED_OUT
:
2518 printf_filtered ("optimized out.\n");
2521 if (SYMBOL_TYPE (sym
))
2522 printf_filtered (", length %d.\n",
2523 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2525 if (BLOCK_FUNCTION (block
))
2528 block
= BLOCK_SUPERBLOCK (block
);
2531 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2535 /* worker function (cleanup) */
2537 replace_comma (comma
)
2545 trace_dump_command (args
, from_tty
)
2549 struct tracepoint
*t
;
2550 struct action_line
*action
;
2551 char *action_exp
, *next_comma
;
2552 struct cleanup
*old_cleanups
;
2553 int stepping_actions
= 0;
2554 int stepping_frame
= 0;
2556 if (!target_is_remote ())
2558 error ("Trace can only be run on remote targets.");
2562 if (tracepoint_number
== -1)
2564 warning ("No current trace frame.");
2569 if (t
->number
== tracepoint_number
)
2573 error ("No known tracepoint matches 'current' tracepoint #%d.",
2576 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2578 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2579 tracepoint_number
, traceframe_number
);
2581 /* The current frame is a trap frame if the frame PC is equal
2582 to the tracepoint PC. If not, then the current frame was
2583 collected during single-stepping. */
2585 stepping_frame
= (t
->address
!= read_pc ());
2587 for (action
= t
->actions
; action
; action
= action
->next
)
2589 struct cmd_list_element
*cmd
;
2591 QUIT
; /* allow user to bail out with ^C */
2592 action_exp
= action
->action
;
2593 while (isspace ((int) *action_exp
))
2596 /* The collection actions to be done while stepping are
2597 bracketed by the commands "while-stepping" and "end". */
2599 if (*action_exp
== '#') /* comment line */
2602 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2604 error ("Bad action list item: %s", action_exp
);
2606 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2607 stepping_actions
= 1;
2608 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2609 stepping_actions
= 0;
2610 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2612 /* Display the collected data.
2613 For the trap frame, display only what was collected at the trap.
2614 Likewise for stepping frames, display only what was collected
2615 while stepping. This means that the two boolean variables,
2616 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2617 if (stepping_frame
== stepping_actions
)
2620 { /* repeat over a comma-separated list */
2621 QUIT
; /* allow user to bail out with ^C */
2622 if (*action_exp
== ',')
2624 while (isspace ((int) *action_exp
))
2627 next_comma
= strchr (action_exp
, ',');
2629 if (0 == strncasecmp (action_exp
, "$reg", 4))
2630 registers_info (NULL
, from_tty
);
2631 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2632 locals_info (NULL
, from_tty
);
2633 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2634 args_info (NULL
, from_tty
);
2639 make_cleanup (replace_comma
, next_comma
);
2642 printf_filtered ("%s = ", action_exp
);
2643 output_command (action_exp
, from_tty
);
2644 printf_filtered ("\n");
2648 action_exp
= next_comma
;
2650 while (action_exp
&& *action_exp
== ',');
2654 discard_cleanups (old_cleanups
);
2657 /* Convert the memory pointed to by mem into hex, placing result in buf.
2658 * Return a pointer to the last char put in buf (null)
2659 * "stolen" from sparc-stub.c
2662 static const char hexchars
[] = "0123456789abcdef";
2664 static unsigned char *
2665 mem2hex (mem
, buf
, count
)
2676 *buf
++ = hexchars
[ch
>> 4];
2677 *buf
++ = hexchars
[ch
& 0xf];
2686 get_traceframe_number ()
2688 return traceframe_number
;
2692 /* module initialization */
2694 _initialize_tracepoint ()
2696 tracepoint_chain
= 0;
2697 tracepoint_count
= 0;
2698 traceframe_number
= -1;
2699 tracepoint_number
= -1;
2701 set_internalvar (lookup_internalvar ("tpnum"),
2702 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2703 set_internalvar (lookup_internalvar ("trace_frame"),
2704 value_from_longest (builtin_type_int
, (LONGEST
) - 1));
2706 if (tracepoint_list
.list
== NULL
)
2708 tracepoint_list
.listsize
= 128;
2709 tracepoint_list
.list
= xmalloc
2710 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2712 if (tracepoint_list
.aexpr_list
== NULL
)
2714 tracepoint_list
.aexpr_listsize
= 128;
2715 tracepoint_list
.aexpr_list
= xmalloc
2716 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2719 if (stepping_list
.list
== NULL
)
2721 stepping_list
.listsize
= 128;
2722 stepping_list
.list
= xmalloc
2723 (stepping_list
.listsize
* sizeof (struct memrange
));
2726 if (stepping_list
.aexpr_list
== NULL
)
2728 stepping_list
.aexpr_listsize
= 128;
2729 stepping_list
.aexpr_list
= xmalloc
2730 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2733 add_info ("scope", scope_info
,
2734 "List the variables local to a scope");
2736 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2737 "Tracing of program execution without stopping the program.",
2740 add_info ("tracepoints", tracepoints_info
,
2741 "Status of tracepoints, or tracepoint number NUMBER.\n\
2742 Convenience variable \"$tpnum\" contains the number of the\n\
2743 last tracepoint set.");
2745 add_info_alias ("tp", "tracepoints", 1);
2747 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2748 "Save current tracepoint definitions as a script.\n\
2749 Use the 'source' command in another debug session to restore them.");
2751 add_com ("tdump", class_trace
, trace_dump_command
,
2752 "Print everything collected at the current tracepoint.");
2754 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2755 "Select a trace frame;\n\
2756 No argument means forward by one frame; '-' meand backward by one frame.",
2757 &tfindlist
, "tfind ", 1, &cmdlist
);
2759 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2760 "Select a trace frame whose PC is outside the given \
2761 range.\nUsage: tfind outside addr1, addr2",
2764 add_cmd ("range", class_trace
, trace_find_range_command
,
2765 "Select a trace frame whose PC is in the given range.\n\
2766 Usage: tfind range addr1,addr2",
2769 add_cmd ("line", class_trace
, trace_find_line_command
,
2770 "Select a trace frame by source line.\n\
2771 Argument can be a line number (with optional source file), \n\
2772 a function name, or '*' followed by an address.\n\
2773 Default argument is 'the next source line that was traced'.",
2776 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2777 "Select a trace frame by tracepoint number.\n\
2778 Default is the tracepoint for the current trace frame.",
2781 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2782 "Select a trace frame by PC.\n\
2783 Default is the current PC, or the PC of the current trace frame.",
2786 add_cmd ("end", class_trace
, trace_find_end_command
,
2787 "Synonym for 'none'.\n\
2788 De-select any trace frame and resume 'live' debugging.",
2791 add_cmd ("none", class_trace
, trace_find_none_command
,
2792 "De-select any trace frame and resume 'live' debugging.",
2795 add_cmd ("start", class_trace
, trace_find_start_command
,
2796 "Select the first trace frame in the trace buffer.",
2799 add_com ("tstatus", class_trace
, trace_status_command
,
2800 "Display the status of the current trace data collection.");
2802 add_com ("tstop", class_trace
, trace_stop_command
,
2803 "Stop trace data collection.");
2805 add_com ("tstart", class_trace
, trace_start_command
,
2806 "Start trace data collection.");
2808 add_com ("passcount", class_trace
, trace_pass_command
,
2809 "Set the passcount for a tracepoint.\n\
2810 The trace will end when the tracepoint has been passed 'count' times.\n\
2811 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2812 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2814 add_com ("end", class_trace
, end_actions_pseudocommand
,
2815 "Ends a list of commands or actions.\n\
2816 Several GDB commands allow you to enter a list of commands or actions.\n\
2817 Entering \"end\" on a line by itself is the normal way to terminate\n\
2819 Note: the \"end\" command cannot be used at the gdb prompt.");
2821 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2822 "Specify single-stepping behavior at a tracepoint.\n\
2823 Argument is number of instructions to trace in single-step mode\n\
2824 following the tracepoint. This command is normally followed by\n\
2825 one or more \"collect\" commands, to specify what to collect\n\
2826 while single-stepping.\n\n\
2827 Note: this command can only be used in a tracepoint \"actions\" list.");
2829 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2830 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2832 add_com ("collect", class_trace
, collect_pseudocommand
,
2833 "Specify one or more data items to be collected at a tracepoint.\n\
2834 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2835 collect all data (variables, registers) referenced by that expression.\n\
2836 Also accepts the following special arguments:\n\
2837 $regs -- all registers.\n\
2838 $args -- all function arguments.\n\
2839 $locals -- all variables local to the block/function scope.\n\
2840 Note: this command can only be used in a tracepoint \"actions\" list.");
2842 add_com ("actions", class_trace
, trace_actions_command
,
2843 "Specify the actions to be taken at a tracepoint.\n\
2844 Tracepoint actions may include collecting of specified data, \n\
2845 single-stepping, or enabling/disabling other tracepoints, \n\
2846 depending on target's capabilities.");
2848 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2849 "Delete specified tracepoints.\n\
2850 Arguments are tracepoint numbers, separated by spaces.\n\
2851 No argument means delete all tracepoints.",
2854 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2855 "Disable specified tracepoints.\n\
2856 Arguments are tracepoint numbers, separated by spaces.\n\
2857 No argument means disable all tracepoints.",
2860 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2861 "Enable specified tracepoints.\n\
2862 Arguments are tracepoint numbers, separated by spaces.\n\
2863 No argument means enable all tracepoints.",
2866 add_com ("trace", class_trace
, trace_command
,
2867 "Set a tracepoint at a specified line or function or address.\n\
2868 Argument may be a line number, function name, or '*' plus an address.\n\
2869 For a line number or function, trace at the start of its code.\n\
2870 If an address is specified, trace at that exact address.\n\n\
2871 Do \"help tracepoints\" for info on other tracepoint commands.");
2873 add_com_alias ("tp", "trace", class_alias
, 0);
2874 add_com_alias ("tr", "trace", class_alias
, 1);
2875 add_com_alias ("tra", "trace", class_alias
, 1);
2876 add_com_alias ("trac", "trace", class_alias
, 1);