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"
39 /* readline include files */
40 #include <readline/readline.h>
41 #include <readline/history.h>
43 /* readline defines this. */
50 /* maximum length of an agent aexpression.
51 this accounts for the fact that packets are limited to 400 bytes
52 (which includes everything -- including the checksum), and assumes
53 the worst case of maximum length for each of the pieces of a
56 NOTE: expressions get mem2hex'ed otherwise this would be twice as
57 large. (400 - 31)/2 == 184 */
58 #define MAX_AGENT_EXPR_LEN 184
61 extern int info_verbose
;
62 extern void (*readline_begin_hook
) (char *, ...);
63 extern char *(*readline_hook
) (char *);
64 extern void (*readline_end_hook
) (void);
65 extern void x_command (char *, int);
66 extern int addressprint
; /* Print machine addresses? */
68 /* GDB commands implemented in other modules:
71 extern void output_command (char *, int);
72 extern void registers_info (char *, int);
73 extern void args_info (char *, int);
74 extern void locals_info (char *, int);
77 /* If this definition isn't overridden by the header files, assume
78 that isatty and fileno exist on this system. */
80 #define ISATTY(FP) (isatty (fileno (FP)))
86 This module defines the following debugger commands:
87 trace : set a tracepoint on a function, line, or address.
88 info trace : list all debugger-defined tracepoints.
89 delete trace : delete one or more tracepoints.
90 enable trace : enable one or more tracepoints.
91 disable trace : disable one or more tracepoints.
92 actions : specify actions to be taken at a tracepoint.
93 passcount : specify a pass count for a tracepoint.
94 tstart : start a trace experiment.
95 tstop : stop a trace experiment.
96 tstatus : query the status of a trace experiment.
97 tfind : find a trace frame in the trace buffer.
98 tdump : print everything collected at the current tracepoint.
99 save-tracepoints : write tracepoint setup into a file.
101 This module defines the following user-visible debugger variables:
102 $trace_frame : sequence number of trace frame currently being debugged.
103 $trace_line : source line of trace frame currently being debugged.
104 $trace_file : source file of trace frame currently being debugged.
105 $tracepoint : tracepoint number of trace frame currently being debugged.
109 /* ======= Important global variables: ======= */
111 /* Chain of all tracepoints defined. */
112 struct tracepoint
*tracepoint_chain
;
114 /* Number of last tracepoint made. */
115 static int tracepoint_count
;
117 /* Number of last traceframe collected. */
118 static int traceframe_number
;
120 /* Tracepoint for last traceframe collected. */
121 static int tracepoint_number
;
123 /* Symbol for function for last traceframe collected */
124 static struct symbol
*traceframe_fun
;
126 /* Symtab and line for last traceframe collected */
127 static struct symtab_and_line traceframe_sal
;
129 /* Tracing command lists */
130 static struct cmd_list_element
*tfindlist
;
132 /* ======= Important command functions: ======= */
133 static void trace_command (char *, int);
134 static void tracepoints_info (char *, int);
135 static void delete_trace_command (char *, int);
136 static void enable_trace_command (char *, int);
137 static void disable_trace_command (char *, int);
138 static void trace_pass_command (char *, int);
139 static void trace_actions_command (char *, int);
140 static void trace_start_command (char *, int);
141 static void trace_stop_command (char *, int);
142 static void trace_status_command (char *, int);
143 static void trace_find_command (char *, int);
144 static void trace_find_pc_command (char *, int);
145 static void trace_find_tracepoint_command (char *, int);
146 static void trace_find_line_command (char *, int);
147 static void trace_find_range_command (char *, int);
148 static void trace_find_outside_command (char *, int);
149 static void tracepoint_save_command (char *, int);
150 static void trace_dump_command (char *, int);
152 /* support routines */
153 static void trace_mention (struct tracepoint
*);
155 struct collection_list
;
156 static void add_aexpr (struct collection_list
*, struct agent_expr
*);
157 static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
158 static void add_register (struct collection_list
*collection
,
160 static struct cleanup
*make_cleanup_free_actions (struct tracepoint
*t
);
161 static void free_actions_list (char **actions_list
);
162 static void free_actions_list_cleanup_wrapper (void *);
164 extern void _initialize_tracepoint (void);
166 /* Utility: returns true if "target remote" */
168 target_is_remote (void)
170 if (current_target
.to_shortname
&&
171 strcmp (current_target
.to_shortname
, "remote") == 0)
177 /* Utility: generate error from an incoming stub packet. */
179 trace_error (char *buf
)
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 (int num
)
224 tracepoint_count
= num
;
225 set_internalvar (lookup_internalvar ("tpnum"),
226 value_from_longest (builtin_type_int
, (LONGEST
) num
));
229 /* Set traceframe number to NUM. */
231 set_traceframe_num (int num
)
233 traceframe_number
= num
;
234 set_internalvar (lookup_internalvar ("trace_frame"),
235 value_from_longest (builtin_type_int
, (LONGEST
) num
));
238 /* Set tracepoint number to NUM. */
240 set_tracepoint_num (int num
)
242 tracepoint_number
= num
;
243 set_internalvar (lookup_internalvar ("tracepoint"),
244 value_from_longest (builtin_type_int
, (LONGEST
) num
));
247 /* Set externally visible debug variables for querying/printing
248 the traceframe context (line, function, file) */
251 set_traceframe_context (CORE_ADDR trace_pc
)
253 static struct type
*func_string
, *file_string
;
254 static struct type
*func_range
, *file_range
;
255 static value_ptr func_val
, file_val
;
256 static struct type
*charstar
;
259 if (charstar
== (struct type
*) NULL
)
260 charstar
= lookup_pointer_type (builtin_type_char
);
262 if (trace_pc
== -1) /* cease debugging any trace buffers */
265 traceframe_sal
.pc
= traceframe_sal
.line
= 0;
266 traceframe_sal
.symtab
= NULL
;
267 set_internalvar (lookup_internalvar ("trace_func"),
268 value_from_pointer (charstar
, (LONGEST
) 0));
269 set_internalvar (lookup_internalvar ("trace_file"),
270 value_from_pointer (charstar
, (LONGEST
) 0));
271 set_internalvar (lookup_internalvar ("trace_line"),
272 value_from_pointer (builtin_type_int
, (LONGEST
) - 1));
276 /* save as globals for internal use */
277 traceframe_sal
= find_pc_line (trace_pc
, 0);
278 traceframe_fun
= find_pc_function (trace_pc
);
280 /* save linenumber as "$trace_line", a debugger variable visible to users */
281 set_internalvar (lookup_internalvar ("trace_line"),
282 value_from_longest (builtin_type_int
,
283 (LONGEST
) traceframe_sal
.line
));
285 /* save func name as "$trace_func", a debugger variable visible to users */
286 if (traceframe_fun
== NULL
||
287 SYMBOL_NAME (traceframe_fun
) == NULL
)
288 set_internalvar (lookup_internalvar ("trace_func"),
289 value_from_pointer (charstar
, (LONGEST
) 0));
292 len
= strlen (SYMBOL_NAME (traceframe_fun
));
293 func_range
= create_range_type (func_range
,
294 builtin_type_int
, 0, len
- 1);
295 func_string
= create_array_type (func_string
,
296 builtin_type_char
, func_range
);
297 func_val
= allocate_value (func_string
);
298 VALUE_TYPE (func_val
) = func_string
;
299 memcpy (VALUE_CONTENTS_RAW (func_val
),
300 SYMBOL_NAME (traceframe_fun
),
302 func_val
->modifiable
= 0;
303 set_internalvar (lookup_internalvar ("trace_func"), func_val
);
306 /* save file name as "$trace_file", a debugger variable visible to users */
307 if (traceframe_sal
.symtab
== NULL
||
308 traceframe_sal
.symtab
->filename
== NULL
)
309 set_internalvar (lookup_internalvar ("trace_file"),
310 value_from_pointer (charstar
, (LONGEST
) 0));
313 len
= strlen (traceframe_sal
.symtab
->filename
);
314 file_range
= create_range_type (file_range
,
315 builtin_type_int
, 0, len
- 1);
316 file_string
= create_array_type (file_string
,
317 builtin_type_char
, file_range
);
318 file_val
= allocate_value (file_string
);
319 VALUE_TYPE (file_val
) = file_string
;
320 memcpy (VALUE_CONTENTS_RAW (file_val
),
321 traceframe_sal
.symtab
->filename
,
323 file_val
->modifiable
= 0;
324 set_internalvar (lookup_internalvar ("trace_file"), file_val
);
328 /* Low level routine to set a tracepoint.
329 Returns the tracepoint object so caller can set other things.
330 Does not set the tracepoint number!
331 Does not print anything.
333 ==> This routine should not be called if there is a chance of later
334 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
335 your arguments BEFORE calling this routine! */
337 static struct tracepoint
*
338 set_raw_tracepoint (struct symtab_and_line sal
)
340 register struct tracepoint
*t
, *tc
;
341 struct cleanup
*old_chain
;
343 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
344 old_chain
= make_cleanup (xfree
, t
);
345 memset (t
, 0, sizeof (*t
));
347 if (sal
.symtab
== NULL
)
348 t
->source_file
= NULL
;
350 t
->source_file
= savestring (sal
.symtab
->filename
,
351 strlen (sal
.symtab
->filename
));
353 t
->section
= sal
.section
;
354 t
->language
= current_language
->la_language
;
355 t
->input_radix
= input_radix
;
356 t
->line_number
= sal
.line
;
357 t
->enabled
= enabled
;
361 t
->addr_string
= NULL
;
363 /* Add this tracepoint to the end of the chain
364 so that a list of tracepoints will come out in order
365 of increasing numbers. */
367 tc
= tracepoint_chain
;
369 tracepoint_chain
= t
;
376 discard_cleanups (old_chain
);
380 /* Set a tracepoint according to ARG (function, linenum or *address) */
382 trace_command (char *arg
, int from_tty
)
384 char **canonical
= (char **) NULL
;
385 struct symtabs_and_lines sals
;
386 struct symtab_and_line sal
;
387 struct tracepoint
*t
;
388 char *addr_start
= 0, *addr_end
= 0;
392 error ("trace command requires an argument");
394 if (from_tty
&& info_verbose
)
395 printf_filtered ("TRACE %s\n", arg
);
398 sals
= decode_line_1 (&arg
, 1, (struct symtab
*) NULL
, 0, &canonical
);
401 return; /* ??? Presumably decode_line_1 has already warned? */
403 /* Resolve all line numbers to PC's */
404 for (i
= 0; i
< sals
.nelts
; i
++)
405 resolve_sal_pc (&sals
.sals
[i
]);
407 /* Now set all the tracepoints. */
408 for (i
= 0; i
< sals
.nelts
; i
++)
412 t
= set_raw_tracepoint (sal
);
413 set_tracepoint_count (tracepoint_count
+ 1);
414 t
->number
= tracepoint_count
;
416 /* If a canonical line spec is needed use that instead of the
418 if (canonical
!= (char **) NULL
&& canonical
[i
] != NULL
)
419 t
->addr_string
= canonical
[i
];
421 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
425 /* Let the UI know of any additions */
426 if (create_tracepoint_hook
)
427 create_tracepoint_hook (t
);
432 printf_filtered ("Multiple tracepoints were set.\n");
433 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
437 /* Tell the user we have just set a tracepoint TP. */
440 trace_mention (struct tracepoint
*tp
)
442 printf_filtered ("Tracepoint %d", tp
->number
);
444 if (addressprint
|| (tp
->source_file
== NULL
))
446 printf_filtered (" at ");
447 print_address_numeric (tp
->address
, 1, gdb_stdout
);
450 printf_filtered (": file %s, line %d.",
451 tp
->source_file
, tp
->line_number
);
453 printf_filtered ("\n");
456 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
459 tracepoints_info (char *tpnum_exp
, int from_tty
)
461 struct tracepoint
*t
;
462 struct action_line
*action
;
463 int found_a_tracepoint
= 0;
464 char wrap_indent
[80];
469 tpnum
= parse_and_eval_long (tpnum_exp
);
472 if (tpnum
== -1 || tpnum
== t
->number
)
474 extern int addressprint
; /* print machine addresses? */
476 if (!found_a_tracepoint
++)
478 printf_filtered ("Num Enb ");
480 printf_filtered ("Address ");
481 printf_filtered ("PassC StepC What\n");
483 strcpy (wrap_indent
, " ");
485 strcat (wrap_indent
, " ");
487 printf_filtered ("%-3d %-3s ", t
->number
,
488 t
->enabled
== enabled
? "y" : "n");
490 printf_filtered ("%s ",
491 local_hex_string_custom ((unsigned long) t
->address
,
493 printf_filtered ("%-5d %-5ld ", t
->pass_count
, t
->step_count
);
497 sym
= find_pc_sect_function (t
->address
, t
->section
);
500 fputs_filtered ("in ", gdb_stdout
);
501 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
502 wrap_here (wrap_indent
);
503 fputs_filtered (" at ", gdb_stdout
);
505 fputs_filtered (t
->source_file
, gdb_stdout
);
506 printf_filtered (":%d", t
->line_number
);
509 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
511 printf_filtered ("\n");
514 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
515 for (action
= t
->actions
; action
; action
= action
->next
)
517 printf_filtered ("\t%s\n", action
->action
);
521 if (!found_a_tracepoint
)
524 printf_filtered ("No tracepoints.\n");
526 printf_filtered ("No tracepoint number %d.\n", tpnum
);
530 /* Optimization: the code to parse an enable, disable, or delete TP command
531 is virtually identical except for whether it performs an enable, disable,
532 or delete. Therefore I've combined them into one function with an opcode.
534 enum tracepoint_opcode
541 /* This function implements enable, disable and delete commands. */
543 tracepoint_operation (struct tracepoint
*t
, int from_tty
,
544 enum tracepoint_opcode opcode
)
546 struct tracepoint
*t2
;
548 if (t
== NULL
) /* no tracepoint operand */
554 t
->enabled
= enabled
;
555 if (modify_tracepoint_hook
)
556 modify_tracepoint_hook (t
);
559 t
->enabled
= disabled
;
560 if (modify_tracepoint_hook
)
561 modify_tracepoint_hook (t
);
564 if (tracepoint_chain
== t
)
565 tracepoint_chain
= t
->next
;
574 /* Let the UI know of any deletions */
575 if (delete_tracepoint_hook
)
576 delete_tracepoint_hook (t
);
579 xfree (t
->addr_string
);
581 xfree (t
->source_file
);
590 /* Utility: parse a tracepoint number and look it up in the list.
591 If MULTI_P is true, there might be a range of tracepoints in ARG.
592 if OPTIONAL_P is true, then if the argument is missing, the most
593 recent tracepoint (tracepoint_count) is returned. */
595 get_tracepoint_by_number (char **arg
, int multi_p
, int optional_p
)
597 struct tracepoint
*t
;
599 char *instring
= arg
== NULL
? NULL
: *arg
;
601 if (arg
== NULL
|| *arg
== NULL
|| ! **arg
)
604 tpnum
= tracepoint_count
;
606 error_no_arg ("tracepoint number");
609 tpnum
= multi_p
? get_number_or_range (arg
) : get_number (arg
);
613 if (instring
&& *instring
)
614 printf_filtered ("bad tracepoint number at or near '%s'\n", instring
);
616 printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
621 if (t
->number
== tpnum
)
626 /* FIXME: if we are in the middle of a range we don't want to give
627 a message. The current interface to get_number_or_range doesn't
628 allow us to discover this. */
629 printf_unfiltered ("No tracepoint number %d.\n", tpnum
);
633 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
635 map_args_over_tracepoints (char *args
, int from_tty
,
636 enum tracepoint_opcode opcode
)
638 struct tracepoint
*t
, *tmp
;
640 if (args
== 0 || *args
== 0) /* do them all */
641 ALL_TRACEPOINTS_SAFE (t
, tmp
)
642 tracepoint_operation (t
, from_tty
, opcode
);
646 QUIT
; /* give user option to bail out with ^C */
647 t
= get_tracepoint_by_number (&args
, 1, 0);
648 tracepoint_operation (t
, from_tty
, opcode
);
649 while (*args
== ' ' || *args
== '\t')
654 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
656 enable_trace_command (char *args
, int from_tty
)
659 map_args_over_tracepoints (args
, from_tty
, enable_op
);
662 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
664 disable_trace_command (char *args
, int from_tty
)
667 map_args_over_tracepoints (args
, from_tty
, disable_op
);
670 /* Remove a tracepoint (or all if no argument) */
672 delete_trace_command (char *args
, int from_tty
)
675 if (!args
|| !*args
) /* No args implies all tracepoints; */
676 if (from_tty
) /* confirm only if from_tty... */
677 if (tracepoint_chain
) /* and if there are tracepoints to delete! */
678 if (!query ("Delete all tracepoints? "))
681 map_args_over_tracepoints (args
, from_tty
, delete_op
);
684 /* Set passcount for tracepoint.
686 First command argument is passcount, second is tracepoint number.
687 If tracepoint number omitted, apply to most recently defined.
688 Also accepts special argument "all". */
691 trace_pass_command (char *args
, int from_tty
)
693 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
697 if (args
== 0 || *args
== 0)
698 error ("passcount command requires an argument (count + optional TP num)");
700 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
702 while (*args
&& isspace ((int) *args
))
705 if (*args
&& strncasecmp (args
, "all", 3) == 0)
707 args
+= 3; /* skip special argument "all" */
710 error ("Junk at end of arguments.");
713 t1
= get_tracepoint_by_number (&args
, 1, 1);
720 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
722 t2
->pass_count
= count
;
723 if (modify_tracepoint_hook
)
724 modify_tracepoint_hook (t2
);
726 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
730 t1
= get_tracepoint_by_number (&args
, 1, 0);
736 /* ACTIONS functions: */
738 /* Prototypes for action-parsing utility commands */
739 static void read_actions (struct tracepoint
*);
741 /* The three functions:
742 collect_pseudocommand,
743 while_stepping_pseudocommand, and
744 end_actions_pseudocommand
745 are placeholders for "commands" that are actually ONLY to be used
746 within a tracepoint action list. If the actual function is ever called,
747 it means that somebody issued the "command" at the top level,
748 which is always an error. */
751 end_actions_pseudocommand (char *args
, int from_tty
)
753 error ("This command cannot be used at the top level.");
757 while_stepping_pseudocommand (char *args
, int from_tty
)
759 error ("This command can only be used in a tracepoint actions list.");
763 collect_pseudocommand (char *args
, int from_tty
)
765 error ("This command can only be used in a tracepoint actions list.");
768 /* Enter a list of actions for a tracepoint. */
770 trace_actions_command (char *args
, int from_tty
)
772 struct tracepoint
*t
;
774 char *end_msg
= "End with a line saying just \"end\".";
776 t
= get_tracepoint_by_number (&args
, 0, 1);
779 sprintf (tmpbuf
, "Enter actions for tracepoint %d, one per line.",
784 if (readline_begin_hook
)
785 (*readline_begin_hook
) ("%s %s\n", tmpbuf
, end_msg
);
786 else if (input_from_terminal_p ())
787 printf_filtered ("%s\n%s\n", tmpbuf
, end_msg
);
791 t
->step_count
= 0; /* read_actions may set this */
794 if (readline_end_hook
)
795 (*readline_end_hook
) ();
796 /* tracepoints_changed () */
798 /* else just return */
801 /* worker function */
803 read_actions (struct tracepoint
*t
)
806 char *prompt1
= "> ", *prompt2
= " > ";
807 char *prompt
= prompt1
;
808 enum actionline_type linetype
;
809 extern FILE *instream
;
810 struct action_line
*next
= NULL
, *temp
;
811 struct cleanup
*old_chain
;
813 /* Control-C quits instantly if typed while in this loop
814 since it should not wait until the user types a newline. */
820 signal (STOP_SIGNAL
, handle_stop_sig
);
822 signal (STOP_SIGNAL
, stop_sig
);
825 old_chain
= make_cleanup_free_actions (t
);
828 /* Make sure that all output has been output. Some machines may let
829 you get away with leaving out some of the gdb_flush, but not all. */
831 gdb_flush (gdb_stdout
);
832 gdb_flush (gdb_stderr
);
834 if (readline_hook
&& instream
== NULL
)
835 line
= (*readline_hook
) (prompt
);
836 else if (instream
== stdin
&& ISATTY (instream
))
838 line
= readline (prompt
);
839 if (line
&& *line
) /* add it to command history */
843 line
= gdb_readline (0);
845 linetype
= validate_actionline (&line
, t
);
846 if (linetype
== BADLINE
)
847 continue; /* already warned -- collect another line */
849 temp
= xmalloc (sizeof (struct action_line
));
853 if (next
== NULL
) /* first action for this tracepoint? */
854 t
->actions
= next
= temp
;
861 if (linetype
== STEPPING
) /* begin "while-stepping" */
863 if (prompt
== prompt2
)
865 warning ("Already processing 'while-stepping'");
869 prompt
= prompt2
; /* change prompt for stepping actions */
871 else if (linetype
== END
)
873 if (prompt
== prompt2
)
875 prompt
= prompt1
; /* end of single-stepping actions */
878 { /* end of actions */
879 if (t
->actions
->next
== NULL
)
881 /* an "end" all by itself with no other actions means
882 this tracepoint has no actions. Discard empty list. */
891 signal (STOP_SIGNAL
, SIG_DFL
);
894 discard_cleanups (old_chain
);
897 /* worker function */
899 validate_actionline (char **line
, struct tracepoint
*t
)
901 struct cmd_list_element
*c
;
902 struct expression
*exp
= NULL
;
903 struct cleanup
*old_chain
= NULL
;
906 for (p
= *line
; isspace ((int) *p
);)
909 /* symbol lookup etc. */
910 if (*p
== '\0') /* empty line: just prompt for another line. */
913 if (*p
== '#') /* comment line */
916 c
= lookup_cmd (&p
, cmdlist
, "", -1, 1);
919 warning ("'%s' is not an action that I know, or is ambiguous.", p
);
923 if (c
->function
.cfunc
== collect_pseudocommand
)
925 struct agent_expr
*aexpr
;
926 struct agent_reqs areqs
;
929 { /* repeat over a comma-separated list */
930 QUIT
; /* allow user to bail out with ^C */
931 while (isspace ((int) *p
))
934 if (*p
== '$') /* look for special pseudo-symbols */
936 if ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
937 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
938 (0 == strncasecmp ("loc", p
+ 1, 3)))
943 /* else fall thru, treat p as an expression and parse it! */
945 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
946 old_chain
= make_cleanup (free_current_contents
, &exp
);
948 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
950 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
952 warning ("constant %s (value %ld) will not be collected.",
953 SYMBOL_NAME (exp
->elts
[2].symbol
),
954 SYMBOL_VALUE (exp
->elts
[2].symbol
));
957 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
959 warning ("%s is optimized away and cannot be collected.",
960 SYMBOL_NAME (exp
->elts
[2].symbol
));
965 /* we have something to collect, make sure that the expr to
966 bytecode translator can handle it and that it's not too long */
967 aexpr
= gen_trace_for_expr (t
->address
, exp
);
968 make_cleanup_free_agent_expr (aexpr
);
970 if (aexpr
->len
> MAX_AGENT_EXPR_LEN
)
971 error ("expression too complicated, try simplifying");
973 ax_reqs (aexpr
, &areqs
);
974 (void) make_cleanup (xfree
, areqs
.reg_mask
);
976 if (areqs
.flaw
!= agent_flaw_none
)
977 error ("malformed expression");
979 if (areqs
.min_height
< 0)
980 error ("gdb: Internal error: expression has min height < 0");
982 if (areqs
.max_height
> 20)
983 error ("expression too complicated, try simplifying");
985 do_cleanups (old_chain
);
987 while (p
&& *p
++ == ',');
990 else if (c
->function
.cfunc
== while_stepping_pseudocommand
)
992 char *steparg
; /* in case warning is necessary */
994 while (isspace ((int) *p
))
999 (t
->step_count
= strtol (p
, &p
, 0)) == 0)
1001 warning ("'%s': bad step-count; command ignored.", *line
);
1006 else if (c
->function
.cfunc
== end_actions_pseudocommand
)
1010 warning ("'%s' is not a supported tracepoint action.", *line
);
1015 /* worker function */
1017 free_actions (struct tracepoint
*t
)
1019 struct action_line
*line
, *next
;
1021 for (line
= t
->actions
; line
; line
= next
)
1025 xfree (line
->action
);
1032 do_free_actions_cleanup (void *t
)
1037 static struct cleanup
*
1038 make_cleanup_free_actions (struct tracepoint
*t
)
1040 return make_cleanup (do_free_actions_cleanup
, t
);
1045 int type
; /* 0 for absolute memory range, else basereg number */
1046 bfd_signed_vma start
;
1050 struct collection_list
1052 unsigned char regs_mask
[8]; /* room for up to 256 regs */
1055 struct memrange
*list
;
1056 long aexpr_listsize
; /* size of array pointed to by expr_list elt */
1057 long next_aexpr_elt
;
1058 struct agent_expr
**aexpr_list
;
1061 tracepoint_list
, stepping_list
;
1063 /* MEMRANGE functions: */
1065 static int memrange_cmp (const void *, const void *);
1067 /* compare memranges for qsort */
1069 memrange_cmp (const void *va
, const void *vb
)
1071 const struct memrange
*a
= va
, *b
= vb
;
1073 if (a
->type
< b
->type
)
1075 if (a
->type
> b
->type
)
1079 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
)
1081 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
)
1086 if (a
->start
< b
->start
)
1088 if (a
->start
> b
->start
)
1094 /* Sort the memrange list using qsort, and merge adjacent memranges */
1096 memrange_sortmerge (struct collection_list
*memranges
)
1100 qsort (memranges
->list
, memranges
->next_memrange
,
1101 sizeof (struct memrange
), memrange_cmp
);
1102 if (memranges
->next_memrange
> 0)
1104 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
1106 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
1107 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
1108 MAX_REGISTER_VIRTUAL_SIZE
)
1110 /* memrange b starts before memrange a ends; merge them. */
1111 if (memranges
->list
[b
].end
> memranges
->list
[a
].end
)
1112 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
1113 continue; /* next b, same a */
1117 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
1118 sizeof (struct memrange
));
1120 memranges
->next_memrange
= a
+ 1;
1124 /* Add a register to a collection list */
1126 add_register (struct collection_list
*collection
, unsigned int regno
)
1129 printf_filtered ("collect register %d\n", regno
);
1130 if (regno
> (8 * sizeof (collection
->regs_mask
)))
1131 error ("Internal: register number %d too large for tracepoint",
1133 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
1136 /* Add a memrange to a collection list */
1138 add_memrange (struct collection_list
*memranges
, int type
, bfd_signed_vma base
,
1143 printf_filtered ("(%d,", type
);
1145 printf_filtered (",%ld)\n", len
);
1148 /* type: 0 == memory, n == basereg */
1149 memranges
->list
[memranges
->next_memrange
].type
= type
;
1150 /* base: addr if memory, offset if reg relative. */
1151 memranges
->list
[memranges
->next_memrange
].start
= base
;
1152 /* len: we actually save end (base + len) for convenience */
1153 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
1154 memranges
->next_memrange
++;
1155 if (memranges
->next_memrange
>= memranges
->listsize
)
1157 memranges
->listsize
*= 2;
1158 memranges
->list
= xrealloc (memranges
->list
,
1159 memranges
->listsize
);
1162 if (type
!= -1) /* better collect the base register! */
1163 add_register (memranges
, type
);
1166 /* Add a symbol to a collection list */
1168 collect_symbol (struct collection_list
*collect
, struct symbol
*sym
,
1169 long frame_regno
, long frame_offset
)
1173 bfd_signed_vma offset
;
1175 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
1176 switch (SYMBOL_CLASS (sym
))
1179 printf_filtered ("%s: don't know symbol class %d\n",
1180 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
1183 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1184 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
1187 offset
= SYMBOL_VALUE_ADDRESS (sym
);
1192 sprintf_vma (tmp
, offset
);
1193 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1194 SYMBOL_NAME (sym
), len
, tmp
/* address */);
1196 add_memrange (collect
, -1, offset
, len
); /* 0 == memory */
1200 reg
= SYMBOL_VALUE (sym
);
1202 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
1203 add_register (collect
, reg
);
1204 /* check for doubles stored in two registers */
1205 /* FIXME: how about larger types stored in 3 or more regs? */
1206 if (TYPE_CODE (SYMBOL_TYPE (sym
)) == TYPE_CODE_FLT
&&
1207 len
> REGISTER_RAW_SIZE (reg
))
1208 add_register (collect
, reg
+ 1);
1211 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1212 printf_filtered (" (will not collect %s)\n",
1217 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1220 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1221 SYMBOL_NAME (sym
), len
);
1222 printf_vma (offset
);
1223 printf_filtered (" from frame ptr reg %d\n", reg
);
1225 add_memrange (collect
, reg
, offset
, len
);
1227 case LOC_REGPARM_ADDR
:
1228 reg
= SYMBOL_VALUE (sym
);
1232 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1233 SYMBOL_NAME (sym
), len
);
1234 printf_vma (offset
);
1235 printf_filtered (" from reg %d\n", reg
);
1237 add_memrange (collect
, reg
, offset
, len
);
1242 offset
= frame_offset
+ SYMBOL_VALUE (sym
);
1245 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1246 SYMBOL_NAME (sym
), len
);
1247 printf_vma (offset
);
1248 printf_filtered (" from frame ptr reg %d\n", reg
);
1250 add_memrange (collect
, reg
, offset
, len
);
1253 case LOC_BASEREG_ARG
:
1254 reg
= SYMBOL_BASEREG (sym
);
1255 offset
= SYMBOL_VALUE (sym
);
1258 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1259 SYMBOL_NAME (sym
), len
);
1260 printf_vma (offset
);
1261 printf_filtered (" from basereg %d\n", reg
);
1263 add_memrange (collect
, reg
, offset
, len
);
1265 case LOC_UNRESOLVED
:
1266 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
1268 case LOC_OPTIMIZED_OUT
:
1269 printf_filtered ("%s has been optimized out of existence.\n",
1275 /* Add all locals (or args) symbols to collection list */
1277 add_local_symbols (struct collection_list
*collect
, CORE_ADDR pc
,
1278 long frame_regno
, long frame_offset
, int type
)
1281 struct block
*block
;
1282 int i
, nsyms
, count
= 0;
1284 block
= block_for_pc (pc
);
1287 QUIT
; /* allow user to bail out with ^C */
1288 nsyms
= BLOCK_NSYMS (block
);
1289 for (i
= 0; i
< nsyms
; i
++)
1291 sym
= BLOCK_SYM (block
, i
);
1292 switch (SYMBOL_CLASS (sym
))
1295 warning ("don't know how to trace local symbol %s",
1301 if (type
== 'L') /* collecting Locals */
1304 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1311 case LOC_REGPARM_ADDR
:
1312 case LOC_BASEREG_ARG
:
1313 if (type
== 'A') /* collecting Arguments */
1316 collect_symbol (collect
, sym
, frame_regno
, frame_offset
);
1320 if (BLOCK_FUNCTION (block
))
1323 block
= BLOCK_SUPERBLOCK (block
);
1326 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1329 /* worker function */
1331 clear_collection_list (struct collection_list
*list
)
1335 list
->next_memrange
= 0;
1336 for (ndx
= 0; ndx
< list
->next_aexpr_elt
; ndx
++)
1338 free_agent_expr (list
->aexpr_list
[ndx
]);
1339 list
->aexpr_list
[ndx
] = NULL
;
1341 list
->next_aexpr_elt
= 0;
1342 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1345 /* reduce a collection list to string form (for gdb protocol) */
1347 stringify_collection_list (struct collection_list
*list
, char *string
)
1349 char temp_buf
[2048];
1353 char *(*str_list
)[];
1357 count
= 1 + list
->next_memrange
+ list
->next_aexpr_elt
+ 1;
1358 str_list
= (char *(*)[]) xmalloc (count
* sizeof (char *));
1360 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1361 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1363 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1366 printf_filtered ("\nCollecting registers (mask): 0x");
1371 QUIT
; /* allow user to bail out with ^C */
1373 printf_filtered ("%02X", list
->regs_mask
[i
]);
1374 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1377 (*str_list
)[ndx
] = savestring (temp_buf
, end
- temp_buf
);
1381 printf_filtered ("\n");
1382 if (list
->next_memrange
> 0 && info_verbose
)
1383 printf_filtered ("Collecting memranges: \n");
1384 for (i
= 0, count
= 0, end
= temp_buf
; i
< list
->next_memrange
; i
++)
1386 QUIT
; /* allow user to bail out with ^C */
1387 sprintf_vma (tmp2
, list
->list
[i
].start
);
1390 printf_filtered ("(%d, %s, %ld)\n",
1393 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1395 if (count
+ 27 > MAX_AGENT_EXPR_LEN
)
1397 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1403 sprintf (end
, "M%X,%s,%lX",
1406 (long) (list
->list
[i
].end
- list
->list
[i
].start
));
1408 count
+= strlen (end
);
1412 for (i
= 0; i
< list
->next_aexpr_elt
; i
++)
1414 QUIT
; /* allow user to bail out with ^C */
1415 if ((count
+ 10 + 2 * list
->aexpr_list
[i
]->len
) > MAX_AGENT_EXPR_LEN
)
1417 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1422 sprintf (end
, "X%08X,", list
->aexpr_list
[i
]->len
);
1423 end
+= 10; /* 'X' + 8 hex digits + ',' */
1426 end
= mem2hex (list
->aexpr_list
[i
]->buf
, end
, list
->aexpr_list
[i
]->len
);
1427 count
+= 2 * list
->aexpr_list
[i
]->len
;
1432 (*str_list
)[ndx
] = savestring (temp_buf
, count
);
1437 (*str_list
)[ndx
] = NULL
;
1446 free_actions_list_cleanup_wrapper (void *al
)
1448 free_actions_list (al
);
1452 free_actions_list (char **actions_list
)
1456 if (actions_list
== 0)
1459 for (ndx
= 0; actions_list
[ndx
]; ndx
++)
1460 xfree (actions_list
[ndx
]);
1462 xfree (actions_list
);
1465 /* render all actions into gdb protocol */
1467 encode_actions (struct tracepoint
*t
, char ***tdp_actions
,
1468 char ***stepping_actions
)
1470 static char tdp_buff
[2048], step_buff
[2048];
1472 struct expression
*exp
= NULL
;
1473 struct action_line
*action
;
1476 struct collection_list
*collect
;
1477 struct cmd_list_element
*cmd
;
1478 struct agent_expr
*aexpr
;
1479 long frame_reg
, frame_offset
;
1482 clear_collection_list (&tracepoint_list
);
1483 clear_collection_list (&stepping_list
);
1484 collect
= &tracepoint_list
;
1486 *tdp_actions
= NULL
;
1487 *stepping_actions
= NULL
;
1489 TARGET_VIRTUAL_FRAME_POINTER (t
->address
, &frame_reg
, &frame_offset
);
1491 for (action
= t
->actions
; action
; action
= action
->next
)
1493 QUIT
; /* allow user to bail out with ^C */
1494 action_exp
= action
->action
;
1495 while (isspace ((int) *action_exp
))
1498 if (*action_exp
== '#') /* comment line */
1501 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
1503 error ("Bad action list item: %s", action_exp
);
1505 if (cmd
->function
.cfunc
== collect_pseudocommand
)
1508 { /* repeat over a comma-separated list */
1509 QUIT
; /* allow user to bail out with ^C */
1510 while (isspace ((int) *action_exp
))
1513 if (0 == strncasecmp ("$reg", action_exp
, 4))
1515 for (i
= 0; i
< NUM_REGS
; i
++)
1516 add_register (collect
, i
);
1517 action_exp
= strchr (action_exp
, ','); /* more? */
1519 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1521 add_local_symbols (collect
,
1526 action_exp
= strchr (action_exp
, ','); /* more? */
1528 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1530 add_local_symbols (collect
,
1535 action_exp
= strchr (action_exp
, ','); /* more? */
1539 unsigned long addr
, len
;
1540 struct cleanup
*old_chain
= NULL
;
1541 struct cleanup
*old_chain1
= NULL
;
1542 struct agent_reqs areqs
;
1544 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1545 old_chain
= make_cleanup (free_current_contents
, &exp
);
1547 switch (exp
->elts
[0].opcode
)
1550 i
= exp
->elts
[1].longconst
;
1552 printf_filtered ("OP_REGISTER: ");
1553 add_register (collect
, i
);
1557 /* safe because we know it's a simple expression */
1558 tempval
= evaluate_expression (exp
);
1559 addr
= VALUE_ADDRESS (tempval
) + VALUE_OFFSET (tempval
);
1560 len
= TYPE_LENGTH (check_typedef (exp
->elts
[1].type
));
1561 add_memrange (collect
, -1, addr
, len
);
1565 collect_symbol (collect
,
1566 exp
->elts
[2].symbol
,
1571 default: /* full-fledged expression */
1572 aexpr
= gen_trace_for_expr (t
->address
, exp
);
1574 old_chain1
= make_cleanup_free_agent_expr (aexpr
);
1576 ax_reqs (aexpr
, &areqs
);
1577 if (areqs
.flaw
!= agent_flaw_none
)
1578 error ("malformed expression");
1580 if (areqs
.min_height
< 0)
1581 error ("gdb: Internal error: expression has min height < 0");
1582 if (areqs
.max_height
> 20)
1583 error ("expression too complicated, try simplifying");
1585 discard_cleanups (old_chain1
);
1586 add_aexpr (collect
, aexpr
);
1588 /* take care of the registers */
1589 if (areqs
.reg_mask_len
> 0)
1594 for (ndx1
= 0; ndx1
< areqs
.reg_mask_len
; ndx1
++)
1596 QUIT
; /* allow user to bail out with ^C */
1597 if (areqs
.reg_mask
[ndx1
] != 0)
1599 /* assume chars have 8 bits */
1600 for (ndx2
= 0; ndx2
< 8; ndx2
++)
1601 if (areqs
.reg_mask
[ndx1
] & (1 << ndx2
))
1602 /* it's used -- record it */
1603 add_register (collect
, ndx1
* 8 + ndx2
);
1609 do_cleanups (old_chain
);
1612 while (action_exp
&& *action_exp
++ == ',');
1614 else if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
1616 collect
= &stepping_list
;
1618 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
1620 if (collect
== &stepping_list
) /* end stepping actions */
1621 collect
= &tracepoint_list
;
1623 break; /* end tracepoint actions */
1626 memrange_sortmerge (&tracepoint_list
);
1627 memrange_sortmerge (&stepping_list
);
1629 *tdp_actions
= stringify_collection_list (&tracepoint_list
, tdp_buff
);
1630 *stepping_actions
= stringify_collection_list (&stepping_list
, step_buff
);
1634 add_aexpr (struct collection_list
*collect
, struct agent_expr
*aexpr
)
1636 if (collect
->next_aexpr_elt
>= collect
->aexpr_listsize
)
1638 collect
->aexpr_list
=
1639 xrealloc (collect
->aexpr_list
,
1640 2 * collect
->aexpr_listsize
* sizeof (struct agent_expr
*));
1641 collect
->aexpr_listsize
*= 2;
1643 collect
->aexpr_list
[collect
->next_aexpr_elt
] = aexpr
;
1644 collect
->next_aexpr_elt
++;
1647 static char target_buf
[2048];
1649 /* Set "transparent" memory ranges
1651 Allow trace mechanism to treat text-like sections
1652 (and perhaps all read-only sections) transparently,
1653 i.e. don't reject memory requests from these address ranges
1654 just because they haven't been collected. */
1657 remote_set_transparent_ranges (void)
1659 extern bfd
*exec_bfd
;
1666 return; /* no information to give. */
1668 strcpy (target_buf
, "QTro");
1669 for (s
= exec_bfd
->sections
; s
; s
= s
->next
)
1671 char tmp1
[40], tmp2
[40];
1673 if ((s
->flags
& SEC_LOAD
) == 0 ||
1674 /* (s->flags & SEC_CODE) == 0 || */
1675 (s
->flags
& SEC_READONLY
) == 0)
1680 size
= bfd_get_section_size_before_reloc (s
);
1681 sprintf_vma (tmp1
, lma
);
1682 sprintf_vma (tmp2
, lma
+ size
);
1683 sprintf (target_buf
+ strlen (target_buf
),
1684 ":%s,%s", tmp1
, tmp2
);
1688 putpkt (target_buf
);
1689 getpkt (target_buf
, sizeof (target_buf
), 0);
1695 Tell target to clear any previous trace experiment.
1696 Walk the list of tracepoints, and send them (and their actions)
1697 to the target. If no errors,
1698 Tell target to start a new trace experiment. */
1701 trace_start_command (char *args
, int from_tty
)
1702 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1703 struct tracepoint
*t
;
1706 char **stepping_actions
;
1708 struct cleanup
*old_chain
= NULL
;
1710 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1712 if (target_is_remote ())
1715 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1716 if (strcmp (target_buf
, "OK"))
1717 error ("Target does not support this command.");
1723 sprintf_vma (tmp
, t
->address
);
1724 sprintf (buf
, "QTDP:%x:%s:%c:%lx:%x", t
->number
, tmp
, /* address */
1725 t
->enabled
== enabled
? 'E' : 'D',
1726 t
->step_count
, t
->pass_count
);
1731 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1732 if (strcmp (target_buf
, "OK"))
1733 error ("Target does not support tracepoints.");
1737 encode_actions (t
, &tdp_actions
, &stepping_actions
);
1738 old_chain
= make_cleanup (free_actions_list_cleanup_wrapper
,
1740 (void) make_cleanup (free_actions_list_cleanup_wrapper
,
1743 /* do_single_steps (t); */
1746 for (ndx
= 0; tdp_actions
[ndx
]; ndx
++)
1748 QUIT
; /* allow user to bail out with ^C */
1749 sprintf (buf
, "QTDP:-%x:%s:%s%c",
1750 t
->number
, tmp
, /* address */
1752 ((tdp_actions
[ndx
+ 1] || stepping_actions
)
1755 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1756 if (strcmp (target_buf
, "OK"))
1757 error ("Error on target while setting tracepoints.");
1760 if (stepping_actions
)
1762 for (ndx
= 0; stepping_actions
[ndx
]; ndx
++)
1764 QUIT
; /* allow user to bail out with ^C */
1765 sprintf (buf
, "QTDP:-%x:%s:%s%s%s",
1766 t
->number
, tmp
, /* address */
1767 ((ndx
== 0) ? "S" : ""),
1768 stepping_actions
[ndx
],
1769 (stepping_actions
[ndx
+ 1] ? "-" : ""));
1771 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1772 if (strcmp (target_buf
, "OK"))
1773 error ("Error on target while setting tracepoints.");
1777 do_cleanups (old_chain
);
1780 /* Tell target to treat text-like sections as transparent */
1781 remote_set_transparent_ranges ();
1782 /* Now insert traps and begin collecting data */
1784 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1785 if (strcmp (target_buf
, "OK"))
1786 error ("Bogus reply from target: %s", target_buf
);
1787 set_traceframe_num (-1); /* all old traceframes invalidated */
1788 set_tracepoint_num (-1);
1789 set_traceframe_context (-1);
1790 trace_running_p
= 1;
1791 if (trace_start_stop_hook
)
1792 trace_start_stop_hook (1, from_tty
);
1796 error ("Trace can only be run on remote targets.");
1801 trace_stop_command (char *args
, int from_tty
)
1802 { /* STUB_COMM IS_IMPLEMENTED */
1803 if (target_is_remote ())
1806 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1807 if (strcmp (target_buf
, "OK"))
1808 error ("Bogus reply from target: %s", target_buf
);
1809 trace_running_p
= 0;
1810 if (trace_start_stop_hook
)
1811 trace_start_stop_hook (0, from_tty
);
1814 error ("Trace can only be run on remote targets.");
1817 unsigned long trace_running_p
;
1819 /* tstatus command */
1821 trace_status_command (char *args
, int from_tty
)
1822 { /* STUB_COMM IS_IMPLEMENTED */
1823 if (target_is_remote ())
1825 putpkt ("qTStatus");
1826 remote_get_noisy_reply (target_buf
, sizeof (target_buf
));
1828 if (target_buf
[0] != 'T' ||
1829 (target_buf
[1] != '0' && target_buf
[1] != '1'))
1830 error ("Bogus reply from target: %s", target_buf
);
1832 /* exported for use by the GUI */
1833 trace_running_p
= (target_buf
[1] == '1');
1836 error ("Trace can only be run on remote targets.");
1839 /* Worker function for the various flavors of the tfind command */
1841 finish_tfind_command (char *msg
,
1845 int target_frameno
= -1, target_tracept
= -1;
1846 CORE_ADDR old_frame_addr
;
1847 struct symbol
*old_func
;
1850 old_frame_addr
= FRAME_FP (get_current_frame ());
1851 old_func
= find_pc_function (read_pc ());
1854 reply
= remote_get_noisy_reply (msg
, sizeof_msg
);
1856 while (reply
&& *reply
)
1860 if ((target_frameno
= (int) strtol (++reply
, &reply
, 16)) == -1)
1862 /* A request for a non-existant trace frame has failed.
1863 Our response will be different, depending on FROM_TTY:
1865 If FROM_TTY is true, meaning that this command was
1866 typed interactively by the user, then give an error
1867 and DO NOT change the state of traceframe_number etc.
1869 However if FROM_TTY is false, meaning that we're either
1870 in a script, a loop, or a user-defined command, then
1871 DON'T give an error, but DO change the state of
1872 traceframe_number etc. to invalid.
1874 The rationalle is that if you typed the command, you
1875 might just have committed a typo or something, and you'd
1876 like to NOT lose your current debugging state. However
1877 if you're in a user-defined command or especially in a
1878 loop, then you need a way to detect that the command
1879 failed WITHOUT aborting. This allows you to write
1880 scripts that search thru the trace buffer until the end,
1881 and then continue on to do something else. */
1884 error ("Target failed to find requested trace frame.");
1888 printf_filtered ("End of trace buffer.\n");
1889 /* The following will not recurse, since it's special-cased */
1890 trace_find_command ("-1", from_tty
);
1891 reply
= NULL
; /* break out of loop,
1892 (avoid recursive nonsense) */
1897 if ((target_tracept
= (int) strtol (++reply
, &reply
, 16)) == -1)
1898 error ("Target failed to find requested trace frame.");
1900 case 'O': /* "OK"? */
1901 if (reply
[1] == 'K' && reply
[2] == '\0')
1904 error ("Bogus reply from target: %s", reply
);
1907 error ("Bogus reply from target: %s", reply
);
1910 flush_cached_frames ();
1911 registers_changed ();
1912 select_frame (get_current_frame (), 0);
1913 set_traceframe_num (target_frameno
);
1914 set_tracepoint_num (target_tracept
);
1915 if (target_frameno
== -1)
1916 set_traceframe_context (-1);
1918 set_traceframe_context (read_pc ());
1924 /* NOTE: in immitation of the step command, try to determine
1925 whether we have made a transition from one function to another.
1926 If so, we'll print the "stack frame" (ie. the new function and
1927 it's arguments) -- otherwise we'll just show the new source line.
1929 This determination is made by checking (1) whether the current
1930 function has changed, and (2) whether the current FP has changed.
1931 Hack: if the FP wasn't collected, either at the current or the
1932 previous frame, assume that the FP has NOT changed. */
1934 if (old_func
== find_pc_function (read_pc ()) &&
1935 (old_frame_addr
== 0 ||
1936 FRAME_FP (get_current_frame ()) == 0 ||
1937 old_frame_addr
== FRAME_FP (get_current_frame ())))
1942 print_stack_frame (selected_frame
, selected_frame_level
, source_only
);
1947 /* trace_find_command takes a trace frame number n,
1948 sends "QTFrame:<n>" to the target,
1949 and accepts a reply that may contain several optional pieces
1950 of information: a frame number, a tracepoint number, and an
1951 indication of whether this is a trap frame or a stepping frame.
1953 The minimal response is just "OK" (which indicates that the
1954 target does not give us a frame number or a tracepoint number).
1955 Instead of that, the target may send us a string containing
1957 F<hexnum> (gives the selected frame number)
1958 T<hexnum> (gives the selected tracepoint number)
1963 trace_find_command (char *args
, int from_tty
)
1964 { /* STUB_COMM PART_IMPLEMENTED */
1965 /* this should only be called with a numeric argument */
1968 if (target_is_remote ())
1970 if (trace_find_hook
)
1971 trace_find_hook (args
, from_tty
);
1973 if (args
== 0 || *args
== 0)
1974 { /* TFIND with no args means find NEXT trace frame. */
1975 if (traceframe_number
== -1)
1976 frameno
= 0; /* "next" is first one */
1978 frameno
= traceframe_number
+ 1;
1980 else if (0 == strcmp (args
, "-"))
1982 if (traceframe_number
== -1)
1983 error ("not debugging trace buffer");
1984 else if (from_tty
&& traceframe_number
== 0)
1985 error ("already at start of trace buffer");
1987 frameno
= traceframe_number
- 1;
1990 frameno
= parse_and_eval_long (args
);
1993 error ("invalid input (%d is less than zero)", frameno
);
1995 sprintf (target_buf
, "QTFrame:%x", frameno
);
1996 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
1999 error ("Trace can only be run on remote targets.");
2004 trace_find_end_command (char *args
, int from_tty
)
2006 trace_find_command ("-1", from_tty
);
2011 trace_find_none_command (char *args
, int from_tty
)
2013 trace_find_command ("-1", from_tty
);
2018 trace_find_start_command (char *args
, int from_tty
)
2020 trace_find_command ("0", from_tty
);
2023 /* tfind pc command */
2025 trace_find_pc_command (char *args
, int from_tty
)
2026 { /* STUB_COMM PART_IMPLEMENTED */
2030 if (target_is_remote ())
2032 if (args
== 0 || *args
== 0)
2033 pc
= read_pc (); /* default is current pc */
2035 pc
= parse_and_eval_address (args
);
2037 sprintf_vma (tmp
, pc
);
2038 sprintf (target_buf
, "QTFrame:pc:%s", tmp
);
2039 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2042 error ("Trace can only be run on remote targets.");
2045 /* tfind tracepoint command */
2047 trace_find_tracepoint_command (char *args
, int from_tty
)
2048 { /* STUB_COMM PART_IMPLEMENTED */
2051 if (target_is_remote ())
2053 if (args
== 0 || *args
== 0)
2054 if (tracepoint_number
== -1)
2055 error ("No current tracepoint -- please supply an argument.");
2057 tdp
= tracepoint_number
; /* default is current TDP */
2059 tdp
= parse_and_eval_long (args
);
2061 sprintf (target_buf
, "QTFrame:tdp:%x", tdp
);
2062 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2065 error ("Trace can only be run on remote targets.");
2068 /* TFIND LINE command:
2070 This command will take a sourceline for argument, just like BREAK
2071 or TRACE (ie. anything that "decode_line_1" can handle).
2073 With no argument, this command will find the next trace frame
2074 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2077 trace_find_line_command (char *args
, int from_tty
)
2078 { /* STUB_COMM PART_IMPLEMENTED */
2079 static CORE_ADDR start_pc
, end_pc
;
2080 struct symtabs_and_lines sals
;
2081 struct symtab_and_line sal
;
2082 struct cleanup
*old_chain
;
2083 char startpc_str
[40], endpc_str
[40];
2085 if (target_is_remote ())
2087 if (args
== 0 || *args
== 0)
2089 sal
= find_pc_line ((get_current_frame ())->pc
, 0);
2091 sals
.sals
= (struct symtab_and_line
*)
2092 xmalloc (sizeof (struct symtab_and_line
));
2097 sals
= decode_line_spec (args
, 1);
2101 old_chain
= make_cleanup (xfree
, sals
.sals
);
2102 if (sal
.symtab
== 0)
2104 printf_filtered ("TFIND: No line number information available");
2107 /* This is useful for "info line *0x7f34". If we can't tell the
2108 user about a source line, at least let them have the symbolic
2110 printf_filtered (" for address ");
2112 print_address (sal
.pc
, gdb_stdout
);
2113 printf_filtered (";\n -- will attempt to find by PC. \n");
2117 printf_filtered (".\n");
2118 return; /* no line, no PC; what can we do? */
2121 else if (sal
.line
> 0
2122 && find_line_pc_range (sal
, &start_pc
, &end_pc
))
2124 if (start_pc
== end_pc
)
2126 printf_filtered ("Line %d of \"%s\"",
2127 sal
.line
, sal
.symtab
->filename
);
2129 printf_filtered (" is at address ");
2130 print_address (start_pc
, gdb_stdout
);
2132 printf_filtered (" but contains no code.\n");
2133 sal
= find_pc_line (start_pc
, 0);
2135 find_line_pc_range (sal
, &start_pc
, &end_pc
) &&
2137 printf_filtered ("Attempting to find line %d instead.\n",
2140 error ("Cannot find a good line.");
2144 /* Is there any case in which we get here, and have an address
2145 which the user would want to see? If we have debugging symbols
2146 and no line numbers? */
2147 error ("Line number %d is out of range for \"%s\".\n",
2148 sal
.line
, sal
.symtab
->filename
);
2150 sprintf_vma (startpc_str
, start_pc
);
2151 sprintf_vma (endpc_str
, end_pc
- 1);
2152 if (args
&& *args
) /* find within range of stated line */
2153 sprintf (target_buf
, "QTFrame:range:%s:%s", startpc_str
, endpc_str
);
2154 else /* find OUTSIDE OF range of CURRENT line */
2155 sprintf (target_buf
, "QTFrame:outside:%s:%s", startpc_str
, endpc_str
);
2156 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2157 do_cleanups (old_chain
);
2160 error ("Trace can only be run on remote targets.");
2163 /* tfind range command */
2165 trace_find_range_command (char *args
, int from_tty
)
2167 static CORE_ADDR start
, stop
;
2168 char start_str
[40], stop_str
[40];
2171 if (target_is_remote ())
2173 if (args
== 0 || *args
== 0)
2174 { /* XXX FIXME: what should default behavior be? */
2175 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2179 if (0 != (tmp
= strchr (args
, ',')))
2181 *tmp
++ = '\0'; /* terminate start address */
2182 while (isspace ((int) *tmp
))
2184 start
= parse_and_eval_address (args
);
2185 stop
= parse_and_eval_address (tmp
);
2188 { /* no explicit end address? */
2189 start
= parse_and_eval_address (args
);
2190 stop
= start
+ 1; /* ??? */
2193 sprintf_vma (start_str
, start
);
2194 sprintf_vma (stop_str
, stop
);
2195 sprintf (target_buf
, "QTFrame:range:%s:%s", start_str
, stop_str
);
2196 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2199 error ("Trace can only be run on remote targets.");
2202 /* tfind outside command */
2204 trace_find_outside_command (char *args
, int from_tty
)
2206 CORE_ADDR start
, stop
;
2207 char start_str
[40], stop_str
[40];
2210 if (target_is_remote ())
2212 if (args
== 0 || *args
== 0)
2213 { /* XXX FIXME: what should default behavior be? */
2214 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2218 if (0 != (tmp
= strchr (args
, ',')))
2220 *tmp
++ = '\0'; /* terminate start address */
2221 while (isspace ((int) *tmp
))
2223 start
= parse_and_eval_address (args
);
2224 stop
= parse_and_eval_address (tmp
);
2227 { /* no explicit end address? */
2228 start
= parse_and_eval_address (args
);
2229 stop
= start
+ 1; /* ??? */
2232 sprintf_vma (start_str
, start
);
2233 sprintf_vma (stop_str
, stop
);
2234 sprintf (target_buf
, "QTFrame:outside:%s:%s", start_str
, stop_str
);
2235 finish_tfind_command (target_buf
, sizeof (target_buf
), from_tty
);
2238 error ("Trace can only be run on remote targets.");
2241 /* save-tracepoints command */
2243 tracepoint_save_command (char *args
, int from_tty
)
2245 struct tracepoint
*tp
;
2246 struct action_line
*line
;
2248 char *i1
= " ", *i2
= " ";
2249 char *indent
, *actionline
;
2252 if (args
== 0 || *args
== 0)
2253 error ("Argument required (file name in which to save tracepoints");
2255 if (tracepoint_chain
== 0)
2257 warning ("save-tracepoints: no tracepoints to save.\n");
2261 if (!(fp
= fopen (args
, "w")))
2262 error ("Unable to open file '%s' for saving tracepoints");
2264 ALL_TRACEPOINTS (tp
)
2266 if (tp
->addr_string
)
2267 fprintf (fp
, "trace %s\n", tp
->addr_string
);
2270 sprintf_vma (tmp
, tp
->address
);
2271 fprintf (fp
, "trace *0x%s\n", tmp
);
2275 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
2279 fprintf (fp
, " actions\n");
2281 for (line
= tp
->actions
; line
; line
= line
->next
)
2283 struct cmd_list_element
*cmd
;
2285 QUIT
; /* allow user to bail out with ^C */
2286 actionline
= line
->action
;
2287 while (isspace ((int) *actionline
))
2290 fprintf (fp
, "%s%s\n", indent
, actionline
);
2291 if (*actionline
!= '#') /* skip for comment lines */
2293 cmd
= lookup_cmd (&actionline
, cmdlist
, "", -1, 1);
2295 error ("Bad action list item: %s", actionline
);
2296 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2298 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2306 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
2310 /* info scope command: list the locals for a scope. */
2312 scope_info (char *args
, int from_tty
)
2314 struct symtabs_and_lines sals
;
2316 struct minimal_symbol
*msym
;
2317 struct block
*block
;
2318 char **canonical
, *symname
, *save_args
= args
;
2319 int i
, j
, nsyms
, count
= 0;
2321 if (args
== 0 || *args
== 0)
2322 error ("requires an argument (function, line or *addr) to define a scope");
2324 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
2325 if (sals
.nelts
== 0)
2326 return; /* presumably decode_line_1 has already warned */
2328 /* Resolve line numbers to PC */
2329 resolve_sal_pc (&sals
.sals
[0]);
2330 block
= block_for_pc (sals
.sals
[0].pc
);
2334 QUIT
; /* allow user to bail out with ^C */
2335 nsyms
= BLOCK_NSYMS (block
);
2336 for (i
= 0; i
< nsyms
; i
++)
2338 QUIT
; /* allow user to bail out with ^C */
2340 printf_filtered ("Scope for %s:\n", save_args
);
2342 sym
= BLOCK_SYM (block
, i
);
2343 symname
= SYMBOL_NAME (sym
);
2344 if (symname
== NULL
|| *symname
== '\0')
2345 continue; /* probably botched, certainly useless */
2347 printf_filtered ("Symbol %s is ", symname
);
2348 switch (SYMBOL_CLASS (sym
))
2351 case LOC_UNDEF
: /* messed up symbol? */
2352 printf_filtered ("a bogus symbol, class %d.\n",
2353 SYMBOL_CLASS (sym
));
2354 count
--; /* don't count this one */
2357 printf_filtered ("a constant with value %ld (0x%lx)",
2358 SYMBOL_VALUE (sym
), SYMBOL_VALUE (sym
));
2360 case LOC_CONST_BYTES
:
2361 printf_filtered ("constant bytes: ");
2362 if (SYMBOL_TYPE (sym
))
2363 for (j
= 0; j
< TYPE_LENGTH (SYMBOL_TYPE (sym
)); j
++)
2364 fprintf_filtered (gdb_stdout
, " %02x",
2365 (unsigned) SYMBOL_VALUE_BYTES (sym
)[j
]);
2368 printf_filtered ("in static storage at address ");
2369 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2372 printf_filtered ("a local variable in register $%s",
2373 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2377 printf_filtered ("an argument at stack/frame offset %ld",
2378 SYMBOL_VALUE (sym
));
2381 printf_filtered ("a local variable at frame offset %ld",
2382 SYMBOL_VALUE (sym
));
2385 printf_filtered ("a reference argument at offset %ld",
2386 SYMBOL_VALUE (sym
));
2389 printf_filtered ("an argument in register $%s",
2390 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2392 case LOC_REGPARM_ADDR
:
2393 printf_filtered ("the address of an argument, in register $%s",
2394 REGISTER_NAME (SYMBOL_VALUE (sym
)));
2397 printf_filtered ("a typedef.\n");
2400 printf_filtered ("a label at address ");
2401 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym
), 1, gdb_stdout
);
2404 printf_filtered ("a function at address ");
2405 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym
)), 1,
2409 printf_filtered ("a variable at offset %ld from register $%s",
2411 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2413 case LOC_BASEREG_ARG
:
2414 printf_filtered ("an argument at offset %ld from register $%s",
2416 REGISTER_NAME (SYMBOL_BASEREG (sym
)));
2418 case LOC_UNRESOLVED
:
2419 msym
= lookup_minimal_symbol (SYMBOL_NAME (sym
), NULL
, NULL
);
2421 printf_filtered ("Unresolved Static");
2424 printf_filtered ("static storage at address ");
2425 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym
), 1,
2429 case LOC_OPTIMIZED_OUT
:
2430 printf_filtered ("optimized out.\n");
2433 if (SYMBOL_TYPE (sym
))
2434 printf_filtered (", length %d.\n",
2435 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
))));
2437 if (BLOCK_FUNCTION (block
))
2440 block
= BLOCK_SUPERBLOCK (block
);
2443 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2447 /* worker function (cleanup) */
2449 replace_comma (void *data
)
2457 trace_dump_command (char *args
, int from_tty
)
2459 struct tracepoint
*t
;
2460 struct action_line
*action
;
2461 char *action_exp
, *next_comma
;
2462 struct cleanup
*old_cleanups
;
2463 int stepping_actions
= 0;
2464 int stepping_frame
= 0;
2466 if (!target_is_remote ())
2468 error ("Trace can only be run on remote targets.");
2472 if (tracepoint_number
== -1)
2474 warning ("No current trace frame.");
2479 if (t
->number
== tracepoint_number
)
2483 error ("No known tracepoint matches 'current' tracepoint #%d.",
2486 old_cleanups
= make_cleanup (null_cleanup
, NULL
);
2488 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2489 tracepoint_number
, traceframe_number
);
2491 /* The current frame is a trap frame if the frame PC is equal
2492 to the tracepoint PC. If not, then the current frame was
2493 collected during single-stepping. */
2495 stepping_frame
= (t
->address
!= read_pc ());
2497 for (action
= t
->actions
; action
; action
= action
->next
)
2499 struct cmd_list_element
*cmd
;
2501 QUIT
; /* allow user to bail out with ^C */
2502 action_exp
= action
->action
;
2503 while (isspace ((int) *action_exp
))
2506 /* The collection actions to be done while stepping are
2507 bracketed by the commands "while-stepping" and "end". */
2509 if (*action_exp
== '#') /* comment line */
2512 cmd
= lookup_cmd (&action_exp
, cmdlist
, "", -1, 1);
2514 error ("Bad action list item: %s", action_exp
);
2516 if (cmd
->function
.cfunc
== while_stepping_pseudocommand
)
2517 stepping_actions
= 1;
2518 else if (cmd
->function
.cfunc
== end_actions_pseudocommand
)
2519 stepping_actions
= 0;
2520 else if (cmd
->function
.cfunc
== collect_pseudocommand
)
2522 /* Display the collected data.
2523 For the trap frame, display only what was collected at the trap.
2524 Likewise for stepping frames, display only what was collected
2525 while stepping. This means that the two boolean variables,
2526 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2527 if (stepping_frame
== stepping_actions
)
2530 { /* repeat over a comma-separated list */
2531 QUIT
; /* allow user to bail out with ^C */
2532 if (*action_exp
== ',')
2534 while (isspace ((int) *action_exp
))
2537 next_comma
= strchr (action_exp
, ',');
2539 if (0 == strncasecmp (action_exp
, "$reg", 4))
2540 registers_info (NULL
, from_tty
);
2541 else if (0 == strncasecmp (action_exp
, "$loc", 4))
2542 locals_info (NULL
, from_tty
);
2543 else if (0 == strncasecmp (action_exp
, "$arg", 4))
2544 args_info (NULL
, from_tty
);
2549 make_cleanup (replace_comma
, next_comma
);
2552 printf_filtered ("%s = ", action_exp
);
2553 output_command (action_exp
, from_tty
);
2554 printf_filtered ("\n");
2558 action_exp
= next_comma
;
2560 while (action_exp
&& *action_exp
== ',');
2564 discard_cleanups (old_cleanups
);
2567 /* Convert the memory pointed to by mem into hex, placing result in buf.
2568 * Return a pointer to the last char put in buf (null)
2569 * "stolen" from sparc-stub.c
2572 static const char hexchars
[] = "0123456789abcdef";
2574 static unsigned char *
2575 mem2hex (unsigned char *mem
, unsigned char *buf
, int count
)
2583 *buf
++ = hexchars
[ch
>> 4];
2584 *buf
++ = hexchars
[ch
& 0xf];
2593 get_traceframe_number (void)
2595 return traceframe_number
;
2599 /* module initialization */
2601 _initialize_tracepoint (void)
2603 tracepoint_chain
= 0;
2604 tracepoint_count
= 0;
2605 traceframe_number
= -1;
2606 tracepoint_number
= -1;
2608 set_internalvar (lookup_internalvar ("tpnum"),
2609 value_from_longest (builtin_type_int
, (LONGEST
) 0));
2610 set_internalvar (lookup_internalvar ("trace_frame"),
2611 value_from_longest (builtin_type_int
, (LONGEST
) - 1));
2613 if (tracepoint_list
.list
== NULL
)
2615 tracepoint_list
.listsize
= 128;
2616 tracepoint_list
.list
= xmalloc
2617 (tracepoint_list
.listsize
* sizeof (struct memrange
));
2619 if (tracepoint_list
.aexpr_list
== NULL
)
2621 tracepoint_list
.aexpr_listsize
= 128;
2622 tracepoint_list
.aexpr_list
= xmalloc
2623 (tracepoint_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2626 if (stepping_list
.list
== NULL
)
2628 stepping_list
.listsize
= 128;
2629 stepping_list
.list
= xmalloc
2630 (stepping_list
.listsize
* sizeof (struct memrange
));
2633 if (stepping_list
.aexpr_list
== NULL
)
2635 stepping_list
.aexpr_listsize
= 128;
2636 stepping_list
.aexpr_list
= xmalloc
2637 (stepping_list
.aexpr_listsize
* sizeof (struct agent_expr
*));
2640 add_info ("scope", scope_info
,
2641 "List the variables local to a scope");
2643 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
2644 "Tracing of program execution without stopping the program.",
2647 add_info ("tracepoints", tracepoints_info
,
2648 "Status of tracepoints, or tracepoint number NUMBER.\n\
2649 Convenience variable \"$tpnum\" contains the number of the\n\
2650 last tracepoint set.");
2652 add_info_alias ("tp", "tracepoints", 1);
2654 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
2655 "Save current tracepoint definitions as a script.\n\
2656 Use the 'source' command in another debug session to restore them.");
2658 add_com ("tdump", class_trace
, trace_dump_command
,
2659 "Print everything collected at the current tracepoint.");
2661 add_prefix_cmd ("tfind", class_trace
, trace_find_command
,
2662 "Select a trace frame;\n\
2663 No argument means forward by one frame; '-' meand backward by one frame.",
2664 &tfindlist
, "tfind ", 1, &cmdlist
);
2666 add_cmd ("outside", class_trace
, trace_find_outside_command
,
2667 "Select a trace frame whose PC is outside the given \
2668 range.\nUsage: tfind outside addr1, addr2",
2671 add_cmd ("range", class_trace
, trace_find_range_command
,
2672 "Select a trace frame whose PC is in the given range.\n\
2673 Usage: tfind range addr1,addr2",
2676 add_cmd ("line", class_trace
, trace_find_line_command
,
2677 "Select a trace frame by source line.\n\
2678 Argument can be a line number (with optional source file), \n\
2679 a function name, or '*' followed by an address.\n\
2680 Default argument is 'the next source line that was traced'.",
2683 add_cmd ("tracepoint", class_trace
, trace_find_tracepoint_command
,
2684 "Select a trace frame by tracepoint number.\n\
2685 Default is the tracepoint for the current trace frame.",
2688 add_cmd ("pc", class_trace
, trace_find_pc_command
,
2689 "Select a trace frame by PC.\n\
2690 Default is the current PC, or the PC of the current trace frame.",
2693 add_cmd ("end", class_trace
, trace_find_end_command
,
2694 "Synonym for 'none'.\n\
2695 De-select any trace frame and resume 'live' debugging.",
2698 add_cmd ("none", class_trace
, trace_find_none_command
,
2699 "De-select any trace frame and resume 'live' debugging.",
2702 add_cmd ("start", class_trace
, trace_find_start_command
,
2703 "Select the first trace frame in the trace buffer.",
2706 add_com ("tstatus", class_trace
, trace_status_command
,
2707 "Display the status of the current trace data collection.");
2709 add_com ("tstop", class_trace
, trace_stop_command
,
2710 "Stop trace data collection.");
2712 add_com ("tstart", class_trace
, trace_start_command
,
2713 "Start trace data collection.");
2715 add_com ("passcount", class_trace
, trace_pass_command
,
2716 "Set the passcount for a tracepoint.\n\
2717 The trace will end when the tracepoint has been passed 'count' times.\n\
2718 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2719 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2721 add_com ("end", class_trace
, end_actions_pseudocommand
,
2722 "Ends a list of commands or actions.\n\
2723 Several GDB commands allow you to enter a list of commands or actions.\n\
2724 Entering \"end\" on a line by itself is the normal way to terminate\n\
2726 Note: the \"end\" command cannot be used at the gdb prompt.");
2728 add_com ("while-stepping", class_trace
, while_stepping_pseudocommand
,
2729 "Specify single-stepping behavior at a tracepoint.\n\
2730 Argument is number of instructions to trace in single-step mode\n\
2731 following the tracepoint. This command is normally followed by\n\
2732 one or more \"collect\" commands, to specify what to collect\n\
2733 while single-stepping.\n\n\
2734 Note: this command can only be used in a tracepoint \"actions\" list.");
2736 add_com_alias ("ws", "while-stepping", class_alias
, 0);
2737 add_com_alias ("stepping", "while-stepping", class_alias
, 0);
2739 add_com ("collect", class_trace
, collect_pseudocommand
,
2740 "Specify one or more data items to be collected at a tracepoint.\n\
2741 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2742 collect all data (variables, registers) referenced by that expression.\n\
2743 Also accepts the following special arguments:\n\
2744 $regs -- all registers.\n\
2745 $args -- all function arguments.\n\
2746 $locals -- all variables local to the block/function scope.\n\
2747 Note: this command can only be used in a tracepoint \"actions\" list.");
2749 add_com ("actions", class_trace
, trace_actions_command
,
2750 "Specify the actions to be taken at a tracepoint.\n\
2751 Tracepoint actions may include collecting of specified data, \n\
2752 single-stepping, or enabling/disabling other tracepoints, \n\
2753 depending on target's capabilities.");
2755 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
2756 "Delete specified tracepoints.\n\
2757 Arguments are tracepoint numbers, separated by spaces.\n\
2758 No argument means delete all tracepoints.",
2761 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
2762 "Disable specified tracepoints.\n\
2763 Arguments are tracepoint numbers, separated by spaces.\n\
2764 No argument means disable all tracepoints.",
2767 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
2768 "Enable specified tracepoints.\n\
2769 Arguments are tracepoint numbers, separated by spaces.\n\
2770 No argument means enable all tracepoints.",
2773 add_com ("trace", class_trace
, trace_command
,
2774 "Set a tracepoint at a specified line or function or address.\n\
2775 Argument may be a line number, function name, or '*' plus an address.\n\
2776 For a line number or function, trace at the start of its code.\n\
2777 If an address is specified, trace at that exact address.\n\n\
2778 Do \"help tracepoints\" for info on other tracepoint commands.");
2780 add_com_alias ("tp", "trace", class_alias
, 0);
2781 add_com_alias ("tr", "trace", class_alias
, 1);
2782 add_com_alias ("tra", "trace", class_alias
, 1);
2783 add_com_alias ("trac", "trace", class_alias
, 1);