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"
35 #include "completer.h"
40 /* readline include files */
41 #include <readline/readline.h>
42 #include <readline/history.h>
44 /* readline defines this. */
51 /* maximum length of an agent aexpression.
52 this accounts for the fact that packets are limited to 400 bytes
53 (which includes everything -- including the checksum), and assumes
54 the worst case of maximum length for each of the pieces of a
57 NOTE: expressions get mem2hex'ed otherwise this would be twice as
58 large. (400 - 31)/2 == 184 */
59 #define MAX_AGENT_EXPR_LEN 184
62 extern int info_verbose
;
63 extern void (*readline_begin_hook
) (char *, ...);
64 extern char *(*readline_hook
) (char *);
65 extern void (*readline_end_hook
) (void);
66 extern void x_command (char *, int);
67 extern int addressprint
; /* Print machine addresses? */
69 /* GDB commands implemented in other modules:
72 extern void output_command (char *, int);
73 extern void registers_info (char *, int);
74 extern void args_info (char *, int);
75 extern void locals_info (char *, int);
78 /* If this definition isn't overridden by the header files, assume
79 that isatty and fileno exist on this system. */
81 #define ISATTY(FP) (isatty (fileno (FP)))
87 This module defines the following debugger commands:
88 trace : set a tracepoint on a function, line, or address.
89 info trace : list all debugger-defined tracepoints.
90 delete trace : delete one or more tracepoints.
91 enable trace : enable one or more tracepoints.
92 disable trace : disable one or more tracepoints.
93 actions : specify actions to be taken at a tracepoint.
94 passcount : specify a pass count for a tracepoint.
95 tstart : start a trace experiment.
96 tstop : stop a trace experiment.
97 tstatus : query the status of a trace experiment.
98 tfind : find a trace frame in the trace buffer.
99 tdump : print everything collected at the current tracepoint.
100 save-tracepoints : write tracepoint setup into a file.
102 This module defines the following user-visible debugger variables:
103 $trace_frame : sequence number of trace frame currently being debugged.
104 $trace_line : source line of trace frame currently being debugged.
105 $trace_file : source file of trace frame currently being debugged.
106 $tracepoint : tracepoint number of trace frame currently being debugged.
110 /* ======= Important global variables: ======= */
112 /* Chain of all tracepoints defined. */
113 struct tracepoint
*tracepoint_chain
;
115 /* Number of last tracepoint made. */
116 static int tracepoint_count
;
118 /* Number of last traceframe collected. */
119 static int traceframe_number
;
121 /* Tracepoint for last traceframe collected. */
122 static int tracepoint_number
;
124 /* Symbol for function for last traceframe collected */
125 static struct symbol
*traceframe_fun
;
127 /* Symtab and line for last traceframe collected */
128 static struct symtab_and_line traceframe_sal
;
130 /* Tracing command lists */
131 static struct cmd_list_element
*tfindlist
;
133 /* ======= Important command functions: ======= */
134 static void trace_command (char *, int);
135 static void tracepoints_info (char *, int);
136 static void delete_trace_command (char *, int);
137 static void enable_trace_command (char *, int);
138 static void disable_trace_command (char *, int);
139 static void trace_pass_command (char *, int);
140 static void trace_actions_command (char *, int);
141 static void trace_start_command (char *, int);
142 static void trace_stop_command (char *, int);
143 static void trace_status_command (char *, int);
144 static void trace_find_command (char *, int);
145 static void trace_find_pc_command (char *, int);
146 static void trace_find_tracepoint_command (char *, int);
147 static void trace_find_line_command (char *, int);
148 static void trace_find_range_command (char *, int);
149 static void trace_find_outside_command (char *, int);
150 static void tracepoint_save_command (char *, int);
151 static void trace_dump_command (char *, int);
153 /* support routines */
154 static void trace_mention (struct tracepoint
*);
156 struct collection_list
;
157 static void add_aexpr (struct collection_list
*, struct agent_expr
*);
158 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
159 static void add_register (struct collection_list
*collection
,
161 static struct cleanup
*make_cleanup_free_actions (struct tracepoint
*t
);
162 static void free_actions_list (char **actions_list
);
163 static void free_actions_list_cleanup_wrapper (void *);
165 extern void _initialize_tracepoint (void);
167 /* Utility: returns true if "target remote" */
169 target_is_remote (void)
171 if (current_target
.to_shortname
&&
172 strcmp (current_target
.to_shortname
, "remote") == 0)
178 /* Utility: generate error from an incoming stub packet. */
180 trace_error (char *buf
)
183 return; /* not an error msg */
186 case '1': /* malformed packet error */
187 if (*++buf
== '0') /* general case: */
188 error ("tracepoint.c: error in outgoing packet.");
190 error ("tracepoint.c: error in outgoing packet at field #%d.",
191 strtol (buf
, NULL
, 16));
193 error ("trace API error 0x%s.", ++buf
);
195 error ("Target returns error code '%s'.", buf
);
199 /* Utility: wait for reply from stub, while accepting "O" packets */
201 remote_get_noisy_reply (char *buf
,
204 do /* loop on reply from remote stub */
206 QUIT
; /* allow user to bail out with ^C */
207 getpkt (buf
, sizeof_buf
, 0);
209 error ("Target does not support this command.");
210 else if (buf
[0] == 'E')
212 else if (buf
[0] == 'O' &&
214 remote_console_output (buf
+ 1); /* 'O' message from stub */
216 return buf
; /* here's the actual reply */
221 /* Set tracepoint count to NUM. */
223 set_tracepoint_count (int 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 (int num
)
234 traceframe_number
= num
;
235 set_internalvar (lookup_internalvar ("trace_frame"),
236 value_from_longest (builtin_type_int
, (LONGEST
) num
));
239 /* Set tracepoint number to NUM. */
241 set_tracepoint_num (int num
)
243 tracepoint_number
= num
;
244 set_internalvar (lookup_internalvar ("tracepoint"),
245 value_from_longest (builtin_type_int
, (LONGEST
) num
));
248 /* Set externally visible debug variables for querying/printing
249 the traceframe context (line, function, file) */
252 set_traceframe_context (CORE_ADDR trace_pc
)
254 static struct type
*func_string
, *file_string
;
255 static struct type
*func_range
, *file_range
;
256 static value_ptr func_val
, file_val
;
257 static struct type
*charstar
;
260 if (charstar
== (struct type
*) NULL
)
261 charstar
= lookup_pointer_type (builtin_type_char
);
263 if (trace_pc
== -1) /* cease debugging any trace buffers */
266 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
267 traceframe_sal
.symtab
= NULL
;
268 set_internalvar (lookup_internalvar ("trace_func"),
269 value_from_pointer (charstar
, (LONGEST
) 0));
270 set_internalvar (lookup_internalvar ("trace_file"),
271 value_from_pointer (charstar
, (LONGEST
) 0));
272 set_internalvar (lookup_internalvar ("trace_line"),
273 value_from_pointer (builtin_type_int
, (LONGEST
) - 1));
277 /* save as globals for internal use */
278 traceframe_sal
= find_pc_line (trace_pc
, 0);
279 traceframe_fun
= find_pc_function (trace_pc
);
281 /* save linenumber as "$trace_line", a debugger variable visible to users */
282 set_internalvar (lookup_internalvar ("trace_line"),
283 value_from_longest (builtin_type_int
,
284 (LONGEST
) traceframe_sal
.line
));
286 /* save func name as "$trace_func", a debugger variable visible to users */
287 if (traceframe_fun
== NULL
||
288 SYMBOL_NAME (traceframe_fun
) == NULL
)
289 set_internalvar (lookup_internalvar ("trace_func"),
290 value_from_pointer (charstar
, (LONGEST
) 0));
293 len
= strlen (SYMBOL_NAME (traceframe_fun
));
294 func_range
= create_range_type (func_range
,
295 builtin_type_int
, 0, len
- 1);
296 func_string
= create_array_type (func_string
,
297 builtin_type_char
, func_range
);
298 func_val
= allocate_value (func_string
);
299 VALUE_TYPE (func_val
) = func_string
;
300 memcpy (VALUE_CONTENTS_RAW (func_val
),
301 SYMBOL_NAME (traceframe_fun
),
303 func_val
->modifiable
= 0;
304 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
307 /* save file name as "$trace_file", a debugger variable visible to users */
308 if (traceframe_sal
.symtab
== NULL
||
309 traceframe_sal
.symtab
->filename
== NULL
)
310 set_internalvar (lookup_internalvar ("trace_file"),
311 value_from_pointer (charstar
, (LONGEST
) 0));
314 len
= strlen (traceframe_sal
.symtab
->filename
);
315 file_range
= create_range_type (file_range
,
316 builtin_type_int
, 0, len
- 1);
317 file_string
= create_array_type (file_string
,
318 builtin_type_char
, file_range
);
319 file_val
= allocate_value (file_string
);
320 VALUE_TYPE (file_val
) = file_string
;
321 memcpy (VALUE_CONTENTS_RAW (file_val
),
322 traceframe_sal
.symtab
->filename
,
324 file_val
->modifiable
= 0;
325 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
329 /* Low level routine to set a tracepoint.
330 Returns the tracepoint object so caller can set other things.
331 Does not set the tracepoint number!
332 Does not print anything.
334 ==> This routine should not be called if there is a chance of later
335 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
336 your arguments BEFORE calling this routine! */
338 static struct tracepoint
*
339 set_raw_tracepoint (struct symtab_and_line sal
)
341 register struct tracepoint
*t
, *tc
;
342 struct cleanup
*old_chain
;
344 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
345 old_chain
= make_cleanup (xfree
, t
);
346 memset (t
, 0, sizeof (*t
));
348 if (sal
.symtab
== NULL
)
349 t
->source_file
= NULL
;
351 t
->source_file
= savestring (sal
.symtab
->filename
,
352 strlen (sal
.symtab
->filename
));
354 t
->section
= sal
.section
;
355 t
->language
= current_language
->la_language
;
356 t
->input_radix
= input_radix
;
357 t
->line_number
= sal
.line
;
358 t
->enabled
= enabled
;
362 t
->addr_string
= NULL
;
364 /* Add this tracepoint to the end of the chain
365 so that a list of tracepoints will come out in order
366 of increasing numbers. */
368 tc
= tracepoint_chain
;
370 tracepoint_chain
= t
;
377 discard_cleanups (old_chain
);
381 /* Set a tracepoint according to ARG (function, linenum or *address) */
383 trace_command (char *arg
, int from_tty
)
385 char **canonical
= (char **) NULL
;
386 struct symtabs_and_lines sals
;
387 struct symtab_and_line sal
;
388 struct tracepoint
*t
;
389 char *addr_start
= 0, *addr_end
= 0;
393 error ("trace command requires an argument");
395 if (from_tty
&& info_verbose
)
396 printf_filtered ("TRACE %s\n", arg
);
399 sals
= decode_line_1 (&arg
, 1, (struct symtab
*) NULL
, 0, &canonical
);
402 return; /* ??? Presumably decode_line_1 has already warned? */
404 /* Resolve all line numbers to PC's */
405 for (i
= 0; i
< sals
.nelts
; i
++)
406 resolve_sal_pc (&sals
.sals
[i
]);
408 /* Now set all the tracepoints. */
409 for (i
= 0; i
< sals
.nelts
; i
++)
413 t
= set_raw_tracepoint (sal
);
414 set_tracepoint_count (tracepoint_count
+ 1);
415 t
->number
= tracepoint_count
;
417 /* If a canonical line spec is needed use that instead of the
419 if (canonical
!= (char **) NULL
&& canonical
[i
] != NULL
)
420 t
->addr_string
= canonical
[i
];
422 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
426 /* Let the UI know of any additions */
427 if (create_tracepoint_hook
)
428 create_tracepoint_hook (t
);
433 printf_filtered ("Multiple tracepoints were set.\n");
434 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
438 /* Tell the user we have just set a tracepoint TP. */
441 trace_mention (struct tracepoint
*tp
)
443 printf_filtered ("Tracepoint %d", tp
->number
);
445 if (addressprint
|| (tp
->source_file
== NULL
))
447 printf_filtered (" at ");
448 print_address_numeric (tp
->address
, 1, gdb_stdout
);
451 printf_filtered (": file %s, line %d.",
452 tp
->source_file
, tp
->line_number
);
454 printf_filtered ("\n");
457 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
460 tracepoints_info (char *tpnum_exp
, int from_tty
)
462 struct tracepoint
*t
;
463 struct action_line
*action
;
464 int found_a_tracepoint
= 0;
465 char wrap_indent
[80];
470 tpnum
= parse_and_eval_long (tpnum_exp
);
473 if (tpnum
== -1 || tpnum
== t
->number
)
475 extern int addressprint
; /* print machine addresses? */
477 if (!found_a_tracepoint
++)
479 printf_filtered ("Num Enb ");
481 printf_filtered ("Address ");
482 printf_filtered ("PassC StepC What\n");
484 strcpy (wrap_indent
, " ");
486 strcat (wrap_indent
, " ");
488 printf_filtered ("%-3d %-3s ", t
->number
,
489 t
->enabled
== enabled
? "y" : "n");
491 printf_filtered ("%s ",
492 local_hex_string_custom ((unsigned long) t
->address
,
494 printf_filtered ("%-5d %-5ld ", t
->pass_count
, t
->step_count
);
498 sym
= find_pc_sect_function (t
->address
, t
->section
);
501 fputs_filtered ("in ", gdb_stdout
);
502 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
503 wrap_here (wrap_indent
);
504 fputs_filtered (" at ", gdb_stdout
);
506 fputs_filtered (t
->source_file
, gdb_stdout
);
507 printf_filtered (":%d", t
->line_number
);
510 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
512 printf_filtered ("\n");
515 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
516 for (action
= t
->actions
; action
; action
= action
->next
)
518 printf_filtered ("\t%s\n", action
->action
);
522 if (!found_a_tracepoint
)
525 printf_filtered ("No tracepoints.\n");
527 printf_filtered ("No tracepoint number %d.\n", tpnum
);
531 /* Optimization: the code to parse an enable, disable, or delete TP command
532 is virtually identical except for whether it performs an enable, disable,
533 or delete. Therefore I've combined them into one function with an opcode.
535 enum tracepoint_opcode
542 /* This function implements enable, disable and delete commands. */
544 tracepoint_operation (struct tracepoint
*t
, int from_tty
,
545 enum tracepoint_opcode opcode
)
547 struct tracepoint
*t2
;
549 if (t
== NULL
) /* no tracepoint operand */
555 t
->enabled
= enabled
;
556 if (modify_tracepoint_hook
)
557 modify_tracepoint_hook (t
);
560 t
->enabled
= disabled
;
561 if (modify_tracepoint_hook
)
562 modify_tracepoint_hook (t
);
565 if (tracepoint_chain
== t
)
566 tracepoint_chain
= t
->next
;
575 /* Let the UI know of any deletions */
576 if (delete_tracepoint_hook
)
577 delete_tracepoint_hook (t
);
580 xfree (t
->addr_string
);
582 xfree (t
->source_file
);
591 /* Utility: parse a tracepoint number and look it up in the list.
592 If MULTI_P is true, there might be a range of tracepoints in ARG.
593 if OPTIONAL_P is true, then if the argument is missing, the most
594 recent tracepoint (tracepoint_count) is returned. */
596 get_tracepoint_by_number (char **arg
, int multi_p
, int optional_p
)
598 struct tracepoint
*t
;
600 char *instring
= arg
== NULL
? NULL
: *arg
;
602 if (arg
== NULL
|| *arg
== NULL
|| ! **arg
)
605 tpnum
= tracepoint_count
;
607 error_no_arg ("tracepoint number");
610 tpnum
= multi_p
? get_number_or_range (arg
) : get_number (arg
);
614 if (instring
&& *instring
)
615 printf_filtered ("bad tracepoint number at or near '%s'\n", instring
);
617 printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
622 if (t
->number
== tpnum
)
627 /* FIXME: if we are in the middle of a range we don't want to give
628 a message. The current interface to get_number_or_range doesn't
629 allow us to discover this. */
630 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
634 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
636 map_args_over_tracepoints (char *args
, int from_tty
,
637 enum tracepoint_opcode opcode
)
639 struct tracepoint
*t
, *tmp
;
641 if (args
== 0 || *args
== 0) /* do them all */
642 ALL_TRACEPOINTS_SAFE (t
, tmp
)
643 tracepoint_operation (t
, from_tty
, opcode
);
647 QUIT
; /* give user option to bail out with ^C */
648 t
= get_tracepoint_by_number (&args
, 1, 0);
649 tracepoint_operation (t
, from_tty
, opcode
);
650 while (*args
== ' ' || *args
== '\t')
655 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
657 enable_trace_command (char *args
, int from_tty
)
660 map_args_over_tracepoints (args
, from_tty
, enable_op
);
663 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
665 disable_trace_command (char *args
, int from_tty
)
668 map_args_over_tracepoints (args
, from_tty
, disable_op
);
671 /* Remove a tracepoint (or all if no argument) */
673 delete_trace_command (char *args
, int from_tty
)
676 if (!args
|| !*args
) /* No args implies all tracepoints; */
677 if (from_tty
) /* confirm only if from_tty... */
678 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
679 if (!query ("Delete all tracepoints? "))
682 map_args_over_tracepoints (args
, from_tty
, delete_op
);
685 /* Set passcount for tracepoint.
687 First command argument is passcount, second is tracepoint number.
688 If tracepoint number omitted, apply to most recently defined.
689 Also accepts special argument "all". */
692 trace_pass_command (char *args
, int from_tty
)
694 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
698 if (args
== 0 || *args
== 0)
699 error ("passcount command requires an argument (count + optional TP num)");
701 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
703 while (*args
&& isspace ((int) *args
))
706 if (*args
&& strncasecmp (args
, "all", 3) == 0)
708 args
+= 3; /* skip special argument "all" */
711 error ("Junk at end of arguments.");
714 t1
= get_tracepoint_by_number (&args
, 1, 1);
721 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
723 t2
->pass_count
= count
;
724 if (modify_tracepoint_hook
)
725 modify_tracepoint_hook (t2
);
727 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
731 t1
= get_tracepoint_by_number (&args
, 1, 0);
737 /* ACTIONS functions: */
739 /* Prototypes for action-parsing utility commands */
740 static void read_actions (struct tracepoint
*);
742 /* The three functions:
743 collect_pseudocommand,
744 while_stepping_pseudocommand, and
745 end_actions_pseudocommand
746 are placeholders for "commands" that are actually ONLY to be used
747 within a tracepoint action list. If the actual function is ever called,
748 it means that somebody issued the "command" at the top level,
749 which is always an error. */
752 end_actions_pseudocommand (char *args
, int from_tty
)
754 error ("This command cannot be used at the top level.");
758 while_stepping_pseudocommand (char *args
, int from_tty
)
760 error ("This command can only be used in a tracepoint actions list.");
764 collect_pseudocommand (char *args
, int from_tty
)
766 error ("This command can only be used in a tracepoint actions list.");
769 /* Enter a list of actions for a tracepoint. */
771 trace_actions_command (char *args
, int from_tty
)
773 struct tracepoint
*t
;
775 char *end_msg
= "End with a line saying just \"end\".";
777 t
= get_tracepoint_by_number (&args
, 0, 1);
780 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
785 if (readline_begin_hook
)
786 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
787 else if (input_from_terminal_p ())
788 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
792 t
->step_count
= 0; /* read_actions may set this */
795 if (readline_end_hook
)
796 (*readline_end_hook
) ();
797 /* tracepoints_changed () */
799 /* else just return */
802 /* worker function */
804 read_actions (struct tracepoint
*t
)
807 char *prompt1
= "> ", *prompt2
= " > ";
808 char *prompt
= prompt1
;
809 enum actionline_type linetype
;
810 extern FILE *instream
;
811 struct action_line
*next
= NULL
, *temp
;
812 struct cleanup
*old_chain
;
814 /* Control-C quits instantly if typed while in this loop
815 since it should not wait until the user types a newline. */
821 signal (STOP_SIGNAL
, handle_stop_sig
);
823 signal (STOP_SIGNAL
, stop_sig
);
826 old_chain
= make_cleanup_free_actions (t
);
829 /* Make sure that all output has been output. Some machines may let
830 you get away with leaving out some of the gdb_flush, but not all. */
832 gdb_flush (gdb_stdout
);
833 gdb_flush (gdb_stderr
);
835 if (readline_hook
&& instream
== NULL
)
836 line
= (*readline_hook
) (prompt
);
837 else if (instream
== stdin
&& ISATTY (instream
))
839 line
= readline (prompt
);
840 if (line
&& *line
) /* add it to command history */
844 line
= gdb_readline (0);
846 linetype
= validate_actionline (&line
, t
);
847 if (linetype
== BADLINE
)
848 continue; /* already warned -- collect another line */
850 temp
= xmalloc (sizeof (struct action_line
));
854 if (next
== NULL
) /* first action for this tracepoint? */
855 t
->actions
= next
= temp
;
862 if (linetype
== STEPPING
) /* begin "while-stepping" */
864 if (prompt
== prompt2
)
866 warning ("Already processing 'while-stepping'");
870 prompt
= prompt2
; /* change prompt for stepping actions */
872 else if (linetype
== END
)
874 if (prompt
== prompt2
)
876 prompt
= prompt1
; /* end of single-stepping actions */
879 { /* end of actions */
880 if (t
->actions
->next
== NULL
)
882 /* an "end" all by itself with no other actions means
883 this tracepoint has no actions. Discard empty list. */
892 signal (STOP_SIGNAL
, SIG_DFL
);
895 discard_cleanups (old_chain
);
898 /* worker function */
900 validate_actionline (char **line
, struct tracepoint
*t
)
902 struct cmd_list_element
*c
;
903 struct expression
*exp
= NULL
;
904 struct cleanup
*old_chain
= NULL
;
907 for (p
= *line
; isspace ((int) *p
);)
910 /* symbol lookup etc. */
911 if (*p
== '\0') /* empty line: just prompt for another line. */
914 if (*p
== '#') /* comment line */
917 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
920 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
924 if (c
->function
.cfunc
== collect_pseudocommand
)
926 struct agent_expr
*aexpr
;
927 struct agent_reqs areqs
;
930 { /* repeat over a comma-separated list */
931 QUIT
; /* allow user to bail out with ^C */
932 while (isspace ((int) *p
))
935 if (*p
== '$') /* look for special pseudo-symbols */
937 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
938 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
939 (0 == strncasecmp ("loc", p
+ 1, 3)))
944 /* else fall thru, treat p as an expression and parse it! */
946 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
947 old_chain
= make_cleanup (free_current_contents
, &exp
);
949 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
951 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
953 warning ("constant %s (value %ld) will not be collected.",
954 SYMBOL_NAME (exp
->elts
[2].symbol
),
955 SYMBOL_VALUE (exp
->elts
[2].symbol
));
958 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
960 warning ("%s is optimized away and cannot be collected.",
961 SYMBOL_NAME (exp
->elts
[2].symbol
));
966 /* we have something to collect, make sure that the expr to
967 bytecode translator can handle it and that it's not too long */
968 aexpr
= gen_trace_for_expr (t
->address
, exp
);
969 make_cleanup_free_agent_expr (aexpr
);
971 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
972 error ("expression too complicated, try simplifying");
974 ax_reqs (aexpr
, &areqs
);
975 (void) make_cleanup (xfree
, areqs
.reg_mask
);
977 if (areqs
.flaw
!= agent_flaw_none
)
978 error ("malformed expression");
980 if (areqs
.min_height
< 0)
981 error ("gdb: Internal error: expression has min height < 0");
983 if (areqs
.max_height
> 20)
984 error ("expression too complicated, try simplifying");
986 do_cleanups (old_chain
);
988 while (p
&& *p
++ == ',');
991 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
993 char *steparg
; /* in case warning is necessary */
995 while (isspace ((int) *p
))
1000 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1002 warning ("'%s': bad step-count; command ignored.", *line
);
1007 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1011 warning ("'%s' is not a supported tracepoint action.", *line
);
1016 /* worker function */
1018 free_actions (struct tracepoint
*t
)
1020 struct action_line
*line
, *next
;
1022 for (line
= t
->actions
; line
; line
= next
)
1026 xfree (line
->action
);
1033 do_free_actions_cleanup (void *t
)
1038 static struct cleanup
*
1039 make_cleanup_free_actions (struct tracepoint
*t
)
1041 return make_cleanup (do_free_actions_cleanup
, t
);
1046 int type
; /* 0 for absolute memory range, else basereg number */
1047 bfd_signed_vma start
;
1051 struct collection_list
1053 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1056 struct memrange
*list
;
1057 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1058 long next_aexpr_elt
;
1059 struct agent_expr
**aexpr_list
;
1062 tracepoint_list
, stepping_list
;
1064 /* MEMRANGE functions: */
1066 static int memrange_cmp (const void *, const void *);
1068 /* compare memranges for qsort */
1070 memrange_cmp (const void *va
, const void *vb
)
1072 const struct memrange
*a
= va
, *b
= vb
;
1074 if (a
->type
< b
->type
)
1076 if (a
->type
> b
->type
)
1080 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
)
1082 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
)
1087 if (a
->start
< b
->start
)
1089 if (a
->start
> b
->start
)
1095 /* Sort the memrange list using qsort, and merge adjacent memranges */
1097 memrange_sortmerge (struct collection_list
*memranges
)
1101 qsort (memranges
->list
, memranges
->next_memrange
,
1102 sizeof (struct memrange
), memrange_cmp
);
1103 if (memranges
->next_memrange
> 0)
1105 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1107 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1108 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1109 MAX_REGISTER_VIRTUAL_SIZE
)
1111 /* memrange b starts before memrange a ends; merge them. */
1112 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1113 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1114 continue; /* next b, same a */
1118 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1119 sizeof (struct memrange
));
1121 memranges
->next_memrange
= a
+ 1;
1125 /* Add a register to a collection list */
1127 add_register (struct collection_list
*collection
, unsigned int regno
)
1130 printf_filtered ("collect register %d\n", regno
);
1131 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1132 error ("Internal: register number %d too large for tracepoint",
1134 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1137 /* Add a memrange to a collection list */
1139 add_memrange (struct collection_list
*memranges
, int type
, bfd_signed_vma base
,
1144 printf_filtered ("(%d,", type
);
1146 printf_filtered (",%ld)\n", len
);
1149 /* type: 0 == memory, n == basereg */
1150 memranges
->list
[memranges
->next_memrange
].type
= type
;
1151 /* base: addr if memory, offset if reg relative. */
1152 memranges
->list
[memranges
->next_memrange
].start
= base
;
1153 /* len: we actually save end (base + len) for convenience */
1154 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1155 memranges
->next_memrange
++;
1156 if (memranges
->next_memrange
>= memranges
->listsize
)
1158 memranges
->listsize
*= 2;
1159 memranges
->list
= xrealloc (memranges
->list
,
1160 memranges
->listsize
);
1163 if (type
!= -1) /* better collect the base register! */
1164 add_register (memranges
, type
);
1167 /* Add a symbol to a collection list */
1169 collect_symbol (struct collection_list
*collect
, struct symbol
*sym
,
1170 long frame_regno
, long frame_offset
)
1174 bfd_signed_vma offset
;
1176 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1177 switch (SYMBOL_CLASS (sym
))
1180 printf_filtered ("%s: don't know symbol class %d\n",
1181 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1184 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1185 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1188 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1193 sprintf_vma (tmp
, offset
);
1194 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1195 SYMBOL_NAME (sym
), len
, tmp
/* address */);
1197 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1201 reg
= SYMBOL_VALUE (sym
);
1203 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1204 add_register (collect
, reg
);
1205 /* check for doubles stored in two registers */
1206 /* FIXME: how about larger types stored in 3 or more regs? */
1207 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1208 len
> REGISTER_RAW_SIZE (reg
))
1209 add_register (collect
, reg
+ 1);
1212 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1213 printf_filtered (" (will not collect %s)\n",
1218 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1221 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1222 SYMBOL_NAME (sym
), len
);
1223 printf_vma (offset
);
1224 printf_filtered (" from frame ptr reg %d\n", reg
);
1226 add_memrange (collect
, reg
, offset
, len
);
1228 case LOC_REGPARM_ADDR
:
1229 reg
= SYMBOL_VALUE (sym
);
1233 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1234 SYMBOL_NAME (sym
), len
);
1235 printf_vma (offset
);
1236 printf_filtered (" from reg %d\n", reg
);
1238 add_memrange (collect
, reg
, offset
, len
);
1243 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1246 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1247 SYMBOL_NAME (sym
), len
);
1248 printf_vma (offset
);
1249 printf_filtered (" from frame ptr reg %d\n", reg
);
1251 add_memrange (collect
, reg
, offset
, len
);
1254 case LOC_BASEREG_ARG
:
1255 reg
= SYMBOL_BASEREG (sym
);
1256 offset
= SYMBOL_VALUE (sym
);
1259 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1260 SYMBOL_NAME (sym
), len
);
1261 printf_vma (offset
);
1262 printf_filtered (" from basereg %d\n", reg
);
1264 add_memrange (collect
, reg
, offset
, len
);
1266 case LOC_UNRESOLVED
:
1267 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1269 case LOC_OPTIMIZED_OUT
:
1270 printf_filtered ("%s has been optimized out of existence.\n",
1276 /* Add all locals (or args) symbols to collection list */
1278 add_local_symbols (struct collection_list
*collect
, CORE_ADDR pc
,
1279 long frame_regno
, long frame_offset
, int type
)
1282 struct block
*block
;
1283 int i
, nsyms
, count
= 0;
1285 block
= block_for_pc (pc
);
1288 QUIT
; /* allow user to bail out with ^C */
1289 nsyms
= BLOCK_NSYMS (block
);
1290 for (i
= 0; i
< nsyms
; i
++)
1292 sym
= BLOCK_SYM (block
, i
);
1293 switch (SYMBOL_CLASS (sym
))
1296 warning ("don't know how to trace local symbol %s",
1302 if (type
== 'L') /* collecting Locals */
1305 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1312 case LOC_REGPARM_ADDR
:
1313 case LOC_BASEREG_ARG
:
1314 if (type
== 'A') /* collecting Arguments */
1317 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1321 if (BLOCK_FUNCTION (block
))
1324 block
= BLOCK_SUPERBLOCK (block
);
1327 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1330 /* worker function */
1332 clear_collection_list (struct collection_list
*list
)
1336 list
->next_memrange
= 0;
1337 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1339 free_agent_expr (list
->aexpr_list
[ndx
]);
1340 list
->aexpr_list
[ndx
] = NULL
;
1342 list
->next_aexpr_elt
= 0;
1343 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1346 /* reduce a collection list to string form (for gdb protocol) */
1348 stringify_collection_list (struct collection_list
*list
, char *string
)
1350 char temp_buf
[2048];
1354 char *(*str_list
)[];
1358 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1359 str_list
= (char *(*)[]) xmalloc (count
* sizeof (char *));
1361 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1362 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1364 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1367 printf_filtered ("\nCollecting registers (mask): 0x");
1372 QUIT
; /* allow user to bail out with ^C */
1374 printf_filtered ("%02X", list
->regs_mask
[i
]);
1375 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1378 (*str_list
)[ndx
] = savestring (temp_buf
, end
- temp_buf
);
1382 printf_filtered ("\n");
1383 if (list
->next_memrange
> 0 && info_verbose
)
1384 printf_filtered ("Collecting memranges: \n");
1385 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1387 QUIT
; /* allow user to bail out with ^C */
1388 sprintf_vma (tmp2
, list
->list
[i
].start
);
1391 printf_filtered ("(%d, %s, %ld)\n",
1394 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1396 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1398 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1404 sprintf (end
, "M%X,%s,%lX",
1407 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1409 count
+= strlen (end
);
1413 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1415 QUIT
; /* allow user to bail out with ^C */
1416 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1418 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1423 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1424 end
+= 10; /* 'X' + 8 hex digits + ',' */
1427 end
= mem2hex (list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1428 count
+= 2 * list
->aexpr_list
[i
]->len
;
1433 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1438 (*str_list
)[ndx
] = NULL
;
1447 free_actions_list_cleanup_wrapper (void *al
)
1449 free_actions_list (al
);
1453 free_actions_list (char **actions_list
)
1457 if (actions_list
== 0)
1460 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1461 xfree (actions_list
[ndx
]);
1463 xfree (actions_list
);
1466 /* render all actions into gdb protocol */
1468 encode_actions (struct tracepoint
*t
, char ***tdp_actions
,
1469 char ***stepping_actions
)
1471 static char tdp_buff
[2048], step_buff
[2048];
1473 struct expression
*exp
= NULL
;
1474 struct action_line
*action
;
1477 struct collection_list
*collect
;
1478 struct cmd_list_element
*cmd
;
1479 struct agent_expr
*aexpr
;
1480 long frame_reg
, frame_offset
;
1483 clear_collection_list (&tracepoint_list
);
1484 clear_collection_list (&stepping_list
);
1485 collect
= &tracepoint_list
;
1487 *tdp_actions
= NULL
;
1488 *stepping_actions
= NULL
;
1490 TARGET_VIRTUAL_FRAME_POINTER (t
->address
, &frame_reg
, &frame_offset
);
1492 for (action
= t
->actions
; action
; action
= action
->next
)
1494 QUIT
; /* allow user to bail out with ^C */
1495 action_exp
= action
->action
;
1496 while (isspace ((int) *action_exp
))
1499 if (*action_exp
== '#') /* comment line */
1502 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1504 error ("Bad action list item: %s", action_exp
);
1506 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1509 { /* repeat over a comma-separated list */
1510 QUIT
; /* allow user to bail out with ^C */
1511 while (isspace ((int) *action_exp
))
1514 if (0 == strncasecmp ("$reg", action_exp
, 4))
1516 for (i
= 0; i
< NUM_REGS
; i
++)
1517 add_register (collect
, i
);
1518 action_exp
= strchr (action_exp
, ','); /* more? */
1520 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1522 add_local_symbols (collect
,
1527 action_exp
= strchr (action_exp
, ','); /* more? */
1529 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1531 add_local_symbols (collect
,
1536 action_exp
= strchr (action_exp
, ','); /* more? */
1540 unsigned long addr
, len
;
1541 struct cleanup
*old_chain
= NULL
;
1542 struct cleanup
*old_chain1
= NULL
;
1543 struct agent_reqs areqs
;
1545 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1546 old_chain
= make_cleanup (free_current_contents
, &exp
);
1548 switch (exp
->elts
[0].opcode
)
1551 i
= exp
->elts
[1].longconst
;
1553 printf_filtered ("OP_REGISTER: ");
1554 add_register (collect
, i
);
1558 /* safe because we know it's a simple expression */
1559 tempval
= evaluate_expression (exp
);
1560 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1561 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1562 add_memrange (collect
, -1, addr
, len
);
1566 collect_symbol (collect
,
1567 exp
->elts
[2].symbol
,
1572 default: /* full-fledged expression */
1573 aexpr
= gen_trace_for_expr (t
->address
, exp
);
1575 old_chain1
= make_cleanup_free_agent_expr (aexpr
);
1577 ax_reqs (aexpr
, &areqs
);
1578 if (areqs
.flaw
!= agent_flaw_none
)
1579 error ("malformed expression");
1581 if (areqs
.min_height
< 0)
1582 error ("gdb: Internal error: expression has min height < 0");
1583 if (areqs
.max_height
> 20)
1584 error ("expression too complicated, try simplifying");
1586 discard_cleanups (old_chain1
);
1587 add_aexpr (collect
, aexpr
);
1589 /* take care of the registers */
1590 if (areqs
.reg_mask_len
> 0)
1595 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1597 QUIT
; /* allow user to bail out with ^C */
1598 if (areqs
.reg_mask
[ndx1
] != 0)
1600 /* assume chars have 8 bits */
1601 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1602 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1603 /* it's used -- record it */
1604 add_register (collect
, ndx1
* 8 + ndx2
);
1610 do_cleanups (old_chain
);
1613 while (action_exp
&& *action_exp
++ == ',');
1615 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1617 collect
= &stepping_list
;
1619 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1621 if (collect
== &stepping_list
) /* end stepping actions */
1622 collect
= &tracepoint_list
;
1624 break; /* end tracepoint actions */
1627 memrange_sortmerge (&tracepoint_list
);
1628 memrange_sortmerge (&stepping_list
);
1630 *tdp_actions
= stringify_collection_list (&tracepoint_list
, tdp_buff
);
1631 *stepping_actions
= stringify_collection_list (&stepping_list
, step_buff
);
1635 add_aexpr (struct collection_list
*collect
, struct agent_expr
*aexpr
)
1637 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1639 collect
->aexpr_list
=
1640 xrealloc (collect
->aexpr_list
,
1641 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1642 collect
->aexpr_listsize
*= 2;
1644 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1645 collect
->next_aexpr_elt
++;
1648 static char target_buf
[2048];
1650 /* Set "transparent" memory ranges
1652 Allow trace mechanism to treat text-like sections
1653 (and perhaps all read-only sections) transparently,
1654 i.e. don't reject memory requests from these address ranges
1655 just because they haven't been collected. */
1658 remote_set_transparent_ranges (void)
1660 extern bfd
*exec_bfd
;
1667 return; /* no information to give. */
1669 strcpy (target_buf
, "QTro");
1670 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1672 char tmp1
[40], tmp2
[40];
1674 if ((s
->flags
& SEC_LOAD
) == 0 ||
1675 /* (s->flags & SEC_CODE) == 0 || */
1676 (s
->flags
& SEC_READONLY
) == 0)
1681 size
= bfd_get_section_size_before_reloc (s
);
1682 sprintf_vma (tmp1
, lma
);
1683 sprintf_vma (tmp2
, lma
+ size
);
1684 sprintf (target_buf
+ strlen (target_buf
),
1685 ":%s,%s", tmp1
, tmp2
);
1689 putpkt (target_buf
);
1690 getpkt (target_buf
, sizeof (target_buf
), 0);
1696 Tell target to clear any previous trace experiment.
1697 Walk the list of tracepoints, and send them (and their actions)
1698 to the target. If no errors,
1699 Tell target to start a new trace experiment. */
1702 trace_start_command (char *args
, int from_tty
)
1703 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1704 struct tracepoint
*t
;
1707 char **stepping_actions
;
1709 struct cleanup
*old_chain
= NULL
;
1711 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1713 if (target_is_remote ())
1716 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1717 if (strcmp (target_buf
, "OK"))
1718 error ("Target does not support this command.");
1724 sprintf_vma (tmp
, t
->address
);
1725 sprintf (buf
, "QTDP:%x:%s:%c:%lx:%x", t
->number
, tmp
, /* address */
1726 t
->enabled
== enabled
? 'E' : 'D',
1727 t
->step_count
, t
->pass_count
);
1732 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1733 if (strcmp (target_buf
, "OK"))
1734 error ("Target does not support tracepoints.");
1738 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1739 old_chain
= make_cleanup (free_actions_list_cleanup_wrapper
,
1741 (void) make_cleanup (free_actions_list_cleanup_wrapper
,
1744 /* do_single_steps (t); */
1747 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1749 QUIT
; /* allow user to bail out with ^C */
1750 sprintf (buf
, "QTDP:-%x:%s:%s%c",
1751 t
->number
, tmp
, /* address */
1753 ((tdp_actions
[ndx
+ 1] || stepping_actions
)
1756 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1757 if (strcmp (target_buf
, "OK"))
1758 error ("Error on target while setting tracepoints.");
1761 if (stepping_actions
)
1763 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1765 QUIT
; /* allow user to bail out with ^C */
1766 sprintf (buf
, "QTDP:-%x:%s:%s%s%s",
1767 t
->number
, tmp
, /* address */
1768 ((ndx
== 0) ? "S" : ""),
1769 stepping_actions
[ndx
],
1770 (stepping_actions
[ndx
+ 1] ? "-" : ""));
1772 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1773 if (strcmp (target_buf
, "OK"))
1774 error ("Error on target while setting tracepoints.");
1778 do_cleanups (old_chain
);
1781 /* Tell target to treat text-like sections as transparent */
1782 remote_set_transparent_ranges ();
1783 /* Now insert traps and begin collecting data */
1785 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1786 if (strcmp (target_buf
, "OK"))
1787 error ("Bogus reply from target: %s", target_buf
);
1788 set_traceframe_num (-1); /* all old traceframes invalidated */
1789 set_tracepoint_num (-1);
1790 set_traceframe_context (-1);
1791 trace_running_p
= 1;
1792 if (trace_start_stop_hook
)
1793 trace_start_stop_hook (1, from_tty
);
1797 error ("Trace can only be run on remote targets.");
1802 trace_stop_command (char *args
, int from_tty
)
1803 { /* STUB_COMM IS_IMPLEMENTED */
1804 if (target_is_remote ())
1807 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1808 if (strcmp (target_buf
, "OK"))
1809 error ("Bogus reply from target: %s", target_buf
);
1810 trace_running_p
= 0;
1811 if (trace_start_stop_hook
)
1812 trace_start_stop_hook (0, from_tty
);
1815 error ("Trace can only be run on remote targets.");
1818 unsigned long trace_running_p
;
1820 /* tstatus command */
1822 trace_status_command (char *args
, int from_tty
)
1823 { /* STUB_COMM IS_IMPLEMENTED */
1824 if (target_is_remote ())
1826 putpkt ("qTStatus");
1827 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1829 if (target_buf
[0] != 'T' ||
1830 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1831 error ("Bogus reply from target: %s", target_buf
);
1833 /* exported for use by the GUI */
1834 trace_running_p
= (target_buf
[1] == '1');
1837 error ("Trace can only be run on remote targets.");
1840 /* Worker function for the various flavors of the tfind command */
1842 finish_tfind_command (char *msg
,
1846 int target_frameno
= -1, target_tracept
= -1;
1847 CORE_ADDR old_frame_addr
;
1848 struct symbol
*old_func
;
1851 old_frame_addr
= FRAME_FP (get_current_frame ());
1852 old_func
= find_pc_function (read_pc ());
1855 reply
= remote_get_noisy_reply (msg
, sizeof_msg
);
1857 while (reply
&& *reply
)
1861 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1863 /* A request for a non-existant trace frame has failed.
1864 Our response will be different, depending on FROM_TTY:
1866 If FROM_TTY is true, meaning that this command was
1867 typed interactively by the user, then give an error
1868 and DO NOT change the state of traceframe_number etc.
1870 However if FROM_TTY is false, meaning that we're either
1871 in a script, a loop, or a user-defined command, then
1872 DON'T give an error, but DO change the state of
1873 traceframe_number etc. to invalid.
1875 The rationalle is that if you typed the command, you
1876 might just have committed a typo or something, and you'd
1877 like to NOT lose your current debugging state. However
1878 if you're in a user-defined command or especially in a
1879 loop, then you need a way to detect that the command
1880 failed WITHOUT aborting. This allows you to write
1881 scripts that search thru the trace buffer until the end,
1882 and then continue on to do something else. */
1885 error ("Target failed to find requested trace frame.");
1889 printf_filtered ("End of trace buffer.\n");
1890 /* The following will not recurse, since it's special-cased */
1891 trace_find_command ("-1", from_tty
);
1892 reply
= NULL
; /* break out of loop,
1893 (avoid recursive nonsense) */
1898 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1899 error ("Target failed to find requested trace frame.");
1901 case 'O': /* "OK"? */
1902 if (reply
[1] == 'K' && reply
[2] == '\0')
1905 error ("Bogus reply from target: %s", reply
);
1908 error ("Bogus reply from target: %s", reply
);
1911 flush_cached_frames ();
1912 registers_changed ();
1913 select_frame (get_current_frame (), 0);
1914 set_traceframe_num (target_frameno
);
1915 set_tracepoint_num (target_tracept
);
1916 if (target_frameno
== -1)
1917 set_traceframe_context (-1);
1919 set_traceframe_context (read_pc ());
1925 /* NOTE: in immitation of the step command, try to determine
1926 whether we have made a transition from one function to another.
1927 If so, we'll print the "stack frame" (ie. the new function and
1928 it's arguments) -- otherwise we'll just show the new source line.
1930 This determination is made by checking (1) whether the current
1931 function has changed, and (2) whether the current FP has changed.
1932 Hack: if the FP wasn't collected, either at the current or the
1933 previous frame, assume that the FP has NOT changed. */
1935 if (old_func
== find_pc_function (read_pc ()) &&
1936 (old_frame_addr
== 0 ||
1937 FRAME_FP (get_current_frame ()) == 0 ||
1938 old_frame_addr
== FRAME_FP (get_current_frame ())))
1943 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1948 /* trace_find_command takes a trace frame number n,
1949 sends "QTFrame:<n>" to the target,
1950 and accepts a reply that may contain several optional pieces
1951 of information: a frame number, a tracepoint number, and an
1952 indication of whether this is a trap frame or a stepping frame.
1954 The minimal response is just "OK" (which indicates that the
1955 target does not give us a frame number or a tracepoint number).
1956 Instead of that, the target may send us a string containing
1958 F<hexnum> (gives the selected frame number)
1959 T<hexnum> (gives the selected tracepoint number)
1964 trace_find_command (char *args
, int from_tty
)
1965 { /* STUB_COMM PART_IMPLEMENTED */
1966 /* this should only be called with a numeric argument */
1969 if (target_is_remote ())
1971 if (trace_find_hook
)
1972 trace_find_hook (args
, from_tty
);
1974 if (args
== 0 || *args
== 0)
1975 { /* TFIND with no args means find NEXT trace frame. */
1976 if (traceframe_number
== -1)
1977 frameno
= 0; /* "next" is first one */
1979 frameno
= traceframe_number
+ 1;
1981 else if (0 == strcmp (args
, "-"))
1983 if (traceframe_number
== -1)
1984 error ("not debugging trace buffer");
1985 else if (from_tty
&& traceframe_number
== 0)
1986 error ("already at start of trace buffer");
1988 frameno
= traceframe_number
- 1;
1991 frameno
= parse_and_eval_long (args
);
1994 error ("invalid input (%d is less than zero)", frameno
);
1996 sprintf (target_buf
, "QTFrame:%x", frameno
);
1997 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2000 error ("Trace can only be run on remote targets.");
2005 trace_find_end_command (char *args
, int from_tty
)
2007 trace_find_command ("-1", from_tty
);
2012 trace_find_none_command (char *args
, int from_tty
)
2014 trace_find_command ("-1", from_tty
);
2019 trace_find_start_command (char *args
, int from_tty
)
2021 trace_find_command ("0", from_tty
);
2024 /* tfind pc command */
2026 trace_find_pc_command (char *args
, int from_tty
)
2027 { /* STUB_COMM PART_IMPLEMENTED */
2031 if (target_is_remote ())
2033 if (args
== 0 || *args
== 0)
2034 pc
= read_pc (); /* default is current pc */
2036 pc
= parse_and_eval_address (args
);
2038 sprintf_vma (tmp
, pc
);
2039 sprintf (target_buf
, "QTFrame:pc:%s", tmp
);
2040 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2043 error ("Trace can only be run on remote targets.");
2046 /* tfind tracepoint command */
2048 trace_find_tracepoint_command (char *args
, int from_tty
)
2049 { /* STUB_COMM PART_IMPLEMENTED */
2052 if (target_is_remote ())
2054 if (args
== 0 || *args
== 0)
2055 if (tracepoint_number
== -1)
2056 error ("No current tracepoint -- please supply an argument.");
2058 tdp
= tracepoint_number
; /* default is current TDP */
2060 tdp
= parse_and_eval_long (args
);
2062 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2063 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2066 error ("Trace can only be run on remote targets.");
2069 /* TFIND LINE command:
2071 This command will take a sourceline for argument, just like BREAK
2072 or TRACE (ie. anything that "decode_line_1" can handle).
2074 With no argument, this command will find the next trace frame
2075 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2078 trace_find_line_command (char *args
, int from_tty
)
2079 { /* STUB_COMM PART_IMPLEMENTED */
2080 static CORE_ADDR start_pc
, end_pc
;
2081 struct symtabs_and_lines sals
;
2082 struct symtab_and_line sal
;
2083 struct cleanup
*old_chain
;
2084 char startpc_str
[40], endpc_str
[40];
2086 if (target_is_remote ())
2088 if (args
== 0 || *args
== 0)
2090 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2092 sals
.sals
= (struct symtab_and_line
*)
2093 xmalloc (sizeof (struct symtab_and_line
));
2098 sals
= decode_line_spec (args
, 1);
2102 old_chain
= make_cleanup (xfree
, sals
.sals
);
2103 if (sal
.symtab
== 0)
2105 printf_filtered ("TFIND: No line number information available");
2108 /* This is useful for "info line *0x7f34". If we can't tell the
2109 user about a source line, at least let them have the symbolic
2111 printf_filtered (" for address ");
2113 print_address (sal
.pc
, gdb_stdout
);
2114 printf_filtered (";\n -- will attempt to find by PC. \n");
2118 printf_filtered (".\n");
2119 return; /* no line, no PC; what can we do? */
2122 else if (sal
.line
> 0
2123 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2125 if (start_pc
== end_pc
)
2127 printf_filtered ("Line %d of \"%s\"",
2128 sal
.line
, sal
.symtab
->filename
);
2130 printf_filtered (" is at address ");
2131 print_address (start_pc
, gdb_stdout
);
2133 printf_filtered (" but contains no code.\n");
2134 sal
= find_pc_line (start_pc
, 0);
2136 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2138 printf_filtered ("Attempting to find line %d instead.\n",
2141 error ("Cannot find a good line.");
2145 /* Is there any case in which we get here, and have an address
2146 which the user would want to see? If we have debugging symbols
2147 and no line numbers? */
2148 error ("Line number %d is out of range for \"%s\".\n",
2149 sal
.line
, sal
.symtab
->filename
);
2151 sprintf_vma (startpc_str
, start_pc
);
2152 sprintf_vma (endpc_str
, end_pc
- 1);
2153 if (args
&& *args
) /* find within range of stated line */
2154 sprintf (target_buf
, "QTFrame:range:%s:%s", startpc_str
, endpc_str
);
2155 else /* find OUTSIDE OF range of CURRENT line */
2156 sprintf (target_buf
, "QTFrame:outside:%s:%s", startpc_str
, endpc_str
);
2157 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2158 do_cleanups (old_chain
);
2161 error ("Trace can only be run on remote targets.");
2164 /* tfind range command */
2166 trace_find_range_command (char *args
, int from_tty
)
2168 static CORE_ADDR start
, stop
;
2169 char start_str
[40], stop_str
[40];
2172 if (target_is_remote ())
2174 if (args
== 0 || *args
== 0)
2175 { /* XXX FIXME: what should default behavior be? */
2176 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2180 if (0 != (tmp
= strchr (args
, ',')))
2182 *tmp
++ = '\0'; /* terminate start address */
2183 while (isspace ((int) *tmp
))
2185 start
= parse_and_eval_address (args
);
2186 stop
= parse_and_eval_address (tmp
);
2189 { /* no explicit end address? */
2190 start
= parse_and_eval_address (args
);
2191 stop
= start
+ 1; /* ??? */
2194 sprintf_vma (start_str
, start
);
2195 sprintf_vma (stop_str
, stop
);
2196 sprintf (target_buf
, "QTFrame:range:%s:%s", start_str
, stop_str
);
2197 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2200 error ("Trace can only be run on remote targets.");
2203 /* tfind outside command */
2205 trace_find_outside_command (char *args
, int from_tty
)
2207 CORE_ADDR start
, stop
;
2208 char start_str
[40], stop_str
[40];
2211 if (target_is_remote ())
2213 if (args
== 0 || *args
== 0)
2214 { /* XXX FIXME: what should default behavior be? */
2215 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2219 if (0 != (tmp
= strchr (args
, ',')))
2221 *tmp
++ = '\0'; /* terminate start address */
2222 while (isspace ((int) *tmp
))
2224 start
= parse_and_eval_address (args
);
2225 stop
= parse_and_eval_address (tmp
);
2228 { /* no explicit end address? */
2229 start
= parse_and_eval_address (args
);
2230 stop
= start
+ 1; /* ??? */
2233 sprintf_vma (start_str
, start
);
2234 sprintf_vma (stop_str
, stop
);
2235 sprintf (target_buf
, "QTFrame:outside:%s:%s", start_str
, stop_str
);
2236 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2239 error ("Trace can only be run on remote targets.");
2242 /* save-tracepoints command */
2244 tracepoint_save_command (char *args
, int from_tty
)
2246 struct tracepoint
*tp
;
2247 struct action_line
*line
;
2249 char *i1
= " ", *i2
= " ";
2250 char *indent
, *actionline
;
2253 if (args
== 0 || *args
== 0)
2254 error ("Argument required (file name in which to save tracepoints");
2256 if (tracepoint_chain
== 0)
2258 warning ("save-tracepoints: no tracepoints to save.\n");
2262 if (!(fp
= fopen (args
, "w")))
2263 error ("Unable to open file '%s' for saving tracepoints");
2265 ALL_TRACEPOINTS (tp
)
2267 if (tp
->addr_string
)
2268 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2271 sprintf_vma (tmp
, tp
->address
);
2272 fprintf (fp
, "trace *0x%s\n", tmp
);
2276 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2280 fprintf (fp
, " actions\n");
2282 for (line
= tp
->actions
; line
; line
= line
->next
)
2284 struct cmd_list_element
*cmd
;
2286 QUIT
; /* allow user to bail out with ^C */
2287 actionline
= line
->action
;
2288 while (isspace ((int) *actionline
))
2291 fprintf (fp
, "%s%s\n", indent
, actionline
);
2292 if (*actionline
!= '#') /* skip for comment lines */
2294 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2296 error ("Bad action list item: %s", actionline
);
2297 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2299 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2307 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2311 /* info scope command: list the locals for a scope. */
2313 scope_info (char *args
, int from_tty
)
2315 struct symtabs_and_lines sals
;
2317 struct minimal_symbol
*msym
;
2318 struct block
*block
;
2319 char **canonical
, *symname
, *save_args
= args
;
2320 int i
, j
, nsyms
, count
= 0;
2322 if (args
== 0 || *args
== 0)
2323 error ("requires an argument (function, line or *addr) to define a scope");
2325 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2326 if (sals
.nelts
== 0)
2327 return; /* presumably decode_line_1 has already warned */
2329 /* Resolve line numbers to PC */
2330 resolve_sal_pc (&sals
.sals
[0]);
2331 block
= block_for_pc (sals
.sals
[0].pc
);
2335 QUIT
; /* allow user to bail out with ^C */
2336 nsyms
= BLOCK_NSYMS (block
);
2337 for (i
= 0; i
< nsyms
; i
++)
2339 QUIT
; /* allow user to bail out with ^C */
2341 printf_filtered ("Scope for %s:\n", save_args
);
2343 sym
= BLOCK_SYM (block
, i
);
2344 symname
= SYMBOL_NAME (sym
);
2345 if (symname
== NULL
|| *symname
== '\0')
2346 continue; /* probably botched, certainly useless */
2348 printf_filtered ("Symbol %s is ", symname
);
2349 switch (SYMBOL_CLASS (sym
))
2352 case LOC_UNDEF
: /* messed up symbol? */
2353 printf_filtered ("a bogus symbol, class %d.\n",
2354 SYMBOL_CLASS (sym
));
2355 count
--; /* don't count this one */
2358 printf_filtered ("a constant with value %ld (0x%lx)",
2359 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2361 case LOC_CONST_BYTES
:
2362 printf_filtered ("constant bytes: ");
2363 if (SYMBOL_TYPE (sym
))
2364 for (j
= 0; j
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); j
++)
2365 fprintf_filtered (gdb_stdout
, " %02x",
2366 (unsigned) SYMBOL_VALUE_BYTES (sym
)[j
]);
2369 printf_filtered ("in static storage at address ");
2370 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2373 printf_filtered ("a local variable in register $%s",
2374 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2378 printf_filtered ("an argument at stack/frame offset %ld",
2379 SYMBOL_VALUE (sym
));
2382 printf_filtered ("a local variable at frame offset %ld",
2383 SYMBOL_VALUE (sym
));
2386 printf_filtered ("a reference argument at offset %ld",
2387 SYMBOL_VALUE (sym
));
2390 printf_filtered ("an argument in register $%s",
2391 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2393 case LOC_REGPARM_ADDR
:
2394 printf_filtered ("the address of an argument, in register $%s",
2395 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2398 printf_filtered ("a typedef.\n");
2401 printf_filtered ("a label at address ");
2402 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2405 printf_filtered ("a function at address ");
2406 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2410 printf_filtered ("a variable at offset %ld from register $%s",
2412 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2414 case LOC_BASEREG_ARG
:
2415 printf_filtered ("an argument at offset %ld from register $%s",
2417 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2419 case LOC_UNRESOLVED
:
2420 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2422 printf_filtered ("Unresolved Static");
2425 printf_filtered ("static storage at address ");
2426 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2430 case LOC_OPTIMIZED_OUT
:
2431 printf_filtered ("optimized out.\n");
2434 if (SYMBOL_TYPE (sym
))
2435 printf_filtered (", length %d.\n",
2436 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2438 if (BLOCK_FUNCTION (block
))
2441 block
= BLOCK_SUPERBLOCK (block
);
2444 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2448 /* worker function (cleanup) */
2450 replace_comma (void *data
)
2458 trace_dump_command (char *args
, int from_tty
)
2460 struct tracepoint
*t
;
2461 struct action_line
*action
;
2462 char *action_exp
, *next_comma
;
2463 struct cleanup
*old_cleanups
;
2464 int stepping_actions
= 0;
2465 int stepping_frame
= 0;
2467 if (!target_is_remote ())
2469 error ("Trace can only be run on remote targets.");
2473 if (tracepoint_number
== -1)
2475 warning ("No current trace frame.");
2480 if (t
->number
== tracepoint_number
)
2484 error ("No known tracepoint matches 'current' tracepoint #%d.",
2487 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2489 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2490 tracepoint_number
, traceframe_number
);
2492 /* The current frame is a trap frame if the frame PC is equal
2493 to the tracepoint PC. If not, then the current frame was
2494 collected during single-stepping. */
2496 stepping_frame
= (t
->address
!= read_pc ());
2498 for (action
= t
->actions
; action
; action
= action
->next
)
2500 struct cmd_list_element
*cmd
;
2502 QUIT
; /* allow user to bail out with ^C */
2503 action_exp
= action
->action
;
2504 while (isspace ((int) *action_exp
))
2507 /* The collection actions to be done while stepping are
2508 bracketed by the commands "while-stepping" and "end". */
2510 if (*action_exp
== '#') /* comment line */
2513 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2515 error ("Bad action list item: %s", action_exp
);
2517 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2518 stepping_actions
= 1;
2519 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2520 stepping_actions
= 0;
2521 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2523 /* Display the collected data.
2524 For the trap frame, display only what was collected at the trap.
2525 Likewise for stepping frames, display only what was collected
2526 while stepping. This means that the two boolean variables,
2527 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2528 if (stepping_frame
== stepping_actions
)
2531 { /* repeat over a comma-separated list */
2532 QUIT
; /* allow user to bail out with ^C */
2533 if (*action_exp
== ',')
2535 while (isspace ((int) *action_exp
))
2538 next_comma
= strchr (action_exp
, ',');
2540 if (0 == strncasecmp (action_exp
, "$reg", 4))
2541 registers_info (NULL
, from_tty
);
2542 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2543 locals_info (NULL
, from_tty
);
2544 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2545 args_info (NULL
, from_tty
);
2550 make_cleanup (replace_comma
, next_comma
);
2553 printf_filtered ("%s = ", action_exp
);
2554 output_command (action_exp
, from_tty
);
2555 printf_filtered ("\n");
2559 action_exp
= next_comma
;
2561 while (action_exp
&& *action_exp
== ',');
2565 discard_cleanups (old_cleanups
);
2568 /* Convert the memory pointed to by mem into hex, placing result in buf.
2569 * Return a pointer to the last char put in buf (null)
2570 * "stolen" from sparc-stub.c
2573 static const char hexchars
[] = "0123456789abcdef";
2575 static unsigned char *
2576 mem2hex (unsigned char *mem
, unsigned char *buf
, int count
)
2584 *buf
++ = hexchars
[ch
>> 4];
2585 *buf
++ = hexchars
[ch
& 0xf];
2594 get_traceframe_number (void)
2596 return traceframe_number
;
2600 /* module initialization */
2602 _initialize_tracepoint (void)
2604 struct cmd_list_element
*c
;
2606 tracepoint_chain
= 0;
2607 tracepoint_count
= 0;
2608 traceframe_number
= -1;
2609 tracepoint_number
= -1;
2611 set_internalvar (lookup_internalvar ("tpnum"),
2612 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2613 set_internalvar (lookup_internalvar ("trace_frame"),
2614 value_from_longest (builtin_type_int
, (LONGEST
) - 1));
2616 if (tracepoint_list
.list
== NULL
)
2618 tracepoint_list
.listsize
= 128;
2619 tracepoint_list
.list
= xmalloc
2620 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2622 if (tracepoint_list
.aexpr_list
== NULL
)
2624 tracepoint_list
.aexpr_listsize
= 128;
2625 tracepoint_list
.aexpr_list
= xmalloc
2626 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2629 if (stepping_list
.list
== NULL
)
2631 stepping_list
.listsize
= 128;
2632 stepping_list
.list
= xmalloc
2633 (stepping_list
.listsize
* sizeof (struct memrange
));
2636 if (stepping_list
.aexpr_list
== NULL
)
2638 stepping_list
.aexpr_listsize
= 128;
2639 stepping_list
.aexpr_list
= xmalloc
2640 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2643 add_info ("scope", scope_info
,
2644 "List the variables local to a scope");
2646 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2647 "Tracing of program execution without stopping the program.",
2650 add_info ("tracepoints", tracepoints_info
,
2651 "Status of tracepoints, or tracepoint number NUMBER.\n\
2652 Convenience variable \"$tpnum\" contains the number of the\n\
2653 last tracepoint set.");
2655 add_info_alias ("tp", "tracepoints", 1);
2657 c
= add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2658 "Save current tracepoint definitions as a script.\n\
2659 Use the 'source' command in another debug session to restore them.");
2660 c
->completer
= filename_completer
;
2662 add_com ("tdump", class_trace
, trace_dump_command
,
2663 "Print everything collected at the current tracepoint.");
2665 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2666 "Select a trace frame;\n\
2667 No argument means forward by one frame; '-' meand backward by one frame.",
2668 &tfindlist
, "tfind ", 1, &cmdlist
);
2670 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2671 "Select a trace frame whose PC is outside the given \
2672 range.\nUsage: tfind outside addr1, addr2",
2675 add_cmd ("range", class_trace
, trace_find_range_command
,
2676 "Select a trace frame whose PC is in the given range.\n\
2677 Usage: tfind range addr1,addr2",
2680 add_cmd ("line", class_trace
, trace_find_line_command
,
2681 "Select a trace frame by source line.\n\
2682 Argument can be a line number (with optional source file), \n\
2683 a function name, or '*' followed by an address.\n\
2684 Default argument is 'the next source line that was traced'.",
2687 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2688 "Select a trace frame by tracepoint number.\n\
2689 Default is the tracepoint for the current trace frame.",
2692 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2693 "Select a trace frame by PC.\n\
2694 Default is the current PC, or the PC of the current trace frame.",
2697 add_cmd ("end", class_trace
, trace_find_end_command
,
2698 "Synonym for 'none'.\n\
2699 De-select any trace frame and resume 'live' debugging.",
2702 add_cmd ("none", class_trace
, trace_find_none_command
,
2703 "De-select any trace frame and resume 'live' debugging.",
2706 add_cmd ("start", class_trace
, trace_find_start_command
,
2707 "Select the first trace frame in the trace buffer.",
2710 add_com ("tstatus", class_trace
, trace_status_command
,
2711 "Display the status of the current trace data collection.");
2713 add_com ("tstop", class_trace
, trace_stop_command
,
2714 "Stop trace data collection.");
2716 add_com ("tstart", class_trace
, trace_start_command
,
2717 "Start trace data collection.");
2719 add_com ("passcount", class_trace
, trace_pass_command
,
2720 "Set the passcount for a tracepoint.\n\
2721 The trace will end when the tracepoint has been passed 'count' times.\n\
2722 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2723 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2725 add_com ("end", class_trace
, end_actions_pseudocommand
,
2726 "Ends a list of commands or actions.\n\
2727 Several GDB commands allow you to enter a list of commands or actions.\n\
2728 Entering \"end\" on a line by itself is the normal way to terminate\n\
2730 Note: the \"end\" command cannot be used at the gdb prompt.");
2732 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2733 "Specify single-stepping behavior at a tracepoint.\n\
2734 Argument is number of instructions to trace in single-step mode\n\
2735 following the tracepoint. This command is normally followed by\n\
2736 one or more \"collect\" commands, to specify what to collect\n\
2737 while single-stepping.\n\n\
2738 Note: this command can only be used in a tracepoint \"actions\" list.");
2740 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2741 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2743 add_com ("collect", class_trace
, collect_pseudocommand
,
2744 "Specify one or more data items to be collected at a tracepoint.\n\
2745 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2746 collect all data (variables, registers) referenced by that expression.\n\
2747 Also accepts the following special arguments:\n\
2748 $regs -- all registers.\n\
2749 $args -- all function arguments.\n\
2750 $locals -- all variables local to the block/function scope.\n\
2751 Note: this command can only be used in a tracepoint \"actions\" list.");
2753 add_com ("actions", class_trace
, trace_actions_command
,
2754 "Specify the actions to be taken at a tracepoint.\n\
2755 Tracepoint actions may include collecting of specified data, \n\
2756 single-stepping, or enabling/disabling other tracepoints, \n\
2757 depending on target's capabilities.");
2759 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2760 "Delete specified tracepoints.\n\
2761 Arguments are tracepoint numbers, separated by spaces.\n\
2762 No argument means delete all tracepoints.",
2765 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2766 "Disable specified tracepoints.\n\
2767 Arguments are tracepoint numbers, separated by spaces.\n\
2768 No argument means disable all tracepoints.",
2771 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2772 "Enable specified tracepoints.\n\
2773 Arguments are tracepoint numbers, separated by spaces.\n\
2774 No argument means enable all tracepoints.",
2777 add_com ("trace", class_trace
, trace_command
,
2778 "Set a tracepoint at a specified line or function or address.\n\
2779 Argument may be a line number, function name, or '*' plus an address.\n\
2780 For a line number or function, trace at the start of its code.\n\
2781 If an address is specified, trace at that exact address.\n\n\
2782 Do \"help tracepoints\" for info on other tracepoint commands.");
2784 add_com_alias ("tp", "trace", class_alias
, 0);
2785 add_com_alias ("tr", "trace", class_alias
, 1);
2786 add_com_alias ("tra", "trace", class_alias
, 1);
2787 add_com_alias ("trac", "trace", class_alias
, 1);