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, Boston, MA 02111-1307, USA. */
23 #include "tracepoint.h"
25 #include "expression.h"
30 #include "gdb_string.h"
35 /* readline include files */
36 #include <readline/readline.h>
37 #include <readline/history.h>
39 /* readline defines this. */
46 /* maximum length of an agent aexpression.
47 this accounts for the fact that packets are limited to 400 bytes
48 (which includes everything -- including the checksum), and assumes
49 the worst case of maximum length for each of the pieces of a
52 NOTE: expressions get mem2hex'ed otherwise this would be twice as
53 large. (400 - 31)/2 == 184 */
54 #define MAX_AGENT_EXPR_LEN 184
57 extern int info_verbose;
58 extern void (*readline_begin_hook) PARAMS ((char *, ...));
59 extern char * (*readline_hook) PARAMS ((char *));
60 extern void (*readline_end_hook) PARAMS ((void));
61 extern void x_command PARAMS ((char *, int));
62 extern int addressprint; /* Print machine addresses? */
64 /* If this definition isn't overridden by the header files, assume
65 that isatty and fileno exist on this system. */
67 #define ISATTY(FP) (isatty (fileno (FP)))
73 This module defines the following debugger commands:
74 trace : set a tracepoint on a function, line, or address.
75 info trace : list all debugger-defined tracepoints.
76 delete trace : delete one or more tracepoints.
77 enable trace : enable one or more tracepoints.
78 disable trace : disable one or more tracepoints.
79 actions : specify actions to be taken at a tracepoint.
80 passcount : specify a pass count for a tracepoint.
81 tstart : start a trace experiment.
82 tstop : stop a trace experiment.
83 tstatus : query the status of a trace experiment.
84 tfind : find a trace frame in the trace buffer.
85 tdump : print everything collected at the current tracepoint.
86 save-tracepoints : write tracepoint setup into a file.
88 This module defines the following user-visible debugger variables:
89 $trace_frame : sequence number of trace frame currently being debugged.
90 $trace_line : source line of trace frame currently being debugged.
91 $trace_file : source file of trace frame currently being debugged.
92 $tracepoint : tracepoint number of trace frame currently being debugged.
96 /* ======= Important global variables: ======= */
98 /* Chain of all tracepoints defined. */
99 struct tracepoint *tracepoint_chain;
101 /* Number of last tracepoint made. */
102 static int tracepoint_count;
104 /* Number of last traceframe collected. */
105 static int traceframe_number;
107 /* Tracepoint for last traceframe collected. */
108 static int tracepoint_number;
110 /* Symbol for function for last traceframe collected */
111 static struct symbol *traceframe_fun;
113 /* Symtab and line for last traceframe collected */
114 static struct symtab_and_line traceframe_sal;
116 /* Tracing command lists */
117 static struct cmd_list_element *tfindlist;
119 /* ======= Important command functions: ======= */
120 static void trace_command PARAMS ((char *, int));
121 static void tracepoints_info PARAMS ((char *, int));
122 static void delete_trace_command PARAMS ((char *, int));
123 static void enable_trace_command PARAMS ((char *, int));
124 static void disable_trace_command PARAMS ((char *, int));
125 static void trace_pass_command PARAMS ((char *, int));
126 static void trace_actions_command PARAMS ((char *, int));
127 static void trace_start_command PARAMS ((char *, int));
128 static void trace_stop_command PARAMS ((char *, int));
129 static void trace_status_command PARAMS ((char *, int));
130 static void trace_find_command PARAMS ((char *, int));
131 static void trace_find_pc_command PARAMS ((char *, int));
132 static void trace_find_tracepoint_command PARAMS ((char *, int));
133 static void trace_find_line_command PARAMS ((char *, int));
134 static void trace_find_range_command PARAMS ((char *, int));
135 static void trace_find_outside_command PARAMS ((char *, int));
136 static void tracepoint_save_command PARAMS ((char *, int));
137 static void trace_dump_command PARAMS ((char *, int));
139 /* support routines */
140 static void trace_mention PARAMS ((struct tracepoint *));
143 struct collection_list;
145 static void add_aexpr PARAMS ((struct collection_list *, struct agent_expr *));
146 static unsigned char *mem2hex(unsigned char *, unsigned char *, int);
147 static void add_register PARAMS ((struct collection_list *collection, unsigned long regno));
148 static void free_actions_list PARAMS ((char **actions_list));
149 static void free_actions_list_cleanup_wrapper PARAMS ((void*));
151 extern void _initialize_tracepoint PARAMS ((void));
153 /* Utility: returns true if "target remote" */
157 if (current_target.to_shortname &&
158 strcmp (current_target.to_shortname, "remote") == 0)
164 /* Utility: generate error from an incoming stub packet. */
170 return; /* not an error msg */
173 case '1': /* malformed packet error */
174 if (*++buf == '0') /* general case: */
175 error ("tracepoint.c: error in outgoing packet.");
177 error ("tracepoint.c: error in outgoing packet at field #%d.",
178 strtol (buf, NULL, 16));
180 error ("trace API error 0x%s.", ++buf);
182 error ("Target returns error code '%s'.", buf);
186 /* Utility: wait for reply from stub, while accepting "O" packets */
188 remote_get_noisy_reply (buf)
191 do /* loop on reply from remote stub */
193 QUIT; /* allow user to bail out with ^C */
196 error ("Target does not support this command.");
197 else if (buf[0] == 'E')
199 else if (buf[0] == 'O' &&
201 remote_console_output (buf + 1); /* 'O' message from stub */
203 return buf; /* here's the actual reply */
207 /* Set tracepoint count to NUM. */
209 set_tracepoint_count (num)
212 tracepoint_count = num;
213 set_internalvar (lookup_internalvar ("tpnum"),
214 value_from_longest (builtin_type_int, (LONGEST) num));
217 /* Set traceframe number to NUM. */
219 set_traceframe_num (num)
222 traceframe_number = num;
223 set_internalvar (lookup_internalvar ("trace_frame"),
224 value_from_longest (builtin_type_int, (LONGEST) num));
227 /* Set tracepoint number to NUM. */
229 set_tracepoint_num (num)
232 tracepoint_number = num;
233 set_internalvar (lookup_internalvar ("tracepoint"),
234 value_from_longest (builtin_type_int, (LONGEST) num));
237 /* Set externally visible debug variables for querying/printing
238 the traceframe context (line, function, file) */
241 set_traceframe_context (trace_pc)
244 static struct type *func_string, *file_string;
245 static struct type *func_range, *file_range;
246 static value_ptr func_val, file_val;
247 static struct type *charstar;
250 if (charstar == (struct type *) NULL)
251 charstar = lookup_pointer_type (builtin_type_char);
253 if (trace_pc == -1) /* cease debugging any trace buffers */
256 traceframe_sal.pc = traceframe_sal.line = 0;
257 traceframe_sal.symtab = NULL;
258 set_internalvar (lookup_internalvar ("trace_func"),
259 value_from_longest (charstar, (LONGEST) 0));
260 set_internalvar (lookup_internalvar ("trace_file"),
261 value_from_longest (charstar, (LONGEST) 0));
262 set_internalvar (lookup_internalvar ("trace_line"),
263 value_from_longest (builtin_type_int, (LONGEST) -1));
267 /* save as globals for internal use */
268 traceframe_sal = find_pc_line (trace_pc, 0);
269 traceframe_fun = find_pc_function (trace_pc);
271 /* save linenumber as "$trace_line", a debugger variable visible to users */
272 set_internalvar (lookup_internalvar ("trace_line"),
273 value_from_longest (builtin_type_int,
274 (LONGEST) traceframe_sal.line));
276 /* save func name as "$trace_func", a debugger variable visible to users */
277 if (traceframe_fun == NULL ||
278 SYMBOL_NAME (traceframe_fun) == NULL)
279 set_internalvar (lookup_internalvar ("trace_func"),
280 value_from_longest (charstar, (LONGEST) 0));
283 len = strlen (SYMBOL_NAME (traceframe_fun));
284 func_range = create_range_type (func_range,
285 builtin_type_int, 0, len - 1);
286 func_string = create_array_type (func_string,
287 builtin_type_char, func_range);
288 func_val = allocate_value (func_string);
289 VALUE_TYPE (func_val) = func_string;
290 memcpy (VALUE_CONTENTS_RAW (func_val),
291 SYMBOL_NAME (traceframe_fun),
293 func_val->modifiable = 0;
294 set_internalvar (lookup_internalvar ("trace_func"), func_val);
297 /* save file name as "$trace_file", a debugger variable visible to users */
298 if (traceframe_sal.symtab == NULL ||
299 traceframe_sal.symtab->filename == NULL)
300 set_internalvar (lookup_internalvar ("trace_file"),
301 value_from_longest (charstar, (LONGEST) 0));
304 len = strlen (traceframe_sal.symtab->filename);
305 file_range = create_range_type (file_range,
306 builtin_type_int, 0, len - 1);
307 file_string = create_array_type (file_string,
308 builtin_type_char, file_range);
309 file_val = allocate_value (file_string);
310 VALUE_TYPE (file_val) = file_string;
311 memcpy (VALUE_CONTENTS_RAW (file_val),
312 traceframe_sal.symtab->filename,
314 file_val->modifiable = 0;
315 set_internalvar (lookup_internalvar ("trace_file"), file_val);
319 /* Low level routine to set a tracepoint.
320 Returns the tracepoint object so caller can set other things.
321 Does not set the tracepoint number!
322 Does not print anything.
324 ==> This routine should not be called if there is a chance of later
325 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
326 your arguments BEFORE calling this routine! */
328 static struct tracepoint *
329 set_raw_tracepoint (sal)
330 struct symtab_and_line sal;
332 register struct tracepoint *t, *tc;
333 struct cleanup *old_chain;
335 t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
336 old_chain = make_cleanup (free, t);
337 memset (t, 0, sizeof (*t));
339 if (sal.symtab == NULL)
340 t->source_file = NULL;
342 t->source_file = savestring (sal.symtab->filename,
343 strlen (sal.symtab->filename));
345 t->section = sal.section;
346 t->language = current_language->la_language;
347 t->input_radix = input_radix;
348 t->line_number = sal.line;
349 t->enabled = enabled;
353 t->addr_string = NULL;
355 /* Add this tracepoint to the end of the chain
356 so that a list of tracepoints will come out in order
357 of increasing numbers. */
359 tc = tracepoint_chain;
361 tracepoint_chain = t;
368 discard_cleanups (old_chain);
372 /* Set a tracepoint according to ARG (function, linenum or *address) */
374 trace_command (arg, from_tty)
378 char **canonical = (char **)NULL;
379 struct symtabs_and_lines sals;
380 struct symtab_and_line sal;
381 struct tracepoint *t;
382 char *addr_start = 0, *addr_end = 0;
386 error ("trace command requires an argument");
388 if (from_tty && info_verbose)
389 printf_filtered ("TRACE %s\n", arg);
392 sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical);
395 return; /* ??? Presumably decode_line_1 has already warned? */
397 /* Resolve all line numbers to PC's */
398 for (i = 0; i < sals.nelts; i++)
399 resolve_sal_pc (&sals.sals[i]);
401 /* Now set all the tracepoints. */
402 for (i = 0; i < sals.nelts; i++)
406 t = set_raw_tracepoint (sal);
407 set_tracepoint_count (tracepoint_count + 1);
408 t->number = tracepoint_count;
410 /* If a canonical line spec is needed use that instead of the
412 if (canonical != (char **)NULL && canonical[i] != NULL)
413 t->addr_string = canonical[i];
415 t->addr_string = savestring (addr_start, addr_end - addr_start);
419 /* Let the UI know of any additions */
420 if (create_tracepoint_hook)
421 create_tracepoint_hook (t);
426 printf_filtered ("Multiple tracepoints were set.\n");
427 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
431 /* Tell the user we have just set a tracepoint TP. */
435 struct tracepoint *tp;
437 printf_filtered ("Tracepoint %d", tp->number);
439 if (addressprint || (tp->source_file == NULL))
441 printf_filtered (" at ");
442 print_address_numeric (tp->address, 1, gdb_stdout);
445 printf_filtered (": file %s, line %d.",
446 tp->source_file, tp->line_number);
448 printf_filtered ("\n");
451 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
454 tracepoints_info (tpnum_exp, from_tty)
458 struct tracepoint *t;
459 struct action_line *action;
460 int found_a_tracepoint = 0;
461 char wrap_indent[80];
466 tpnum = parse_and_eval_address (tpnum_exp);
469 if (tpnum == -1 || tpnum == t->number)
471 extern int addressprint; /* print machine addresses? */
473 if (!found_a_tracepoint++)
475 printf_filtered ("Num Enb ");
477 printf_filtered ("Address ");
478 printf_filtered ("PassC StepC What\n");
480 strcpy (wrap_indent, " ");
482 strcat (wrap_indent, " ");
484 printf_filtered ("%-3d %-3s ", t->number,
485 t->enabled == enabled ? "y" : "n");
487 printf_filtered ("%s ",
488 local_hex_string_custom ((unsigned long) t->address,
490 printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
494 sym = find_pc_sect_function (t->address, t->section);
497 fputs_filtered ("in ", gdb_stdout);
498 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
499 wrap_here (wrap_indent);
500 fputs_filtered (" at ", gdb_stdout);
502 fputs_filtered (t->source_file, gdb_stdout);
503 printf_filtered (":%d", t->line_number);
506 print_address_symbolic (t->address, gdb_stdout, demangle, " ");
508 printf_filtered ("\n");
511 printf_filtered (" Actions for tracepoint %d: \n", t->number);
512 for (action = t->actions; action; action = action->next)
514 printf_filtered ("\t%s\n", action->action);
518 if (!found_a_tracepoint)
521 printf_filtered ("No tracepoints.\n");
523 printf_filtered ("No tracepoint number %d.\n", tpnum);
527 /* Optimization: the code to parse an enable, disable, or delete TP command
528 is virtually identical except for whether it performs an enable, disable,
529 or delete. Therefore I've combined them into one function with an opcode.
531 enum tracepoint_opcode
538 /* This function implements enable, disable and delete. */
540 tracepoint_operation (t, from_tty, opcode)
541 struct tracepoint *t;
543 enum tracepoint_opcode opcode;
545 struct tracepoint *t2;
549 t->enabled = enabled;
550 if (modify_tracepoint_hook)
551 modify_tracepoint_hook (t);
554 t->enabled = disabled;
555 if (modify_tracepoint_hook)
556 modify_tracepoint_hook (t);
559 if (tracepoint_chain == t)
560 tracepoint_chain = t->next;
569 /* Let the UI know of any deletions */
570 if (delete_tracepoint_hook)
571 delete_tracepoint_hook (t);
574 free (t->addr_string);
576 free (t->source_file);
585 /* Utility: parse a tracepoint number and look it up in the list. */
587 get_tracepoint_by_number (arg)
590 struct tracepoint *t;
596 error ("Bad tracepoint argument");
598 if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
599 tpnum = tracepoint_count;
600 else if (**arg == '$') /* handle convenience variable */
602 /* Make a copy of the name, so we can null-terminate it
603 to pass to lookup_internalvar(). */
605 while (isalnum(*end) || *end == '_')
607 copy = (char *) alloca (end - *arg);
608 strncpy (copy, *arg + 1, (end - *arg - 1));
609 copy[end - *arg - 1] = '\0';
612 val = value_of_internalvar (lookup_internalvar (copy));
613 if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
614 error ("Convenience variable must have integral type.");
615 tpnum = (int) value_as_long (val);
617 else /* handle tracepoint number */
619 tpnum = strtol (*arg, arg, 0);
620 if (tpnum == 0) /* possible strtol failure */
621 while (**arg && !isspace (**arg))
622 (*arg)++; /* advance to next white space, if any */
625 if (t->number == tpnum)
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 (args, from_tty, opcode)
638 enum tracepoint_opcode opcode;
640 struct tracepoint *t, *tmp;
644 if (args == 0 || *args == 0) /* do them all */
645 ALL_TRACEPOINTS_SAFE (t, tmp)
646 tracepoint_operation (t, from_tty, opcode);
650 QUIT; /* give user option to bail out with ^C */
651 t = get_tracepoint_by_number (&args);
653 tracepoint_operation (t, from_tty, opcode);
654 while (*args == ' ' || *args == '\t')
659 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
661 enable_trace_command (args, from_tty)
666 map_args_over_tracepoints (args, from_tty, enable);
669 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
671 disable_trace_command (args, from_tty)
676 map_args_over_tracepoints (args, from_tty, disable);
679 /* Remove a tracepoint (or all if no argument) */
681 delete_trace_command (args, from_tty)
686 if (!args || !*args) /* No args implies all tracepoints; */
687 if (from_tty) /* confirm only if from_tty... */
688 if (tracepoint_chain) /* and if there are tracepoints to delete! */
689 if (!query ("Delete all tracepoints? "))
692 map_args_over_tracepoints (args, from_tty, delete);
695 /* Set passcount for tracepoint.
697 First command argument is passcount, second is tracepoint number.
698 If tracepoint number omitted, apply to most recently defined.
699 Also accepts special argument "all". */
702 trace_pass_command (args, from_tty)
706 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
709 if (args == 0 || *args == 0)
710 error ("PASS command requires an argument (count + optional TP num)");
712 count = strtoul (args, &args, 10); /* count comes first, then TP num */
714 while (*args && isspace (*args))
717 if (*args && strncasecmp (args, "all", 3) == 0)
718 args += 3; /* skip special argument "all" */
720 t1 = get_tracepoint_by_number (&args);
723 error ("Junk at end of arguments.");
726 return; /* error, bad tracepoint number */
729 if (t1 == (struct tracepoint *) -1 || t1 == t2)
731 t2->pass_count = count;
732 if (modify_tracepoint_hook)
733 modify_tracepoint_hook (t2);
735 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
740 /* ACTIONS functions: */
742 /* Prototypes for action-parsing utility commands */
743 static void read_actions PARAMS((struct tracepoint *));
744 static char *parse_and_eval_memrange PARAMS ((char *,
750 /* The three functions:
751 collect_pseudocommand,
752 while_stepping_pseudocommand, and
753 end_actions_pseudocommand
754 are placeholders for "commands" that are actually ONLY to be used
755 within a tracepoint action list. If the actual function is ever called,
756 it means that somebody issued the "command" at the top level,
757 which is always an error. */
760 end_actions_pseudocommand (args, from_tty)
764 error ("This command cannot be used at the top level.");
768 while_stepping_pseudocommand (args, from_tty)
772 error ("This command can only be used in a tracepoint actions list.");
776 collect_pseudocommand (args, from_tty)
780 error ("This command can only be used in a tracepoint actions list.");
783 /* Enter a list of actions for a tracepoint. */
785 trace_actions_command (args, from_tty)
789 struct tracepoint *t;
792 char *end_msg = "End with a line saying just \"end\".";
794 t = get_tracepoint_by_number (&args);
797 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
802 if (readline_begin_hook)
803 (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
804 else if (input_from_terminal_p ())
805 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
809 t->step_count = 0; /* read_actions may set this */
812 if (readline_end_hook)
813 (*readline_end_hook) ();
815 /* tracepoints_changed () */
817 /* else error, just return; */
820 /* worker function */
823 struct tracepoint *t;
826 char *prompt1 = "> ", *prompt2 = " > ";
827 char *prompt = prompt1;
828 enum actionline_type linetype;
829 extern FILE *instream;
830 struct action_line *next = NULL, *temp;
831 struct cleanup *old_chain;
833 /* Control-C quits instantly if typed while in this loop
834 since it should not wait until the user types a newline. */
840 signal (STOP_SIGNAL, handle_stop_sig);
842 signal (STOP_SIGNAL, stop_sig);
845 old_chain = make_cleanup ((make_cleanup_func) free_actions, (void *) t);
848 /* Make sure that all output has been output. Some machines may let
849 you get away with leaving out some of the gdb_flush, but not all. */
851 gdb_flush (gdb_stdout);
852 gdb_flush (gdb_stderr);
854 if (readline_hook && instream == NULL)
855 line = (*readline_hook) (prompt);
856 else if (instream == stdin && ISATTY (instream))
858 line = readline (prompt);
859 if (line && *line) /* add it to command history */
863 line = gdb_readline (0);
865 linetype = validate_actionline (&line, t);
866 if (linetype == BADLINE)
867 continue; /* already warned -- collect another line */
869 temp = xmalloc (sizeof (struct action_line));
873 if (next == NULL) /* first action for this tracepoint? */
874 t->actions = next = temp;
881 if (linetype == STEPPING) /* begin "while-stepping" */
883 if (prompt == prompt2)
885 warning ("Already processing 'while-stepping'");
889 prompt = prompt2; /* change prompt for stepping actions */
891 else if (linetype == END)
893 if (prompt == prompt2)
895 prompt = prompt1; /* end of single-stepping actions */
898 { /* end of actions */
899 if (t->actions->next == NULL)
901 /* an "end" all by itself with no other actions means
902 this tracepoint has no actions. Discard empty list. */
911 signal (STOP_SIGNAL, SIG_DFL);
914 discard_cleanups (old_chain);
917 /* worker function */
919 validate_actionline (line, t)
921 struct tracepoint *t;
923 struct cmd_list_element *c;
924 struct expression *exp = NULL;
925 value_ptr temp, temp2;
926 struct cleanup *old_chain = NULL;
929 for (p = *line; isspace (*p); )
932 /* symbol lookup etc. */
933 if (*p == '\0') /* empty line: just prompt for another line. */
936 if (*p == '#') /* comment line */
939 c = lookup_cmd (&p, cmdlist, "", -1, 1);
942 warning ("'%s' is not an action that I know, or is ambiguous.", p);
946 if (c->function.cfunc == collect_pseudocommand)
948 struct agent_expr *aexpr;
949 struct agent_reqs areqs;
951 do { /* repeat over a comma-separated list */
952 QUIT; /* allow user to bail out with ^C */
956 if (*p == '$') /* look for special pseudo-symbols */
959 bfd_signed_vma offset;
961 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
962 (0 == strncasecmp ("arg", p + 1, 3)) ||
963 (0 == strncasecmp ("loc", p + 1, 3)))
968 /* else fall thru, treat p as an expression and parse it! */
970 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
971 old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
974 if (exp->elts[0].opcode == OP_VAR_VALUE)
976 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
978 warning ("%s is constant (value %d): will not be collected.",
979 SYMBOL_NAME (exp->elts[2].symbol),
980 SYMBOL_VALUE (exp->elts[2].symbol));
983 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
985 warning ("%s is optimized away and cannot be collected.",
986 SYMBOL_NAME (exp->elts[2].symbol));
991 /* we have something to collect, make sure that the expr to
992 bytecode translator can handle it and that it's not too long */
993 aexpr = gen_trace_for_expr (t->address, exp);
994 (void) make_cleanup ((make_cleanup_func) free_agent_expr, aexpr);
996 if (aexpr->len > MAX_AGENT_EXPR_LEN)
997 error ("expression too complicated, try simplifying");
999 ax_reqs(aexpr, &areqs);
1000 (void) make_cleanup (free, areqs.reg_mask);
1002 if (areqs.flaw != agent_flaw_none)
1003 error ("malformed expression");
1005 if (areqs.min_height < 0)
1006 error ("gdb: Internal error: expression has min height < 0");
1008 if (areqs.max_height > 20)
1009 error ("expression too complicated, try simplifying");
1011 do_cleanups (old_chain);
1012 } while (p && *p++ == ',');
1015 else if (c->function.cfunc == while_stepping_pseudocommand)
1017 char *steparg; /* in case warning is necessary */
1019 while (isspace (*p))
1024 (t->step_count = strtol (p, &p, 0)) == 0)
1026 warning ("bad step-count: command ignored.", *line);
1031 else if (c->function.cfunc == end_actions_pseudocommand)
1035 warning ("'%s' is not a supported tracepoint action.", *line);
1040 /* worker function */
1043 struct tracepoint *t;
1045 struct action_line *line, *next;
1047 for (line = t->actions; line; line = next)
1051 free (line->action);
1058 int type; /* 0 for absolute memory range, else basereg number */
1059 bfd_signed_vma start;
1063 struct collection_list {
1064 unsigned char regs_mask[8]; /* room for up to 256 regs */
1067 struct memrange *list;
1068 long aexpr_listsize; /* size of array pointed to by expr_list elt */
1069 long next_aexpr_elt;
1070 struct agent_expr **aexpr_list;
1072 } tracepoint_list, stepping_list;
1074 /* MEMRANGE functions: */
1076 static int memrange_cmp PARAMS ((const void *, const void *));
1078 /* compare memranges for qsort */
1080 memrange_cmp (va, vb)
1084 const struct memrange *a = va, *b = vb;
1086 if (a->type < b->type)
1088 if (a->type > b->type)
1092 if ((bfd_vma) a->start < (bfd_vma) b->start) return -1;
1093 if ((bfd_vma) a->start > (bfd_vma) b->start) return 1;
1097 if (a->start < b->start)
1099 if (a->start > b->start)
1105 /* Sort the memrange list using qsort, and merge adjacent memranges */
1107 memrange_sortmerge (memranges)
1108 struct collection_list *memranges;
1112 qsort (memranges->list, memranges->next_memrange,
1113 sizeof (struct memrange), memrange_cmp);
1114 if (memranges->next_memrange > 0)
1116 for (a = 0, b = 1; b < memranges->next_memrange; b++)
1118 if (memranges->list[a].type == memranges->list[b].type &&
1119 memranges->list[b].start - memranges->list[a].end <=
1120 MAX_REGISTER_VIRTUAL_SIZE)
1122 /* memrange b starts before memrange a ends; merge them. */
1123 if (memranges->list[b].end > memranges->list[a].end)
1124 memranges->list[a].end = memranges->list[b].end;
1125 continue; /* next b, same a */
1129 memcpy (&memranges->list[a], &memranges->list[b],
1130 sizeof (struct memrange));
1132 memranges->next_memrange = a + 1;
1136 /* Add a register to a collection list */
1138 add_register (collection, regno)
1139 struct collection_list *collection;
1140 unsigned long regno;
1143 printf_filtered ("collect register %d\n", regno);
1144 if (regno > (8 * sizeof (collection->regs_mask)))
1145 error ("Internal: register number %d too large for tracepoint",
1147 collection->regs_mask [regno / 8] |= 1 << (regno % 8);
1150 /* Add a memrange to a collection list */
1152 add_memrange (memranges, type, base, len)
1153 struct collection_list *memranges;
1155 bfd_signed_vma base;
1159 printf_filtered ("(%d,0x%x,%d)\n", type, base, len);
1160 /* type: 0 == memory, n == basereg */
1161 memranges->list[memranges->next_memrange].type = type;
1162 /* base: addr if memory, offset if reg relative. */
1163 memranges->list[memranges->next_memrange].start = base;
1164 /* len: we actually save end (base + len) for convenience */
1165 memranges->list[memranges->next_memrange].end = base + len;
1166 memranges->next_memrange++;
1167 if (memranges->next_memrange >= memranges->listsize)
1169 memranges->listsize *= 2;
1170 memranges->list = xrealloc (memranges->list,
1171 memranges->listsize);
1174 if (type != -1) /* better collect the base register! */
1175 add_register (memranges, type);
1178 /* Add a symbol to a collection list */
1180 collect_symbol (collect, sym, frame_regno, frame_offset)
1181 struct collection_list *collect;
1188 bfd_signed_vma offset;
1190 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1191 switch (SYMBOL_CLASS (sym)) {
1193 printf_filtered ("%s: don't know symbol class %d\n",
1194 SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1197 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1198 SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1201 offset = SYMBOL_VALUE_ADDRESS (sym);
1203 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1204 SYMBOL_NAME (sym), len, offset);
1205 add_memrange (collect, -1, offset, len); /* 0 == memory */
1209 reg = SYMBOL_VALUE (sym);
1211 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1212 add_register (collect, reg);
1213 /* check for doubles stored in two registers */
1214 /* FIXME: how about larger types stored in 3 or more regs? */
1215 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
1216 len > REGISTER_RAW_SIZE (reg))
1217 add_register (collect, reg + 1);
1220 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1221 printf_filtered (" (will not collect %s)\n",
1226 offset = frame_offset + SYMBOL_VALUE (sym);
1229 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1230 SYMBOL_NAME (sym), len);
1231 printf_filtered (" %d from frame ptr reg %d\n", offset, reg);
1233 add_memrange (collect, reg, offset, len);
1235 case LOC_REGPARM_ADDR:
1236 reg = SYMBOL_VALUE (sym);
1240 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset",
1241 SYMBOL_NAME (sym), len);
1242 printf_filtered (" %d from reg %d\n", offset, reg);
1244 add_memrange (collect, reg, offset, len);
1249 offset = frame_offset + SYMBOL_VALUE (sym);
1252 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset",
1253 SYMBOL_NAME (sym), len);
1254 printf_filtered (" %d from frame ptr reg %d\n", offset, reg);
1256 add_memrange (collect, reg, offset, len);
1259 case LOC_BASEREG_ARG:
1260 reg = SYMBOL_BASEREG (sym);
1261 offset = SYMBOL_VALUE (sym);
1264 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1265 SYMBOL_NAME (sym), len, offset, reg);
1267 add_memrange (collect, reg, offset, len);
1269 case LOC_UNRESOLVED:
1270 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1272 case LOC_OPTIMIZED_OUT:
1273 printf_filtered ("%s has been optimized out of existance.\n",
1279 /* Add all locals (or args) symbols to collection list */
1281 add_local_symbols (collect, pc, frame_regno, frame_offset, type)
1282 struct collection_list *collect;
1289 struct block *block;
1290 int i, nsyms, count = 0;
1292 block = block_for_pc (pc);
1295 QUIT; /* allow user to bail out with ^C */
1296 nsyms = BLOCK_NSYMS (block);
1297 for (i = 0; i < nsyms; i++)
1299 sym = BLOCK_SYM (block, i);
1300 switch (SYMBOL_CLASS (sym)) {
1305 if (type == 'L') /* collecting Locals */
1308 collect_symbol (collect, sym, frame_regno, frame_offset);
1315 case LOC_REGPARM_ADDR:
1316 case LOC_BASEREG_ARG:
1317 if (type == 'A') /* collecting Arguments */
1320 collect_symbol (collect, sym, frame_regno, frame_offset);
1324 if (BLOCK_FUNCTION (block))
1327 block = BLOCK_SUPERBLOCK (block);
1330 warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1333 /* worker function */
1335 clear_collection_list (list)
1336 struct collection_list *list;
1340 list->next_memrange = 0;
1341 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1343 free_agent_expr(list->aexpr_list[ndx]);
1344 list->aexpr_list[ndx] = NULL;
1346 list->next_aexpr_elt = 0;
1347 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1350 /* reduce a collection list to string form (for gdb protocol) */
1352 stringify_collection_list (list, string)
1353 struct collection_list *list;
1356 char temp_buf[2048];
1359 char *(*str_list)[];
1363 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
1364 str_list = (char *(*)[])xmalloc(count * sizeof (char *));
1366 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1367 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1369 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1372 printf_filtered ("\nCollecting registers (mask): 0x");
1377 QUIT; /* allow user to bail out with ^C */
1379 printf_filtered ("%02X", list->regs_mask[i]);
1380 sprintf (end, "%02X", list->regs_mask[i]);
1383 (*str_list)[ndx] = savestring(temp_buf, end - temp_buf);
1387 printf_filtered ("\n");
1388 if (list->next_memrange > 0 && info_verbose)
1389 printf_filtered ("Collecting memranges: \n");
1390 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1392 QUIT; /* allow user to bail out with ^C */
1394 printf_filtered ("(%d, 0x%x, %d)\n",
1396 list->list[i].start,
1397 list->list[i].end - list->list[i].start);
1398 if (count + 27 > MAX_AGENT_EXPR_LEN)
1400 (*str_list)[ndx] = savestring(temp_buf, count);
1405 sprintf (end, "M%X,%X,%X",
1407 list->list[i].start,
1408 list->list[i].end - list->list[i].start);
1409 count += strlen (end);
1410 end += 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 (al)
1450 free_actions_list (al);
1454 free_actions_list(actions_list)
1455 char **actions_list;
1459 if (actions_list == 0)
1462 for (ndx = 0; actions_list[ndx]; ndx++)
1463 free(actions_list[ndx]);
1468 /* render all actions into gdb protocol */
1470 encode_actions (t, tdp_actions, stepping_actions)
1471 struct tracepoint *t;
1472 char ***tdp_actions;
1473 char ***stepping_actions;
1475 static char tdp_buff[2048], step_buff[2048];
1477 struct expression *exp = NULL;
1478 struct action_line *action;
1479 bfd_signed_vma offset;
1482 struct collection_list *collect;
1483 struct cmd_list_element *cmd;
1484 struct agent_expr *aexpr;
1485 long frame_reg, frame_offset;
1488 clear_collection_list (&tracepoint_list);
1489 clear_collection_list (&stepping_list);
1490 collect = &tracepoint_list;
1492 *tdp_actions = NULL;
1493 *stepping_actions = NULL;
1495 TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
1497 for (action = t->actions; action; action = action->next)
1499 QUIT; /* allow user to bail out with ^C */
1500 action_exp = action->action;
1501 while (isspace (*action_exp))
1504 if (*action_exp == '#') /* comment line */
1507 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1509 error ("Bad action list item: %s", action_exp);
1511 if (cmd->function.cfunc == collect_pseudocommand)
1513 do { /* repeat over a comma-separated list */
1514 QUIT; /* allow user to bail out with ^C */
1515 while (isspace (*action_exp))
1518 if (0 == strncasecmp ("$reg", action_exp, 4))
1520 for (i = 0; i < NUM_REGS; i++)
1521 add_register (collect, i);
1522 action_exp = strchr (action_exp, ','); /* more? */
1524 else if (0 == strncasecmp ("$arg", action_exp, 4))
1526 add_local_symbols (collect,
1531 action_exp = strchr (action_exp, ','); /* more? */
1533 else if (0 == strncasecmp ("$loc", action_exp, 4))
1535 add_local_symbols (collect,
1540 action_exp = strchr (action_exp, ','); /* more? */
1544 unsigned long addr, len;
1545 struct cleanup *old_chain = NULL;
1546 struct cleanup *old_chain1 = NULL;
1547 struct agent_reqs areqs;
1549 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1550 old_chain = make_cleanup ((make_cleanup_func)
1551 free_current_contents, &exp);
1553 switch (exp->elts[0].opcode) {
1555 i = exp->elts[1].longconst;
1557 printf_filtered ("OP_REGISTER: ");
1558 add_register (collect, i);
1562 /* safe because we know it's a simple expression */
1563 tempval = evaluate_expression (exp);
1564 addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1565 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1566 add_memrange (collect, -1, addr, len);
1570 collect_symbol (collect,
1571 exp->elts[2].symbol,
1576 default: /* full-fledged expression */
1577 aexpr = gen_trace_for_expr (t->address, exp);
1579 old_chain1 = make_cleanup ((make_cleanup_func)
1580 free_agent_expr, aexpr);
1582 ax_reqs (aexpr, &areqs);
1583 if (areqs.flaw != agent_flaw_none)
1584 error ("malformed expression");
1586 if (areqs.min_height < 0)
1587 error ("gdb: Internal error: expression has min height < 0");
1588 if (areqs.max_height > 20)
1589 error ("expression too complicated, try simplifying");
1591 discard_cleanups (old_chain1);
1592 add_aexpr (collect, aexpr);
1594 /* take care of the registers */
1595 if (areqs.reg_mask_len > 0)
1600 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1602 QUIT; /* allow user to bail out with ^C */
1603 if (areqs.reg_mask[ndx1] != 0)
1605 /* assume chars have 8 bits */
1606 for (ndx2 = 0; ndx2 < 8; ndx2++)
1607 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1608 /* it's used -- record it */
1609 add_register (collect, ndx1 * 8 + ndx2);
1615 do_cleanups (old_chain);
1617 } while (action_exp && *action_exp++ == ',');
1619 else if (cmd->function.cfunc == while_stepping_pseudocommand)
1621 collect = &stepping_list;
1623 else if (cmd->function.cfunc == end_actions_pseudocommand)
1625 if (collect == &stepping_list) /* end stepping actions */
1626 collect = &tracepoint_list;
1628 break; /* end tracepoint actions */
1631 memrange_sortmerge (&tracepoint_list);
1632 memrange_sortmerge (&stepping_list);
1634 *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
1635 *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
1639 add_aexpr(collect, aexpr)
1640 struct collection_list *collect;
1641 struct agent_expr *aexpr;
1643 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1645 collect->aexpr_list =
1646 xrealloc (collect->aexpr_list,
1647 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
1648 collect->aexpr_listsize *= 2;
1650 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1651 collect->next_aexpr_elt++;
1654 static char target_buf[2048];
1656 /* Set "transparent" memory ranges
1658 Allow trace mechanism to treat text-like sections
1659 (and perhaps all read-only sections) transparently,
1660 i.e. don't reject memory requests from these address ranges
1661 just because they haven't been collected. */
1664 remote_set_transparent_ranges (void)
1666 extern bfd *exec_bfd;
1673 return; /* no information to give. */
1675 strcpy (target_buf, "QTro");
1676 for (s = exec_bfd->sections; s; s = s->next)
1680 if ((s->flags & SEC_LOAD) == 0 ||
1681 /* (s->flags & SEC_CODE) == 0 || */
1682 (s->flags & SEC_READONLY) == 0)
1687 size = bfd_get_section_size_before_reloc (s);
1688 sprintf (tmp, ":%x,%x", lma, lma + size);
1689 strcat (target_buf, tmp);
1693 putpkt (target_buf);
1694 getpkt (target_buf, 0);
1700 Tell target to clear any previous trace experiment.
1701 Walk the list of tracepoints, and send them (and their actions)
1702 to the target. If no errors,
1703 Tell target to start a new trace experiment. */
1706 trace_start_command (args, from_tty)
1709 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1710 struct tracepoint *t;
1713 char **stepping_actions;
1715 struct cleanup *old_chain = NULL;
1717 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1719 if (target_is_remote ())
1722 remote_get_noisy_reply (target_buf);
1723 if (strcmp (target_buf, "OK"))
1724 error ("Target does not support this command.");
1728 int ss_count; /* if actions include singlestepping */
1729 int disable_mask; /* ??? */
1730 int enable_mask; /* ??? */
1732 sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address,
1733 t->enabled == enabled ? 'E' : 'D',
1734 t->step_count, t->pass_count);
1739 remote_get_noisy_reply (target_buf);
1740 if (strcmp (target_buf, "OK"))
1741 error ("Target does not support tracepoints.");
1745 encode_actions (t, &tdp_actions, &stepping_actions);
1746 old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
1748 (void) make_cleanup (free_actions_list_cleanup_wrapper,
1751 /* do_single_steps (t); */
1754 for (ndx = 0; tdp_actions[ndx]; ndx++)
1756 QUIT; /* allow user to bail out with ^C */
1757 sprintf (buf, "QTDP:-%x:%x:%s%c",
1758 t->number, t->address,
1760 ((tdp_actions[ndx+1] || stepping_actions)
1763 remote_get_noisy_reply (target_buf);
1764 if (strcmp (target_buf, "OK"))
1765 error ("Error on target while setting tracepoints.");
1768 if (stepping_actions)
1770 for (ndx = 0; stepping_actions[ndx]; ndx++)
1772 QUIT; /* allow user to bail out with ^C */
1773 sprintf (buf, "QTDP:-%x:%x:%s%s%s",
1774 t->number, t->address,
1775 ((ndx == 0) ? "S" : ""),
1776 stepping_actions[ndx],
1777 (stepping_actions[ndx+1] ? "-" : ""));
1779 remote_get_noisy_reply (target_buf);
1780 if (strcmp (target_buf, "OK"))
1781 error ("Error on target while setting tracepoints.");
1785 do_cleanups (old_chain);
1788 /* Tell target to treat text-like sections as transparent */
1789 remote_set_transparent_ranges ();
1790 /* Now insert traps and begin collecting data */
1792 remote_get_noisy_reply (target_buf);
1793 if (strcmp (target_buf, "OK"))
1794 error ("Bogus reply from target: %s", target_buf);
1795 set_traceframe_num (-1); /* all old traceframes invalidated */
1796 set_tracepoint_num (-1);
1797 set_traceframe_context(-1);
1798 trace_running_p = 1;
1799 if (trace_start_stop_hook)
1800 trace_start_stop_hook(1, from_tty);
1804 error ("Trace can only be run on remote targets.");
1809 trace_stop_command (args, from_tty)
1812 { /* STUB_COMM IS_IMPLEMENTED */
1813 if (target_is_remote ())
1816 remote_get_noisy_reply (target_buf);
1817 if (strcmp (target_buf, "OK"))
1818 error ("Bogus reply from target: %s", target_buf);
1819 trace_running_p = 0;
1820 if (trace_start_stop_hook)
1821 trace_start_stop_hook(0, from_tty);
1824 error ("Trace can only be run on remote targets.");
1827 unsigned long trace_running_p;
1829 /* tstatus command */
1831 trace_status_command (args, from_tty)
1834 { /* STUB_COMM IS_IMPLEMENTED */
1835 if (target_is_remote ())
1837 putpkt ("qTStatus");
1838 remote_get_noisy_reply (target_buf);
1840 if (target_buf[0] != 'T' ||
1841 (target_buf[1] != '0' && target_buf[1] != '1'))
1842 error ("Bogus reply from target: %s", target_buf);
1844 /* exported for use by the GUI */
1845 trace_running_p = (target_buf[1] == '1');
1848 error ("Trace can only be run on remote targets.");
1851 /* Worker function for the various flavors of the tfind command */
1853 finish_tfind_command (msg, from_tty)
1857 int target_frameno = -1, target_tracept = -1;
1858 CORE_ADDR old_frame_addr;
1859 struct symbol *old_func;
1862 old_frame_addr = FRAME_FP (get_current_frame ());
1863 old_func = find_pc_function (read_pc ());
1866 reply = remote_get_noisy_reply (msg);
1868 while (reply && *reply)
1871 if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
1873 /* A request for a non-existant trace frame has failed.
1874 Our response will be different, depending on FROM_TTY:
1876 If FROM_TTY is true, meaning that this command was
1877 typed interactively by the user, then give an error
1878 and DO NOT change the state of traceframe_number etc.
1880 However if FROM_TTY is false, meaning that we're either
1881 in a script, a loop, or a user-defined command, then
1882 DON'T give an error, but DO change the state of
1883 traceframe_number etc. to invalid.
1885 The rationalle is that if you typed the command, you
1886 might just have committed a typo or something, and you'd
1887 like to NOT lose your current debugging state. However
1888 if you're in a user-defined command or especially in a
1889 loop, then you need a way to detect that the command
1890 failed WITHOUT aborting. This allows you to write
1891 scripts that search thru the trace buffer until the end,
1892 and then continue on to do something else. */
1895 error ("Target failed to find requested trace frame.");
1899 printf_filtered ("End of trace buffer.\n");
1900 /* The following will not recurse, since it's special-cased */
1901 trace_find_command ("-1", from_tty);
1902 reply = NULL; /* break out of loop,
1903 (avoid recursive nonsense) */
1908 if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
1909 error ("Target failed to find requested trace frame.");
1911 case 'O': /* "OK"? */
1912 if (reply[1] == 'K' && reply[2] == '\0')
1915 error ("Bogus reply from target: %s", reply);
1918 error ("Bogus reply from target: %s", reply);
1921 flush_cached_frames ();
1922 registers_changed ();
1923 select_frame (get_current_frame (), 0);
1924 set_traceframe_num (target_frameno);
1925 set_tracepoint_num (target_tracept);
1926 if (target_frameno == -1)
1927 set_traceframe_context (-1);
1929 set_traceframe_context (read_pc ());
1935 /* NOTE: in immitation of the step command, try to determine
1936 whether we have made a transition from one function to another.
1937 If so, we'll print the "stack frame" (ie. the new function and
1938 it's arguments) -- otherwise we'll just show the new source line.
1940 This determination is made by checking (1) whether the current
1941 function has changed, and (2) whether the current FP has changed.
1942 Hack: if the FP wasn't collected, either at the current or the
1943 previous frame, assume that the FP has NOT changed. */
1945 if (old_func == find_pc_function (read_pc ()) &&
1946 (old_frame_addr == 0 ||
1947 FRAME_FP (get_current_frame ()) == 0 ||
1948 old_frame_addr == FRAME_FP (get_current_frame ())))
1953 print_stack_frame (selected_frame, selected_frame_level, source_only);
1958 /* trace_find_command takes a trace frame number n,
1959 sends "QTFrame:<n>" to the target,
1960 and accepts a reply that may contain several optional pieces
1961 of information: a frame number, a tracepoint number, and an
1962 indication of whether this is a trap frame or a stepping frame.
1964 The minimal response is just "OK" (which indicates that the
1965 target does not give us a frame number or a tracepoint number).
1966 Instead of that, the target may send us a string containing
1968 F<hexnum> (gives the selected frame number)
1969 T<hexnum> (gives the selected tracepoint number)
1974 trace_find_command (args, from_tty)
1977 { /* STUB_COMM PART_IMPLEMENTED */
1978 /* this should only be called with a numeric argument */
1982 if (target_is_remote ())
1984 if (trace_find_hook)
1985 trace_find_hook (args, from_tty);
1987 if (args == 0 || *args == 0)
1988 { /* TFIND with no args means find NEXT trace frame. */
1989 if (traceframe_number == -1)
1990 frameno = 0; /* "next" is first one */
1992 frameno = traceframe_number + 1;
1994 else if (0 == strcmp (args, "-"))
1996 if (traceframe_number == -1)
1997 error ("not debugging trace buffer");
1998 else if (from_tty && traceframe_number == 0)
1999 error ("already at start of trace buffer");
2001 frameno = traceframe_number - 1;
2004 frameno = parse_and_eval_address (args);
2007 error ("invalid input (%d is less than zero)", frameno);
2009 sprintf (target_buf, "QTFrame:%x", frameno);
2010 finish_tfind_command (target_buf, from_tty);
2013 error ("Trace can only be run on remote targets.");
2018 trace_find_end_command (args, from_tty)
2022 trace_find_command ("-1", from_tty);
2027 trace_find_none_command (args, from_tty)
2031 trace_find_command ("-1", from_tty);
2036 trace_find_start_command (args, from_tty)
2040 trace_find_command ("0", from_tty);
2043 /* tfind pc command */
2045 trace_find_pc_command (args, from_tty)
2048 { /* STUB_COMM PART_IMPLEMENTED */
2052 if (target_is_remote ())
2054 if (args == 0 || *args == 0)
2055 pc = read_pc (); /* default is current pc */
2057 pc = parse_and_eval_address (args);
2059 sprintf (target_buf, "QTFrame:pc:%x", pc);
2060 finish_tfind_command (target_buf, from_tty);
2063 error ("Trace can only be run on remote targets.");
2066 /* tfind tracepoint command */
2068 trace_find_tracepoint_command (args, from_tty)
2071 { /* STUB_COMM PART_IMPLEMENTED */
2075 if (target_is_remote ())
2077 if (args == 0 || *args == 0)
2078 if (tracepoint_number == -1)
2079 error ("No current tracepoint -- please supply an argument.");
2081 tdp = tracepoint_number; /* default is current TDP */
2083 tdp = parse_and_eval_address (args);
2085 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
2086 finish_tfind_command (target_buf, from_tty);
2089 error ("Trace can only be run on remote targets.");
2092 /* TFIND LINE command:
2094 This command will take a sourceline for argument, just like BREAK
2095 or TRACE (ie. anything that "decode_line_1" can handle).
2097 With no argument, this command will find the next trace frame
2098 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2101 trace_find_line_command (args, from_tty)
2104 { /* STUB_COMM PART_IMPLEMENTED */
2105 static CORE_ADDR start_pc, end_pc;
2106 struct symtabs_and_lines sals;
2107 struct symtab_and_line sal;
2109 struct cleanup *old_chain;
2111 if (target_is_remote ())
2113 if (args == 0 || *args == 0)
2115 sal = find_pc_line ((get_current_frame ())->pc, 0);
2117 sals.sals = (struct symtab_and_line *)
2118 xmalloc (sizeof (struct symtab_and_line));
2123 sals = decode_line_spec (args, 1);
2127 old_chain = make_cleanup (free, sals.sals);
2128 if (sal.symtab == 0)
2130 printf_filtered ("TFIND: No line number information available");
2133 /* This is useful for "info line *0x7f34". If we can't tell the
2134 user about a source line, at least let them have the symbolic
2136 printf_filtered (" for address ");
2138 print_address (sal.pc, gdb_stdout);
2139 printf_filtered (";\n -- will attempt to find by PC. \n");
2143 printf_filtered (".\n");
2144 return; /* no line, no PC; what can we do? */
2147 else if (sal.line > 0
2148 && find_line_pc_range (sal, &start_pc, &end_pc))
2150 if (start_pc == end_pc)
2152 printf_filtered ("Line %d of \"%s\"",
2153 sal.line, sal.symtab->filename);
2155 printf_filtered (" is at address ");
2156 print_address (start_pc, gdb_stdout);
2158 printf_filtered (" but contains no code.\n");
2159 sal = find_pc_line (start_pc, 0);
2161 find_line_pc_range (sal, &start_pc, &end_pc) &&
2163 printf_filtered ("Attempting to find line %d instead.\n",
2166 error ("Cannot find a good line.");
2170 /* Is there any case in which we get here, and have an address
2171 which the user would want to see? If we have debugging symbols
2172 and no line numbers? */
2173 error ("Line number %d is out of range for \"%s\".\n",
2174 sal.line, sal.symtab->filename);
2176 if (args && *args) /* find within range of stated line */
2177 sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
2178 else /* find OUTSIDE OF range of CURRENT line */
2179 sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
2180 finish_tfind_command (target_buf, from_tty);
2181 do_cleanups (old_chain);
2184 error ("Trace can only be run on remote targets.");
2187 /* tfind range command */
2189 trace_find_range_command (args, from_tty)
2192 { /* STUB_COMM PART_IMPLEMENTED */
2193 static CORE_ADDR start, stop;
2196 if (target_is_remote ())
2198 if (args == 0 || *args == 0)
2199 { /* XXX FIXME: what should default behavior be? */
2200 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2204 if (0 != (tmp = strchr (args, ',' )))
2206 *tmp++ = '\0'; /* terminate start address */
2207 while (isspace (*tmp))
2209 start = parse_and_eval_address (args);
2210 stop = parse_and_eval_address (tmp);
2213 { /* no explicit end address? */
2214 start = parse_and_eval_address (args);
2215 stop = start + 1; /* ??? */
2218 sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
2219 finish_tfind_command (target_buf, from_tty);
2222 error ("Trace can only be run on remote targets.");
2225 /* tfind outside command */
2227 trace_find_outside_command (args, from_tty)
2230 { /* STUB_COMM PART_IMPLEMENTED */
2231 CORE_ADDR start, stop;
2234 if (target_is_remote ())
2236 if (args == 0 || *args == 0)
2237 { /* XXX FIXME: what should default behavior be? */
2238 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2242 if (0 != (tmp = strchr (args, ',' )))
2244 *tmp++ = '\0'; /* terminate start address */
2245 while (isspace (*tmp))
2247 start = parse_and_eval_address (args);
2248 stop = parse_and_eval_address (tmp);
2251 { /* no explicit end address? */
2252 start = parse_and_eval_address (args);
2253 stop = start + 1; /* ??? */
2256 sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
2257 finish_tfind_command (target_buf, from_tty);
2260 error ("Trace can only be run on remote targets.");
2263 /* save-tracepoints command */
2265 tracepoint_save_command (args, from_tty)
2269 struct tracepoint *tp;
2270 struct action_line *line;
2272 char *i1 = " ", *i2 = " ";
2273 char *indent, *actionline;
2275 if (args == 0 || *args == 0)
2276 error ("Argument required (file name in which to save tracepoints");
2278 if (tracepoint_chain == 0)
2280 warning ("save-tracepoints: no tracepoints to save.\n");
2284 if (!(fp = fopen (args, "w")))
2285 error ("Unable to open file '%s' for saving tracepoints");
2287 ALL_TRACEPOINTS (tp)
2289 if (tp->addr_string)
2290 fprintf (fp, "trace %s\n", tp->addr_string);
2292 fprintf (fp, "trace *0x%x\n", tp->address);
2295 fprintf (fp, " passcount %d\n", tp->pass_count);
2299 fprintf (fp, " actions\n");
2301 for (line = tp->actions; line; line = line->next)
2303 struct cmd_list_element *cmd;
2305 QUIT; /* allow user to bail out with ^C */
2306 actionline = line->action;
2307 while (isspace(*actionline))
2310 fprintf (fp, "%s%s\n", indent, actionline);
2311 if (*actionline != '#') /* skip for comment lines */
2313 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2315 error ("Bad action list item: %s", actionline);
2316 if (cmd->function.cfunc == while_stepping_pseudocommand)
2318 else if (cmd->function.cfunc == end_actions_pseudocommand)
2326 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2330 /* info scope command: list the locals for a scope. */
2332 scope_info (args, from_tty)
2336 struct symtab_and_line sal;
2337 struct symtabs_and_lines sals;
2339 struct minimal_symbol *msym;
2340 struct block *block;
2341 char **canonical, *symname, *save_args = args;
2342 int i, j, nsyms, count = 0;
2344 if (args == 0 || *args == 0)
2345 error ("requires an argument (function, line or *addr) to define a scope");
2347 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2348 if (sals.nelts == 0)
2349 return; /* presumably decode_line_1 has already warned */
2351 /* Resolve line numbers to PC */
2352 resolve_sal_pc (&sals.sals[0]);
2353 block = block_for_pc (sals.sals[0].pc);
2357 QUIT; /* allow user to bail out with ^C */
2358 nsyms = BLOCK_NSYMS (block);
2359 for (i = 0; i < nsyms; i++)
2361 QUIT; /* allow user to bail out with ^C */
2363 printf_filtered ("Scope for %s:\n", save_args);
2365 sym = BLOCK_SYM (block, i);
2366 symname = SYMBOL_NAME (sym);
2367 if (symname == NULL || *symname == '\0')
2368 continue; /* probably botched, certainly useless */
2370 printf_filtered ("Symbol %s is ", symname);
2371 switch (SYMBOL_CLASS (sym)) {
2373 case LOC_UNDEF: /* messed up symbol? */
2374 printf_filtered ("a bogus symbol, class %d.\n",
2375 SYMBOL_CLASS (sym));
2376 count--; /* don't count this one */
2379 printf_filtered ("a constant with value %d (0x%x)",
2380 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2382 case LOC_CONST_BYTES:
2383 printf_filtered ("constant bytes: ");
2384 if (SYMBOL_TYPE (sym))
2385 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2386 fprintf_filtered (gdb_stdout, " %02x",
2387 (unsigned) SYMBOL_VALUE_BYTES (sym) [j]);
2390 printf_filtered ("in static storage at address ");
2391 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2394 printf_filtered ("a local variable in register $%s",
2395 REGISTER_NAME (SYMBOL_VALUE (sym)));
2399 printf_filtered ("an argument at stack/frame offset %ld",
2400 SYMBOL_VALUE (sym));
2403 printf_filtered ("a local variable at frame offset %ld",
2404 SYMBOL_VALUE (sym));
2407 printf_filtered ("a reference argument at offset %ld",
2408 SYMBOL_VALUE (sym));
2411 printf_filtered ("an argument in register $%s",
2412 REGISTER_NAME (SYMBOL_VALUE (sym)));
2414 case LOC_REGPARM_ADDR:
2415 printf_filtered ("the address of an argument, in register $%s",
2416 REGISTER_NAME (SYMBOL_VALUE (sym)));
2419 printf_filtered ("a typedef.\n");
2422 printf_filtered ("a label at address ");
2423 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2426 printf_filtered ("a function at address ");
2427 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2431 printf_filtered ("a variable at offset %d from register $%s",
2433 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2435 case LOC_BASEREG_ARG:
2436 printf_filtered ("an argument at offset %d from register $%s",
2438 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2440 case LOC_UNRESOLVED:
2441 msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2443 printf_filtered ("Unresolved Static");
2446 printf_filtered ("static storage at address ");
2447 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2451 case LOC_OPTIMIZED_OUT:
2452 printf_filtered ("optimized out.\n");
2455 if (SYMBOL_TYPE (sym))
2456 printf_filtered (", length %d.\n",
2457 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2459 if (BLOCK_FUNCTION (block))
2462 block = BLOCK_SUPERBLOCK (block);
2465 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2469 /* worker function (cleanup) */
2471 replace_comma (comma)
2479 trace_dump_command (args, from_tty)
2483 struct tracepoint *t;
2484 struct action_line *action;
2485 char *action_exp, *next_comma;
2486 struct cleanup *old_cleanups;
2487 int stepping_actions = 0;
2488 int stepping_frame = 0;
2490 if (!target_is_remote ())
2492 error ("Trace can only be run on remote targets.");
2496 if (tracepoint_number == -1)
2498 warning ("No current trace frame.");
2503 if (t->number == tracepoint_number)
2507 error ("No known tracepoint matches 'current' tracepoint #%d.",
2510 old_cleanups = make_cleanup (null_cleanup, NULL);
2512 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2513 tracepoint_number, traceframe_number);
2515 /* The current frame is a trap frame if the frame PC is equal
2516 to the tracepoint PC. If not, then the current frame was
2517 collected during single-stepping. */
2519 stepping_frame = (t->address != read_pc());
2521 for (action = t->actions; action; action = action->next)
2523 struct cmd_list_element *cmd;
2525 QUIT; /* allow user to bail out with ^C */
2526 action_exp = action->action;
2527 while (isspace (*action_exp))
2530 /* The collection actions to be done while stepping are
2531 bracketed by the commands "while-stepping" and "end". */
2533 if (*action_exp == '#') /* comment line */
2536 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2538 error ("Bad action list item: %s", action_exp);
2540 if (cmd->function.cfunc == while_stepping_pseudocommand)
2541 stepping_actions = 1;
2542 else if (cmd->function.cfunc == end_actions_pseudocommand)
2543 stepping_actions = 0;
2544 else if (cmd->function.cfunc == collect_pseudocommand)
2546 /* Display the collected data.
2547 For the trap frame, display only what was collected at the trap.
2548 Likewise for stepping frames, display only what was collected
2549 while stepping. This means that the two boolean variables,
2550 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2551 if (stepping_frame == stepping_actions)
2553 do { /* repeat over a comma-separated list */
2554 QUIT; /* allow user to bail out with ^C */
2555 if (*action_exp == ',')
2557 while (isspace (*action_exp))
2560 next_comma = strchr (action_exp, ',');
2562 if (0 == strncasecmp (action_exp, "$reg", 4))
2563 registers_info (NULL, from_tty);
2564 else if (0 == strncasecmp (action_exp, "$loc", 4))
2565 locals_info (NULL, from_tty);
2566 else if (0 == strncasecmp (action_exp, "$arg", 4))
2567 args_info (NULL, from_tty);
2572 make_cleanup (replace_comma, next_comma);
2575 printf_filtered ("%s = ", action_exp);
2576 output_command (action_exp, from_tty);
2577 printf_filtered ("\n");
2581 action_exp = next_comma;
2582 } while (action_exp && *action_exp == ',');
2586 discard_cleanups (old_cleanups);
2589 /* Convert the memory pointed to by mem into hex, placing result in buf.
2590 * Return a pointer to the last char put in buf (null)
2591 * "stolen" from sparc-stub.c
2594 static const char hexchars[]="0123456789abcdef";
2596 static unsigned char *
2597 mem2hex(mem, buf, count)
2608 *buf++ = hexchars[ch >> 4];
2609 *buf++ = hexchars[ch & 0xf];
2617 int get_traceframe_number()
2619 return traceframe_number;
2623 /* module initialization */
2625 _initialize_tracepoint ()
2627 tracepoint_chain = 0;
2628 tracepoint_count = 0;
2629 traceframe_number = -1;
2630 tracepoint_number = -1;
2632 set_internalvar (lookup_internalvar ("tpnum"),
2633 value_from_longest (builtin_type_int, (LONGEST) 0));
2634 set_internalvar (lookup_internalvar ("trace_frame"),
2635 value_from_longest (builtin_type_int, (LONGEST) -1));
2637 if (tracepoint_list.list == NULL)
2639 tracepoint_list.listsize = 128;
2640 tracepoint_list.list = xmalloc
2641 (tracepoint_list.listsize * sizeof (struct memrange));
2643 if (tracepoint_list.aexpr_list == NULL)
2645 tracepoint_list.aexpr_listsize = 128;
2646 tracepoint_list.aexpr_list = xmalloc
2647 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
2650 if (stepping_list.list == NULL)
2652 stepping_list.listsize = 128;
2653 stepping_list.list = xmalloc
2654 (stepping_list.listsize * sizeof (struct memrange));
2657 if (stepping_list.aexpr_list == NULL)
2659 stepping_list.aexpr_listsize = 128;
2660 stepping_list.aexpr_list = xmalloc
2661 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
2664 add_info ("scope", scope_info,
2665 "List the variables local to a scope");
2667 add_cmd ("tracepoints", class_trace, NO_FUNCTION,
2668 "Tracing of program execution without stopping the program.",
2671 add_info ("tracepoints", tracepoints_info,
2672 "Status of tracepoints, or tracepoint number NUMBER.\n\
2673 Convenience variable \"$tpnum\" contains the number of the\n\
2674 last tracepoint set.");
2676 add_info_alias ("tp", "tracepoints", 1);
2678 add_com ("save-tracepoints", class_trace, tracepoint_save_command,
2679 "Save current tracepoint definitions as a script.\n\
2680 Use the 'source' command in another debug session to restore them.");
2682 add_com ("tdump", class_trace, trace_dump_command,
2683 "Print everything collected at the current tracepoint.");
2685 add_prefix_cmd ("tfind", class_trace, trace_find_command,
2686 "Select a trace frame;\n\
2687 No argument means forward by one frame; '-' meand backward by one frame.",
2688 &tfindlist, "tfind ", 1, &cmdlist);
2690 add_cmd ("outside", class_trace, trace_find_outside_command,
2691 "Select a trace frame whose PC is outside the given \
2692 range.\nUsage: tfind outside addr1, addr2",
2695 add_cmd ("range", class_trace, trace_find_range_command,
2696 "Select a trace frame whose PC is in the given range.\n\
2697 Usage: tfind range addr1,addr2",
2700 add_cmd ("line", class_trace, trace_find_line_command,
2701 "Select a trace frame by source line.\n\
2702 Argument can be a line number (with optional source file), \n\
2703 a function name, or '*' followed by an address.\n\
2704 Default argument is 'the next source line that was traced'.",
2707 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2708 "Select a trace frame by tracepoint number.\n\
2709 Default is the tracepoint for the current trace frame.",
2712 add_cmd ("pc", class_trace, trace_find_pc_command,
2713 "Select a trace frame by PC.\n\
2714 Default is the current PC, or the PC of the current trace frame.",
2717 add_cmd ("end", class_trace, trace_find_end_command,
2718 "Synonym for 'none'.\n\
2719 De-select any trace frame and resume 'live' debugging.",
2722 add_cmd ("none", class_trace, trace_find_none_command,
2723 "De-select any trace frame and resume 'live' debugging.",
2726 add_cmd ("start", class_trace, trace_find_start_command,
2727 "Select the first trace frame in the trace buffer.",
2730 add_com ("tstatus", class_trace, trace_status_command,
2731 "Display the status of the current trace data collection.");
2733 add_com ("tstop", class_trace, trace_stop_command,
2734 "Stop trace data collection.");
2736 add_com ("tstart", class_trace, trace_start_command,
2737 "Start trace data collection.");
2739 add_com ("passcount", class_trace, trace_pass_command,
2740 "Set the passcount for a tracepoint.\n\
2741 The trace will end when the tracepoint has been passed 'count' times.\n\
2742 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2743 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2745 add_com ("end", class_trace, end_actions_pseudocommand,
2746 "Ends a list of commands or actions.\n\
2747 Several GDB commands allow you to enter a list of commands or actions.\n\
2748 Entering \"end\" on a line by itself is the normal way to terminate\n\
2750 Note: the \"end\" command cannot be used at the gdb prompt.");
2752 add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
2753 "Specify single-stepping behavior at a tracepoint.\n\
2754 Argument is number of instructions to trace in single-step mode\n\
2755 following the tracepoint. This command is normally followed by\n\
2756 one or more \"collect\" commands, to specify what to collect\n\
2757 while single-stepping.\n\n\
2758 Note: this command can only be used in a tracepoint \"actions\" list.");
2760 add_com_alias ("ws", "while-stepping", class_alias, 0);
2761 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2763 add_com ("collect", class_trace, collect_pseudocommand,
2764 "Specify one or more data items to be collected at a tracepoint.\n\
2765 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2766 collect all data (variables, registers) referenced by that expression.\n\
2767 Also accepts the following special arguments:\n\
2768 $regs -- all registers.\n\
2769 $args -- all function arguments.\n\
2770 $locals -- all variables local to the block/function scope.\n\
2771 Note: this command can only be used in a tracepoint \"actions\" list.");
2773 add_com ("actions", class_trace, trace_actions_command,
2774 "Specify the actions to be taken at a tracepoint.\n\
2775 Tracepoint actions may include collecting of specified data, \n\
2776 single-stepping, or enabling/disabling other tracepoints, \n\
2777 depending on target's capabilities.");
2779 add_cmd ("tracepoints", class_trace, delete_trace_command,
2780 "Delete specified tracepoints.\n\
2781 Arguments are tracepoint numbers, separated by spaces.\n\
2782 No argument means delete all tracepoints.",
2785 add_cmd ("tracepoints", class_trace, disable_trace_command,
2786 "Disable specified tracepoints.\n\
2787 Arguments are tracepoint numbers, separated by spaces.\n\
2788 No argument means disable all tracepoints.",
2791 add_cmd ("tracepoints", class_trace, enable_trace_command,
2792 "Enable specified tracepoints.\n\
2793 Arguments are tracepoint numbers, separated by spaces.\n\
2794 No argument means enable all tracepoints.",
2797 add_com ("trace", class_trace, trace_command,
2798 "Set a tracepoint at a specified line or function or address.\n\
2799 Argument may be a line number, function name, or '*' plus an address.\n\
2800 For a line number or function, trace at the start of its code.\n\
2801 If an address is specified, trace at that exact address.\n\n\
2802 Do \"help tracepoints\" for info on other tracepoint commands.");
2804 add_com_alias ("tp", "trace", class_alias, 0);
2805 add_com_alias ("tr", "trace", class_alias, 1);
2806 add_com_alias ("tra", "trace", class_alias, 1);
2807 add_com_alias ("trac", "trace", class_alias, 1);