1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "tracepoint.h"
25 #include "expression.h"
30 #include "gdb_string.h"
32 /* readline include files */
36 /* readline defines this. */
43 extern int info_verbose;
44 extern void (*readline_begin_hook) PARAMS ((char *, ...));
45 extern char * (*readline_hook) PARAMS ((char *));
46 extern void (*readline_end_hook) PARAMS ((void));
47 extern void x_command PARAMS ((char *, int));
49 /* If this definition isn't overridden by the header files, assume
50 that isatty and fileno exist on this system. */
52 #define ISATTY(FP) (isatty (fileno (FP)))
58 This module defines the following debugger commands:
59 trace : set a tracepoint on a function, line, or address.
60 info trace : list all debugger-defined tracepoints.
61 delete trace : delete one or more tracepoints.
62 enable trace : enable one or more tracepoints.
63 disable trace : disable one or more tracepoints.
64 actions : specify actions to be taken at a tracepoint.
65 passcount : specify a pass count for a tracepoint.
66 tstart : start a trace experiment.
67 tstop : stop a trace experiment.
68 tstatus : query the status of a trace experiment.
69 tfind : find a trace frame in the trace buffer.
70 tdump : print everything collected at the current tracepoint.
71 save-tracepoints : write tracepoint setup into a file.
73 This module defines the following user-visible debugger variables:
74 $trace_frame : sequence number of trace frame currently being debugged.
75 $trace_line : source line of trace frame currently being debugged.
76 $trace_file : source file of trace frame currently being debugged.
77 $tracepoint : tracepoint number of trace frame currently being debugged.
81 /* ======= Important global variables: ======= */
83 /* Chain of all tracepoints defined. */
84 struct tracepoint *tracepoint_chain;
86 /* Number of last tracepoint made. */
87 static int tracepoint_count;
89 /* Number of last traceframe collected. */
90 static int traceframe_number;
92 /* Tracepoint for last traceframe collected. */
93 static int tracepoint_number;
95 /* Symbol for function for last traceframe collected */
96 static struct symbol *traceframe_fun;
98 /* Symtab and line for last traceframe collected */
99 static struct symtab_and_line traceframe_sal;
101 /* Tracing command lists */
102 static struct cmd_list_element *tfindlist;
104 /* ======= Important command functions: ======= */
105 static void trace_command PARAMS ((char *, int));
106 static void tracepoints_info PARAMS ((char *, int));
107 static void delete_trace_command PARAMS ((char *, int));
108 static void enable_trace_command PARAMS ((char *, int));
109 static void disable_trace_command PARAMS ((char *, int));
110 static void trace_pass_command PARAMS ((char *, int));
111 static void trace_actions_command PARAMS ((char *, int));
112 static void trace_start_command PARAMS ((char *, int));
113 static void trace_stop_command PARAMS ((char *, int));
114 static void trace_status_command PARAMS ((char *, int));
115 static void trace_find_command PARAMS ((char *, int));
116 static void trace_find_pc_command PARAMS ((char *, int));
117 static void trace_find_tracepoint_command PARAMS ((char *, int));
118 static void trace_find_line_command PARAMS ((char *, int));
119 static void trace_find_range_command PARAMS ((char *, int));
120 static void trace_find_outside_command PARAMS ((char *, int));
121 static void tracepoint_save_command PARAMS ((char *, int));
122 static void trace_dump_command PARAMS ((char *, int));
125 /* Utility: returns true if "target remote" */
129 if (current_target.to_shortname &&
130 strcmp (current_target.to_shortname, "remote") == 0)
136 /* Utility: generate error from an incoming stub packet. */
142 return; /* not an error msg */
145 case '1': /* malformed packet error */
146 if (*++buf == '0') /* general case: */
147 error ("tracepoint.c: error in outgoing packet.");
149 error ("tracepoint.c: error in outgoing packet at field #%d.",
150 strtol (buf, NULL, 16));
152 error ("trace API error 0x%s.", ++buf);
154 error ("Target returns error code '%s'.", buf);
158 /* Utility: wait for reply from stub, while accepting "O" packets */
160 remote_get_noisy_reply (buf)
163 do /* loop on reply from remote stub */
167 error ("Target does not support this command.");
168 else if (buf[0] == 'E')
170 else if (buf[0] == 'O' &&
172 remote_console_output (buf + 1); /* 'O' message from stub */
174 return buf; /* here's the actual reply */
178 /* Set tracepoint count to NUM. */
180 set_tracepoint_count (num)
183 tracepoint_count = num;
184 set_internalvar (lookup_internalvar ("tpnum"),
185 value_from_longest (builtin_type_int, (LONGEST) num));
188 /* Set traceframe number to NUM. */
190 set_traceframe_num (num)
193 traceframe_number = num;
194 set_internalvar (lookup_internalvar ("trace_frame"),
195 value_from_longest (builtin_type_int, (LONGEST) num));
198 /* Set tracepoint number to NUM. */
200 set_tracepoint_num (num)
203 tracepoint_number = num;
204 set_internalvar (lookup_internalvar ("tracepoint"),
205 value_from_longest (builtin_type_int, (LONGEST) num));
208 /* Set externally visible debug variables for querying/printing
209 the traceframe context (line, function, file) */
212 set_traceframe_context (trace_pc)
215 static struct type *func_string, *file_string;
216 static struct type *func_range, *file_range;
217 static value_ptr func_val, file_val;
218 static struct type *charstar;
221 if (charstar == (struct type *) NULL)
222 charstar = lookup_pointer_type (builtin_type_char);
224 if (trace_pc == -1) /* cease debugging any trace buffers */
227 traceframe_sal.pc = traceframe_sal.line = 0;
228 traceframe_sal.symtab = NULL;
229 set_internalvar (lookup_internalvar ("trace_func"),
230 value_from_longest (charstar, (LONGEST) 0));
231 set_internalvar (lookup_internalvar ("trace_file"),
232 value_from_longest (charstar, (LONGEST) 0));
233 set_internalvar (lookup_internalvar ("trace_line"),
234 value_from_longest (builtin_type_int, (LONGEST) -1));
238 /* save as globals for internal use */
239 traceframe_sal = find_pc_line (trace_pc, 0);
240 traceframe_fun = find_pc_function (trace_pc);
242 /* save linenumber as "$trace_line", a debugger variable visible to users */
243 set_internalvar (lookup_internalvar ("trace_line"),
244 value_from_longest (builtin_type_int,
245 (LONGEST) traceframe_sal.line));
247 /* save func name as "$trace_func", a debugger variable visible to users */
248 if (traceframe_fun == NULL ||
249 SYMBOL_NAME (traceframe_fun) == NULL)
250 set_internalvar (lookup_internalvar ("trace_func"),
251 value_from_longest (charstar, (LONGEST) 0));
254 len = strlen (SYMBOL_NAME (traceframe_fun));
255 func_range = create_range_type (func_range,
256 builtin_type_int, 0, len - 1);
257 func_string = create_array_type (func_string,
258 builtin_type_char, func_range);
259 func_val = allocate_value (func_string);
260 VALUE_TYPE (func_val) = func_string;
261 memcpy (VALUE_CONTENTS_RAW (func_val),
262 SYMBOL_NAME (traceframe_fun),
264 func_val->modifiable = 0;
265 set_internalvar (lookup_internalvar ("trace_func"), func_val);
268 /* save file name as "$trace_file", a debugger variable visible to users */
269 if (traceframe_sal.symtab == NULL ||
270 traceframe_sal.symtab->filename == NULL)
271 set_internalvar (lookup_internalvar ("trace_file"),
272 value_from_longest (charstar, (LONGEST) 0));
275 len = strlen (traceframe_sal.symtab->filename);
276 file_range = create_range_type (file_range,
277 builtin_type_int, 0, len - 1);
278 file_string = create_array_type (file_string,
279 builtin_type_char, file_range);
280 file_val = allocate_value (file_string);
281 VALUE_TYPE (file_val) = file_string;
282 memcpy (VALUE_CONTENTS_RAW (file_val),
283 traceframe_sal.symtab->filename,
285 file_val->modifiable = 0;
286 set_internalvar (lookup_internalvar ("trace_file"), file_val);
290 /* Low level routine to set a tracepoint.
291 Returns the tracepoint object so caller can set other things.
292 Does not set the tracepoint number!
293 Does not print anything.
295 ==> This routine should not be called if there is a chance of later
296 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
297 your arguments BEFORE calling this routine! */
299 static struct tracepoint *
300 set_raw_tracepoint (sal)
301 struct symtab_and_line sal;
303 register struct tracepoint *t, *tc;
304 struct cleanup *old_chain;
306 t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
307 old_chain = make_cleanup (free, t);
308 memset (t, 0, sizeof (*t));
310 if (sal.symtab == NULL)
311 t->source_file = NULL;
316 t->source_file = (char *) xmalloc (strlen (sal.symtab->filename) +
317 strlen (sal.symtab->dirname) + 2);
319 strcpy (t->source_file, sal.symtab->dirname);
323 if (*(--p) != '/') /* Will this work on Windows? */
324 strcat (t->source_file, "/");
325 strcat (t->source_file, sal.symtab->filename);
328 t->language = current_language->la_language;
329 t->input_radix = input_radix;
330 t->line_number = sal.line;
331 t->enabled = enabled;
335 t->addr_string = NULL;
337 /* Add this tracepoint to the end of the chain
338 so that a list of tracepoints will come out in order
339 of increasing numbers. */
341 tc = tracepoint_chain;
343 tracepoint_chain = t;
350 discard_cleanups (old_chain);
354 /* Set a tracepoint according to ARG (function, linenum or *address) */
356 trace_command (arg, from_tty)
360 char **canonical = (char **)NULL;
361 struct symtabs_and_lines sals;
362 struct symtab_and_line sal;
363 struct tracepoint *t;
364 char *addr_start = 0, *addr_end = 0;
368 error ("trace command requires an argument");
370 if (from_tty && info_verbose)
371 printf_filtered ("TRACE %s\n", arg);
379 sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0, &canonical);
382 return; /* ??? Presumably decode_line_1 has already warned? */
384 /* Resolve all line numbers to PC's */
385 for (i = 0; i < sals.nelts; i++)
386 resolve_sal_pc (&sals.sals[i]);
388 /* Now set all the tracepoints. */
389 for (i = 0; i < sals.nelts; i++)
393 t = set_raw_tracepoint (sal);
394 set_tracepoint_count (tracepoint_count + 1);
395 t->number = tracepoint_count;
397 /* If a canonical line spec is needed use that instead of the
399 if (canonical != (char **)NULL && canonical[i] != NULL)
400 t->addr_string = canonical[i];
402 t->addr_string = savestring (addr_start, addr_end - addr_start);
404 /* Let the UI know of any additions */
405 if (create_tracepoint_hook)
406 create_tracepoint_hook (t);
411 printf_filtered ("Multiple tracepoints were set.\n");
412 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
416 /* Print information on tracepoint number TPNUM_EXP, or all if omitted. */
419 tracepoints_info (tpnum_exp, from_tty)
423 struct tracepoint *t;
424 struct action_line *action;
425 int found_a_tracepoint = 0;
426 char wrap_indent[80];
430 char *i1 = "\t", *i2 = "\t ";
431 char *indent, *actionline;;
435 tpnum = parse_and_eval_address (tpnum_exp);
438 if (tpnum == -1 || tpnum == t->number)
440 extern int addressprint; /* print machine addresses? */
442 if (!found_a_tracepoint++)
444 printf_filtered ("Num Enb ");
446 printf_filtered ("Address ");
447 printf_filtered ("PassC StepC What\n");
449 strcpy (wrap_indent, " ");
451 strcat (wrap_indent, " ");
453 printf_filtered ("%-3d %-3s ", t->number,
454 t->enabled == enabled ? "y" : "n");
456 printf_filtered ("%s ",
457 local_hex_string_custom ((unsigned long) t->address,
459 printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
463 sym = find_pc_function (t->address);
466 fputs_filtered ("in ", gdb_stdout);
467 fputs_filtered (SYMBOL_SOURCE_NAME (sym), gdb_stdout);
468 wrap_here (wrap_indent);
469 fputs_filtered (" at ", gdb_stdout);
471 fputs_filtered (t->source_file, gdb_stdout);
472 printf_filtered (":%d", t->line_number);
475 print_address_symbolic (t->address, gdb_stdout, demangle, " ");
477 printf_filtered ("\n");
480 printf_filtered (" Actions for tracepoint %d: \n", t->number);
482 for (action = t->actions; action; action = action->next)
485 actionline = action->action;
486 while (isspace(*actionline))
489 printf_filtered ("%s%s\n", indent, actionline);
490 if (0 == strncasecmp (actionline, "while-stepping", 14))
492 else if (0 == strncasecmp (actionline, "end", 3))
495 printf_filtered ("\t%s\n", action->action);
500 if (!found_a_tracepoint)
503 printf_filtered ("No tracepoints.\n");
505 printf_filtered ("No tracepoint number %d.\n", tpnum);
509 /* Optimization: the code to parse an enable, disable, or delete TP command
510 is virtually identical except for whether it performs an enable, disable,
511 or delete. Therefore I've combined them into one function with an opcode.
513 enum tracepoint_opcode
520 /* This function implements enable, disable and delete. */
522 tracepoint_operation (t, from_tty, opcode)
523 struct tracepoint *t;
525 enum tracepoint_opcode opcode;
527 struct tracepoint *t2;
531 t->enabled = enabled;
532 if (modify_tracepoint_hook)
533 modify_tracepoint_hook (t);
536 t->enabled = disabled;
537 if (modify_tracepoint_hook)
538 modify_tracepoint_hook (t);
541 if (tracepoint_chain == t)
542 tracepoint_chain = t->next;
551 /* Let the UI know of any deletions */
552 if (delete_tracepoint_hook)
553 delete_tracepoint_hook (t);
556 free (t->addr_string);
558 free (t->source_file);
567 /* Utility: parse a tracepoint number and look it up in the list. */
569 get_tracepoint_by_number (arg)
572 struct tracepoint *t;
578 error ("Bad tracepoint argument");
580 if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
581 tpnum = tracepoint_count;
582 else if (**arg == '$') /* handle convenience variable */
584 /* Make a copy of the name, so we can null-terminate it
585 to pass to lookup_internalvar(). */
587 while (isalnum(*end) || *end == '_')
589 copy = (char *) alloca (end - *arg);
590 strncpy (copy, *arg + 1, (end - *arg - 1));
591 copy[end - *arg - 1] = '\0';
594 val = value_of_internalvar (lookup_internalvar (copy));
595 if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
596 error ("Convenience variable must have integral type.");
597 tpnum = (int) value_as_long (val);
599 else /* handle tracepoint number */
601 tpnum = strtol (*arg, arg, 10);
604 if (t->number == tpnum)
608 warning ("No tracepoint number %d.\n", tpnum);
612 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
614 map_args_over_tracepoints (args, from_tty, opcode)
617 enum tracepoint_opcode opcode;
619 struct tracepoint *t, *tmp;
623 if (args == 0 || *args == 0) /* do them all */
624 ALL_TRACEPOINTS_SAFE (t, tmp)
625 tracepoint_operation (t, from_tty, opcode);
629 if (t = get_tracepoint_by_number (&args))
630 tracepoint_operation (t, from_tty, opcode);
631 while (*args == ' ' || *args == '\t')
636 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
638 enable_trace_command (args, from_tty)
643 map_args_over_tracepoints (args, from_tty, enable);
646 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
648 disable_trace_command (args, from_tty)
653 map_args_over_tracepoints (args, from_tty, disable);
656 /* Remove a tracepoint (or all if no argument) */
658 delete_trace_command (args, from_tty)
664 if (!query ("Delete all tracepoints? "))
667 map_args_over_tracepoints (args, from_tty, delete);
670 /* Set passcount for tracepoint.
672 First command argument is passcount, second is tracepoint number.
673 If tracepoint number omitted, apply to most recently defined.
674 Also accepts special argument "all". */
677 trace_pass_command (args, from_tty)
681 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
684 if (args == 0 || *args == 0)
685 error ("PASS command requires an argument (count + optional TP num)");
687 count = strtoul (args, &args, 10); /* count comes first, then TP num */
689 while (*args && isspace (*args))
692 if (*args && strncasecmp (args, "all", 3) == 0)
693 args += 3; /* skip special argument "all" */
695 t1 = get_tracepoint_by_number (&args);
698 return; /* error, bad tracepoint number */
701 if (t1 == (struct tracepoint *) -1 || t1 == t2)
703 t2->pass_count = count;
705 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
710 /* ACTIONS functions: */
712 /* Prototypes for action-parsing utility commands */
713 static void read_actions PARAMS((struct tracepoint *));
714 static char *parse_and_eval_memrange PARAMS ((char *,
720 /* The three functions:
721 collect_pseudocommand,
722 while_stepping_pseudocommand, and
723 end_actions_pseudocommand
724 are placeholders for "commands" that are actually ONLY to be used
725 within a tracepoint action list. If the actual function is ever called,
726 it means that somebody issued the "command" at the top level,
727 which is always an error. */
730 end_actions_pseudocommand (args, from_tty)
734 error ("This command cannot be used at the top level.");
738 while_stepping_pseudocommand (args, from_tty)
742 error ("This command can only be used in a tracepoint actions list.");
746 collect_pseudocommand (args, from_tty)
750 error ("This command can only be used in a tracepoint actions list.");
753 /* Enter a list of actions for a tracepoint. */
755 trace_actions_command (args, from_tty)
759 struct tracepoint *t;
762 char *end_msg = "End with a line saying just \"end\".";
764 if (t = get_tracepoint_by_number (&args))
766 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
771 if (readline_begin_hook)
772 (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
773 else if (input_from_terminal_p ())
774 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
780 if (readline_end_hook)
781 (*readline_end_hook) ();
783 /* tracepoints_changed () */
785 /* else error, just return; */
796 static enum actionline_type validate_actionline PARAMS((char **,
797 struct tracepoint *));
799 /* worker function */
802 struct tracepoint *t;
805 char *prompt1 = "> ", *prompt2 = " > ";
806 char *prompt = prompt1;
807 enum actionline_type linetype;
808 extern FILE *instream;
809 struct action_line *next = NULL, *temp;
810 struct cleanup *old_chain;
812 /* Control-C quits instantly if typed while in this loop
813 since it should not wait until the user types a newline. */
817 signal (STOP_SIGNAL, stop_sig);
819 old_chain = make_cleanup (free_actions, (void *) t);
822 /* Make sure that all output has been output. Some machines may let
823 you get away with leaving out some of the gdb_flush, but not all. */
825 gdb_flush (gdb_stdout);
826 gdb_flush (gdb_stderr);
828 if (readline_hook && instream == NULL)
829 line = (*readline_hook) (prompt);
830 else if (instream == stdin && ISATTY (instream))
832 line = readline (prompt);
833 if (line && *line) /* add it to command history */
837 line = gdb_readline (0);
839 linetype = validate_actionline (&line, t);
840 if (linetype == BADLINE)
841 continue; /* already warned -- collect another line */
843 temp = xmalloc (sizeof (struct action_line));
847 if (next == NULL) /* first action for this tracepoint? */
848 t->actions = next = temp;
855 if (linetype == STEPPING) /* begin "while-stepping" */
856 if (prompt == prompt2)
858 warning ("Already processing 'while-stepping'");
862 prompt = prompt2; /* change prompt for stepping actions */
863 else if (linetype == END)
864 if (prompt == prompt2)
865 prompt = prompt1; /* end of single-stepping actions */
867 break; /* end of actions */
871 signal (STOP_SIGNAL, SIG_DFL);
874 discard_cleanups (old_chain);
877 /* worker function */
878 static enum actionline_type
879 validate_actionline (line, t)
881 struct tracepoint *t;
883 struct cmd_list_element *c;
884 struct expression *exp;
885 value_ptr temp, temp2;
888 for (p = *line; isspace (*p); )
891 /* symbol lookup etc. */
892 if (*p == '\0') /* empty line: just prompt for another line. */
895 if (*p == '#') /* comment line */
898 c = lookup_cmd (&p, cmdlist, "", -1, 1);
901 warning ("'%s' is not an action that I know, or is ambiguous.", p);
905 if (c->function.cfunc == collect_pseudocommand)
907 do { /* repeat over a comma-separated list */
911 if (*p == '$') /* look for special pseudo-symbols */
914 bfd_signed_vma offset;
916 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
917 (0 == strncasecmp ("arg", p + 1, 3)) ||
918 (0 == strncasecmp ("loc", p + 1, 3)))
921 else if (p[1] == '(') /* literal memrange */
923 char *temp, *newline;
925 newline = malloc (strlen (*line) + 32);
926 strcpy (newline, *line);
927 newline[p - *line] = '\0';
928 /* newline is now a copy of line, up to "p" (the memrange) */
929 temp = parse_and_eval_memrange (p, t->address,
930 &typecode, &offset, &size) + 1;
931 /* now compose the memrange as a literal value */
933 sprintf (newline + strlen (newline),
937 sprintf (newline + strlen (newline),
939 reg_names[typecode], offset, size);
940 /* now add the remainder of the old line to the new one */
941 p = newline + strlen (newline);
943 strcat (newline, temp);
950 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
952 if (exp->elts[0].opcode != OP_VAR_VALUE &&
953 exp->elts[0].opcode != UNOP_MEMVAL &&
954 /*exp->elts[0].opcode != OP_LONG && */
955 /*exp->elts[0].opcode != UNOP_CAST && */
956 exp->elts[0].opcode != OP_REGISTER)
958 warning ("collect requires a variable or register name.\n");
961 if (exp->elts[0].opcode == OP_VAR_VALUE)
962 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
964 warning ("%s is constant (value %d): will not be collected.",
965 SYMBOL_NAME (exp->elts[2].symbol),
966 SYMBOL_VALUE (exp->elts[2].symbol));
969 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
971 warning ("%s is optimized away and cannot be collected.",
972 SYMBOL_NAME (exp->elts[2].symbol));
976 } while (p && *p++ == ',');
979 else if (c->function.cfunc == while_stepping_pseudocommand)
981 char *steparg; /* in case warning is necessary */
989 t->step_count = strtol (p, &p, 0);
990 if (t->step_count == 0)
992 warning ("'%s' evaluates to zero -- command ignored.");
1000 else if (c->function.cfunc == end_actions_pseudocommand)
1004 warning ("'%s' is not a supported tracepoint action.", *line);
1009 /* worker function */
1012 struct tracepoint *t;
1014 struct action_line *line, *next;
1016 for (line = t->actions; line; line = next)
1020 free (line->action);
1027 int type; /* 0 for absolute memory range, else basereg number */
1028 bfd_signed_vma start;
1032 struct collection_list {
1033 unsigned char regs_mask[8]; /* room for up to 256 regs */
1036 struct memrange *list;
1037 } tracepoint_list, stepping_list;
1039 /* MEMRANGE functions: */
1041 /* parse a memrange spec from command input */
1043 parse_and_eval_memrange (arg, addr, typecode, offset, size)
1046 long *typecode, *size;
1047 bfd_signed_vma *offset;
1050 struct expression *exp;
1053 if (*arg++ != '$' || *arg++ != '(')
1054 error ("Internal: bad argument to parse_and_eval_memrange: %s", start);
1056 if (*arg == '$') /* register for relative memrange? */
1058 exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
1059 if (exp->elts[0].opcode != OP_REGISTER)
1060 error ("Bad register operand for memrange: %s", start);
1062 error ("missing comma for memrange: %s", start);
1063 *typecode = exp->elts[1].longconst;
1066 *typecode = -1; /* absolute memrange; */
1068 exp = parse_exp_1 (&arg, 0, 1);
1069 *offset = value_as_pointer (evaluate_expression (exp));
1071 /* now parse the size */
1073 error ("missing comma for memrange: %s", start);
1075 exp = parse_exp_1 (&arg, 0, 0);
1076 *size = value_as_long (evaluate_expression (exp));
1079 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1080 *typecode, *offset, *size);
1085 /* compare memranges for qsort */
1088 struct memrange *a, *b;
1090 if (a->type < b->type) return -1;
1091 if (a->type > b->type) return 1;
1094 if ((bfd_vma) a->start < (bfd_vma) b->start) return -1;
1095 if ((bfd_vma) a->start > (bfd_vma) b->start) return 1;
1099 if (a->start < b->start) return -1;
1100 if (a->start > b->start) return 1;
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)
1181 struct collection_list *collect;
1186 bfd_signed_vma offset;
1188 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1189 switch (SYMBOL_CLASS (sym)) {
1191 printf_filtered ("%s: don't know symbol class %d\n",
1192 SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1195 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1196 SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1199 offset = SYMBOL_VALUE_ADDRESS (sym);
1201 printf_filtered ("LOC_STATIC %s: collect %d bytes at 0x%08x\n",
1202 SYMBOL_NAME (sym), len, offset);
1203 add_memrange (collect, -1, offset, len); /* 0 == memory */
1207 reg = SYMBOL_VALUE (sym);
1209 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1210 add_register (collect, reg);
1214 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1215 printf_filtered (" (will not collect %s)\n",
1218 case LOC_REGPARM_ADDR:
1219 reg = SYMBOL_VALUE (sym);
1223 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1224 SYMBOL_NAME (sym), len, offset, reg);
1226 add_memrange (collect, reg, offset, len);
1230 offset = SYMBOL_VALUE (sym);
1234 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1235 SYMBOL_NAME (sym), len, offset, reg);
1237 add_memrange (collect, reg, offset, len);
1240 case LOC_BASEREG_ARG:
1241 reg = SYMBOL_BASEREG (sym);
1242 offset = SYMBOL_VALUE (sym);
1245 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1246 SYMBOL_NAME (sym), len, offset, reg);
1248 add_memrange (collect, reg, offset, len);
1250 case LOC_UNRESOLVED:
1251 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1253 case LOC_OPTIMIZED_OUT:
1254 printf_filtered ("%s has been optimized out of existance.\n",
1260 /* Add all locals (or args) symbols to collection list */
1262 add_local_symbols (collect, pc, type)
1263 struct collection_list *collect;
1268 struct block *block;
1269 int i, nsyms, count = 0;
1271 block = block_for_pc (pc);
1274 nsyms = BLOCK_NSYMS (block);
1275 for (i = 0; i < nsyms; i++)
1277 sym = BLOCK_SYM (block, i);
1278 switch (SYMBOL_CLASS (sym)) {
1283 if (type == 'L') /* collecting Locals */
1286 collect_symbol (collect, sym);
1293 case LOC_REGPARM_ADDR:
1294 case LOC_BASEREG_ARG:
1295 if (type == 'A') /* collecting Arguments */
1298 collect_symbol (collect, sym);
1302 if (BLOCK_FUNCTION (block))
1305 block = BLOCK_SUPERBLOCK (block);
1308 warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1311 /* worker function */
1313 clear_collection_list (list)
1314 struct collection_list *list;
1316 list->next_memrange = 0;
1317 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1320 /* reduce a collection list to string form (for gdb protocol) */
1322 stringify_collection_list (list, string)
1323 struct collection_list *list;
1329 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1330 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1332 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1335 printf_filtered ("\nCollecting registers (mask): 0x");
1340 printf_filtered ("%02X", list->regs_mask[i]);
1341 sprintf (end, "%02X", list->regs_mask[i]);
1346 printf_filtered ("\n");
1347 if (list->next_memrange > 0 && info_verbose)
1348 printf_filtered ("Collecting memranges: \n");
1349 for (i = 0; i < list->next_memrange; i++)
1352 printf_filtered ("(%d, 0x%x, %d)\n",
1354 list->list[i].start,
1355 list->list[i].end - list->list[i].start);
1356 sprintf (end, "M%X,%X,%X",
1358 list->list[i].start,
1359 list->list[i].end - list->list[i].start);
1360 end += strlen (end);
1368 /* render all actions into gdb protocol */
1370 encode_actions (t, tdp_actions, step_count, stepping_actions)
1371 struct tracepoint *t;
1373 unsigned long *step_count;
1374 char **stepping_actions;
1376 static char tdp_buff[2048], step_buff[2048];
1378 struct expression *exp;
1379 struct action_line *action;
1380 bfd_signed_vma offset;
1383 struct collection_list *collect;
1384 struct cmd_list_element *cmd;
1386 clear_collection_list (&tracepoint_list);
1387 clear_collection_list (&stepping_list);
1388 collect = &tracepoint_list;
1390 *tdp_actions = NULL;
1391 *stepping_actions = NULL;
1393 for (action = t->actions; action; action = action->next)
1395 action_exp = action->action;
1396 while (isspace (*action_exp))
1399 if (*action_exp == '#') /* comment line */
1402 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1404 error ("Bad action list item: %s", action_exp);
1406 if (cmd->function.cfunc == collect_pseudocommand)
1408 do { /* repeat over a comma-separated list */
1409 while (isspace (*action_exp))
1412 if (0 == strncasecmp ("$reg", action_exp, 4))
1414 for (i = 0; i < NUM_REGS; i++)
1415 add_register (collect, i);
1416 action_exp = strchr (action_exp, ','); /* more? */
1418 else if (0 == strncasecmp ("$arg", action_exp, 4))
1420 add_local_symbols (collect, t->address, 'A');
1421 action_exp = strchr (action_exp, ','); /* more? */
1423 else if (0 == strncasecmp ("$loc", action_exp, 4))
1425 add_local_symbols (collect, t->address, 'L');
1426 action_exp = strchr (action_exp, ','); /* more? */
1428 else if (action_exp[0] == '$' &&
1429 action_exp[1] == '(') /* literal memrange */
1431 long typecode, size;
1432 bfd_signed_vma offset;
1434 action_exp = parse_and_eval_memrange (action_exp,
1439 add_memrange (collect, typecode, offset, size);
1443 unsigned long addr, len;
1445 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1446 switch (exp->elts[0].opcode) {
1448 i = exp->elts[1].longconst;
1450 printf_filtered ("OP_REGISTER: ");
1451 add_register (collect, i);
1455 /* safe because we know it's a simple expression */
1456 tempval = evaluate_expression (exp);
1457 addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1458 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1459 add_memrange (collect, -1, addr, len);
1463 collect_symbol (collect, exp->elts[2].symbol);
1467 addr = exp->elts[2].longconst;
1468 if (*action_exp == ':')
1470 exp = parse_exp_1 (&action_exp,
1471 block_for_pc (t->address),
1473 if (exp->elts[0].opcode == OP_LONG)
1474 len = exp->elts[2].longconst;
1476 error ("length field requires a literal long const");
1481 add_memrange (collect, -1, addr, len);
1486 } while (action_exp && *action_exp++ == ',');
1488 else if (cmd->function.cfunc == while_stepping_pseudocommand)
1490 collect = &stepping_list;
1492 else if (cmd->function.cfunc == end_actions_pseudocommand)
1494 if (collect == &stepping_list) /* end stepping actions */
1495 collect = &tracepoint_list;
1497 break; /* end tracepoint actions */
1500 memrange_sortmerge (&tracepoint_list);
1501 memrange_sortmerge (&stepping_list);
1503 *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
1504 *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
1507 static char target_buf[2048];
1511 Tell target to lear any previous trace experiment.
1512 Walk the list of tracepoints, and send them (and their actions)
1513 to the target. If no errors,
1514 Tell target to start a new trace experiment. */
1517 trace_start_command (args, from_tty)
1520 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1521 struct tracepoint *t;
1524 char *stepping_actions;
1525 unsigned long step_count;
1527 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1529 if (target_is_remote ())
1532 remote_get_noisy_reply (target_buf);
1533 if (strcmp (target_buf, "OK"))
1534 error ("Target does not support this command.");
1538 int ss_count; /* if actions include singlestepping */
1539 int disable_mask; /* ??? */
1540 int enable_mask; /* ??? */
1542 sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address,
1543 t->enabled == enabled ? 'E' : 'D',
1544 t->step_count, t->pass_count);
1547 encode_actions (t, &tdp_actions, &step_count, &stepping_actions);
1548 /* do_single_steps (t); */
1551 if (strlen (buf) + strlen (tdp_actions) >= sizeof (buf))
1552 error ("Actions for tracepoint %d too complex; please simplify.",
1554 strcat (buf, tdp_actions);
1556 if (stepping_actions)
1559 if (strlen (buf) + strlen (stepping_actions) >= sizeof (buf))
1560 error ("Actions for tracepoint %d too complex; please simplify.",
1562 strcat (buf, stepping_actions);
1566 remote_get_noisy_reply (target_buf);
1567 if (strcmp (target_buf, "OK"))
1568 error ("Target does not support tracepoints.");
1571 remote_get_noisy_reply (target_buf);
1572 if (strcmp (target_buf, "OK"))
1573 error ("Bogus reply from target: %s", target_buf);
1574 set_traceframe_num (-1); /* all old traceframes invalidated */
1575 set_tracepoint_num (-1);
1576 set_traceframe_context(-1);
1579 printf_filtered ("Trace can only be run on remote targets.\n");
1584 trace_stop_command (args, from_tty)
1587 { /* STUB_COMM IS_IMPLEMENTED */
1588 if (target_is_remote ())
1591 remote_get_noisy_reply (target_buf);
1592 if (strcmp (target_buf, "OK"))
1593 error ("Bogus reply from target: %s", target_buf);
1596 error ("Trace can only be run on remote targets.");
1599 /* tstatus command */
1601 trace_status_command (args, from_tty)
1604 { /* STUB_COMM IS_IMPLEMENTED */
1605 if (target_is_remote ())
1607 putpkt ("qTStatus");
1608 remote_get_noisy_reply (target_buf);
1609 if (strcmp (target_buf, "OK"))
1610 error ("Bogus reply from target: %s", target_buf);
1613 error ("Trace can only be run on remote targets.");
1616 /* Worker function for the various flavors of the tfind command */
1618 finish_tfind_command (msg, from_tty)
1622 int target_frameno = -1, target_tracept = -1;
1623 CORE_ADDR old_frame_addr;
1624 struct symbol *old_func;
1627 old_frame_addr = FRAME_FP (get_current_frame ());
1628 old_func = find_pc_function (read_pc ());
1631 reply = remote_get_noisy_reply (msg);
1633 while (reply && *reply)
1636 if ((target_frameno = strtol (++reply, &reply, 16)) == -1)
1638 /* A request for a non-existant trace frame has failed.
1639 Our response will be different, depending on FROM_TTY:
1641 If FROM_TTY is true, meaning that this command was
1642 typed interactively by the user, then give an error
1643 and DO NOT change the state of traceframe_number etc.
1645 However if FROM_TTY is false, meaning that we're either
1646 in a script, a loop, or a user-defined command, then
1647 DON'T give an error, but DO change the state of
1648 traceframe_number etc. to invalid.
1650 The rationalle is that if you typed the command, you
1651 might just have committed a typo or something, and you'd
1652 like to NOT lose your current debugging state. However
1653 if you're in a user-defined command or especially in a
1654 loop, then you need a way to detect that the command
1655 failed WITHOUT aborting. This allows you to write
1656 scripts that search thru the trace buffer until the end,
1657 and then continue on to do something else. */
1660 error ("Target failed to find requested trace frame.");
1664 printf_filtered ("End of trace buffer.\n");
1665 /* The following will not recurse, since it's special-cased */
1666 trace_find_command ("-1", from_tty);
1667 reply = NULL; /* break out of loop,
1668 (avoid recursive nonsense) */
1673 if ((target_tracept = strtol (++reply, &reply, 16)) == -1)
1674 error ("Target failed to find requested trace frame.");
1676 case 'O': /* "OK"? */
1677 if (reply[1] == 'K' && reply[2] == '\0')
1680 error ("Bogus reply from target: %s", reply);
1683 error ("Bogus reply from target: %s", reply);
1686 flush_cached_frames ();
1687 registers_changed ();
1688 select_frame (get_current_frame (), 0);
1689 set_traceframe_num (target_frameno);
1690 set_tracepoint_num (target_tracept);
1691 if (target_frameno == -1)
1692 set_traceframe_context (-1);
1694 set_traceframe_context (read_pc ());
1700 /* NOTE: in immitation of the step command, try to determine
1701 whether we have made a transition from one function to another.
1702 If so, we'll print the "stack frame" (ie. the new function and
1703 it's arguments) -- otherwise we'll just show the new source line.
1705 This determination is made by checking (1) whether the current
1706 function has changed, and (2) whether the current FP has changed.
1707 Hack: if the FP wasn't collected, either at the current or the
1708 previous frame, assume that the FP has NOT changed. */
1710 if (old_func == find_pc_function (read_pc ()) &&
1711 (old_frame_addr == 0 ||
1712 FRAME_FP (get_current_frame ()) == 0 ||
1713 old_frame_addr == FRAME_FP (get_current_frame ())))
1718 print_stack_frame (selected_frame, selected_frame_level, source_only);
1723 /* trace_find_command takes a trace frame number n,
1724 sends "QTFrame:<n>" to the target,
1725 and accepts a reply that may contain several optional pieces
1726 of information: a frame number, a tracepoint number, and an
1727 indication of whether this is a trap frame or a stepping frame.
1729 The minimal response is just "OK" (which indicates that the
1730 target does not give us a frame number or a tracepoint number).
1731 Instead of that, the target may send us a string containing
1733 F<hexnum> (gives the selected frame number)
1734 T<hexnum> (gives the selected tracepoint number)
1739 trace_find_command (args, from_tty)
1742 { /* STUB_COMM PART_IMPLEMENTED */
1743 /* this should only be called with a numeric argument */
1745 int target_frameno = -1, target_tracept = -1, target_stepfrm = 0;
1748 if (target_is_remote ())
1750 if (args == 0 || *args == 0)
1751 { /* TFIND with no args means find NEXT trace frame. */
1752 if (traceframe_number == -1)
1753 frameno = 0; /* "next" is first one */
1755 frameno = traceframe_number + 1;
1757 else if (0 == strcmp (args, "-"))
1759 if (traceframe_number == -1)
1760 error ("not debugging trace buffer");
1761 else if (from_tty && traceframe_number == 0)
1762 error ("already at start of trace buffer");
1764 frameno = traceframe_number - 1;
1767 frameno = parse_and_eval_address (args);
1769 sprintf (target_buf, "QTFrame:%x", frameno);
1771 putpkt (target_buf);
1772 tmp = remote_get_noisy_reply (target_buf);
1774 if (frameno == -1) /* end trace debugging */
1775 { /* hopefully the stub has complied! */
1776 if (0 != strcmp (tmp, "OK"))
1777 error ("Bogus response from target: %s", tmp);
1779 finish_tfind_command (NULL, from_tty);
1782 finish_tfind_command (tmp, from_tty);
1784 finish_tfind_command (target_buf, from_tty);
1788 error ("Trace can only be run on remote targets.");
1793 trace_find_end_command (args, from_tty)
1797 trace_find_command ("-1", from_tty);
1802 trace_find_none_command (args, from_tty)
1806 trace_find_command ("-1", from_tty);
1811 trace_find_start_command (args, from_tty)
1815 trace_find_command ("0", from_tty);
1818 /* tfind pc command */
1820 trace_find_pc_command (args, from_tty)
1823 { /* STUB_COMM PART_IMPLEMENTED */
1828 if (target_is_remote ())
1830 if (args == 0 || *args == 0)
1831 pc = read_pc (); /* default is current pc */
1833 pc = parse_and_eval_address (args);
1835 sprintf (target_buf, "QTFrame:pc:%x", pc);
1837 putpkt (target_buf);
1838 tmp = remote_get_noisy_reply (target_buf);
1840 finish_tfind_command (tmp, from_tty);
1842 finish_tfind_command (target_buf, from_tty);
1846 error ("Trace can only be run on remote targets.");
1849 /* tfind tracepoint command */
1851 trace_find_tracepoint_command (args, from_tty)
1854 { /* STUB_COMM PART_IMPLEMENTED */
1855 int target_frameno, tdp;
1858 if (target_is_remote ())
1860 if (args == 0 || *args == 0)
1861 if (tracepoint_number == -1)
1862 error ("No current tracepoint -- please supply an argument.");
1864 tdp = tracepoint_number; /* default is current TDP */
1866 tdp = parse_and_eval_address (args);
1868 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
1870 putpkt (target_buf);
1871 tmp = remote_get_noisy_reply (target_buf);
1873 finish_tfind_command (tmp, from_tty);
1875 finish_tfind_command (target_buf, from_tty);
1879 error ("Trace can only be run on remote targets.");
1882 /* TFIND LINE command:
1884 This command will take a sourceline for argument, just like BREAK
1885 or TRACE (ie. anything that "decode_line_1" can handle).
1887 With no argument, this command will find the next trace frame
1888 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1891 trace_find_line_command (args, from_tty)
1894 { /* STUB_COMM PART_IMPLEMENTED */
1895 static CORE_ADDR start_pc, end_pc;
1896 struct symtabs_and_lines sals;
1897 struct symtab_and_line sal;
1900 struct cleanup *old_chain;
1902 if (target_is_remote ())
1904 if (args == 0 || *args == 0)
1906 sal = find_pc_line ((get_current_frame ())->pc, 0);
1908 sals.sals = (struct symtab_and_line *)
1909 xmalloc (sizeof (struct symtab_and_line));
1914 sals = decode_line_spec (args, 1);
1918 old_chain = make_cleanup (free, sals.sals);
1919 if (sal.symtab == 0)
1921 printf_filtered ("TFIND: No line number information available");
1924 /* This is useful for "info line *0x7f34". If we can't tell the
1925 user about a source line, at least let them have the symbolic
1927 printf_filtered (" for address ");
1929 print_address (sal.pc, gdb_stdout);
1930 printf_filtered (";\n -- will attempt to find by PC. \n");
1934 printf_filtered (".\n");
1935 return; /* no line, no PC; what can we do? */
1938 else if (sal.line > 0
1939 && find_line_pc_range (sal, &start_pc, &end_pc))
1941 if (start_pc == end_pc)
1943 printf_filtered ("Line %d of \"%s\"",
1944 sal.line, sal.symtab->filename);
1946 printf_filtered (" is at address ");
1947 print_address (start_pc, gdb_stdout);
1949 printf_filtered (" but contains no code.\n");
1950 sal = find_pc_line (start_pc, 0);
1952 find_line_pc_range (sal, &start_pc, &end_pc) &&
1954 printf_filtered ("Attempting to find line %d instead.\n",
1957 error ("Cannot find a good line.");
1961 /* Is there any case in which we get here, and have an address
1962 which the user would want to see? If we have debugging symbols
1963 and no line numbers? */
1964 error ("Line number %d is out of range for \"%s\".\n",
1965 sal.line, sal.symtab->filename);
1967 if (args && *args) /* find within range of stated line */
1968 sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
1969 else /* find OUTSIDE OF range of CURRENT line */
1970 sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
1972 putpkt (target_buf);
1973 tmp = remote_get_noisy_reply (target_buf);
1975 finish_tfind_command (tmp, from_tty);
1977 finish_tfind_command (target_buf, from_tty);
1979 do_cleanups (old_chain);
1982 error ("Trace can only be run on remote targets.");
1985 /* tfind range command */
1987 trace_find_range_command (args, from_tty)
1990 { /* STUB_COMM PART_IMPLEMENTED */
1991 static CORE_ADDR start, stop;
1995 if (target_is_remote ())
1997 if (args == 0 || *args == 0)
1998 { /* XXX FIXME: what should default behavior be? */
1999 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2003 if (0 != (tmp = strchr (args, ',' )))
2005 *tmp++ = '\0'; /* terminate start address */
2006 while (isspace (*tmp))
2008 start = parse_and_eval_address (args);
2009 stop = parse_and_eval_address (tmp);
2012 { /* no explicit end address? */
2013 start = parse_and_eval_address (args);
2014 stop = start + 1; /* ??? */
2017 sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
2019 putpkt (target_buf);
2020 tmp = remote_get_noisy_reply (target_buf);
2022 finish_tfind_command (tmp, from_tty);
2024 finish_tfind_command (target_buf, from_tty);
2028 error ("Trace can only be run on remote targets.");
2031 /* tfind outside command */
2033 trace_find_outside_command (args, from_tty)
2036 { /* STUB_COMM PART_IMPLEMENTED */
2037 CORE_ADDR start, stop;
2041 if (target_is_remote ())
2043 if (args == 0 || *args == 0)
2044 { /* XXX FIXME: what should default behavior be? */
2045 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2049 if (0 != (tmp = strchr (args, ',' )))
2051 *tmp++ = '\0'; /* terminate start address */
2052 while (isspace (*tmp))
2054 start = parse_and_eval_address (args);
2055 stop = parse_and_eval_address (tmp);
2058 { /* no explicit end address? */
2059 start = parse_and_eval_address (args);
2060 stop = start + 1; /* ??? */
2063 sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
2065 putpkt (target_buf);
2066 tmp = remote_get_noisy_reply (target_buf);
2068 finish_tfind_command (tmp, from_tty);
2070 finish_tfind_command (target_buf, from_tty);
2074 error ("Trace can only be run on remote targets.");
2077 /* save-tracepoints command */
2079 tracepoint_save_command (args, from_tty)
2083 struct tracepoint *tp;
2084 struct action_line *line;
2086 char *i1 = " ", *i2 = " ";
2087 char *indent, *actionline;
2089 if (args == 0 || *args == 0)
2090 error ("Argument required (file name in which to save tracepoints");
2092 if (tracepoint_chain == 0)
2094 warning ("save-tracepoints: no tracepoints to save.\n");
2098 if (!(fp = fopen (args, "w")))
2099 error ("Unable to open file '%s' for saving tracepoints");
2101 ALL_TRACEPOINTS (tp)
2103 if (tp->addr_string)
2104 fprintf (fp, "trace %s\n", tp->addr_string);
2106 fprintf (fp, "trace *0x%x\n", tp->address);
2109 fprintf (fp, " passcount %d\n", tp->pass_count);
2113 fprintf (fp, " actions\n");
2115 for (line = tp->actions; line; line = line->next)
2117 struct cmd_list_element *cmd;
2119 actionline = line->action;
2120 while (isspace(*actionline))
2123 fprintf (fp, "%s%s\n", indent, actionline);
2124 if (*actionline != '#') /* skip for comment lines */
2126 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2128 error ("Bad action list item: %s", actionline);
2129 if (cmd->function.cfunc == while_stepping_pseudocommand)
2131 else if (cmd->function.cfunc == end_actions_pseudocommand)
2139 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2143 /* info scope command: list the locals for a scope. */
2145 scope_info (args, from_tty)
2149 struct symtab_and_line sal;
2150 struct symtabs_and_lines sals;
2152 struct minimal_symbol *msym;
2153 struct block *block;
2154 char **canonical, *symname, *save_args = args;
2155 int i, nsyms, count = 0;
2157 if (args == 0 || *args == 0)
2158 error ("requires an argument (function, line or *addr) to define a scope");
2160 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2161 if (sals.nelts == 0)
2162 return; /* presumably decode_line_1 has already warned */
2164 /* Resolve line numbers to PC */
2165 resolve_sal_pc (&sals.sals[0]);
2166 block = block_for_pc (sals.sals[0].pc);
2170 nsyms = BLOCK_NSYMS (block);
2171 for (i = 0; i < nsyms; i++)
2174 printf_filtered ("Scope for %s:\n", save_args);
2176 sym = BLOCK_SYM (block, i);
2177 symname = SYMBOL_NAME (sym);
2178 if (symname == NULL || *symname == '\0')
2179 continue; /* probably botched, certainly useless */
2181 printf_filtered ("Symbol %s is ", symname);
2182 switch (SYMBOL_CLASS (sym)) {
2184 case LOC_UNDEF: /* messed up symbol? */
2185 printf_filtered ("a bogus symbol, class %d.\n",
2186 SYMBOL_CLASS (sym));
2187 count--; /* don't count this one */
2190 printf_filtered ("a constant with value %d (0x%x)",
2191 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2193 case LOC_CONST_BYTES:
2194 printf_filtered ("constant bytes: ");
2195 if (SYMBOL_TYPE (sym))
2196 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (sym)); i++)
2197 fprintf_filtered (gdb_stdout, " %02x",
2198 (unsigned) SYMBOL_VALUE_BYTES (sym) [i]);
2201 printf_filtered ("in static storage at address ");
2202 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2205 printf_filtered ("a local variable in register $%s",
2206 reg_names [SYMBOL_VALUE (sym)]);
2210 printf_filtered ("an argument at stack/frame offset %ld",
2211 SYMBOL_VALUE (sym));
2214 printf_filtered ("a local variable at frame offset %ld",
2215 SYMBOL_VALUE (sym));
2218 printf_filtered ("a reference argument at offset %ld",
2219 SYMBOL_VALUE (sym));
2222 printf_filtered ("an argument in register $%s",
2223 reg_names[SYMBOL_VALUE (sym)]);
2225 case LOC_REGPARM_ADDR:
2226 printf_filtered ("the address of an argument, in register $%s",
2227 reg_names[SYMBOL_VALUE (sym)]);
2230 printf_filtered ("a typedef.\n");
2233 printf_filtered ("a label at address ");
2234 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2237 printf_filtered ("a function at address ");
2238 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2242 printf_filtered ("a variable at offset %d from register $%s",
2244 reg_names [SYMBOL_BASEREG (sym)]);
2246 case LOC_BASEREG_ARG:
2247 printf_filtered ("an argument at offset %d from register $%s",
2249 reg_names [SYMBOL_BASEREG (sym)]);
2251 case LOC_UNRESOLVED:
2252 msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2254 printf_filtered ("Unresolved Static");
2257 printf_filtered ("static storage at address ");
2258 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2262 case LOC_OPTIMIZED_OUT:
2263 printf_filtered ("optimized out.\n");
2266 if (SYMBOL_TYPE (sym))
2267 printf_filtered (", length %d.\n",
2268 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2270 if (BLOCK_FUNCTION (block))
2273 block = BLOCK_SUPERBLOCK (block);
2276 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2280 /* worker function (cleanup) */
2282 replace_comma (comma)
2290 trace_dump_command (args, from_tty)
2294 struct tracepoint *t;
2295 struct action_line *action;
2296 char *action_exp, *next_comma;
2297 struct cleanup *old_cleanups;
2298 int stepping_actions = 0;
2299 int stepping_frame = 0;
2301 if (tracepoint_number == -1)
2303 warning ("No current trace frame.");
2308 if (t->number == tracepoint_number)
2312 error ("No known tracepoint matches 'current' tracepoint #%d.",
2315 old_cleanups = make_cleanup (null_cleanup, NULL);
2317 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2318 tracepoint_number, traceframe_number);
2320 /* The current frame is a trap frame if the frame PC is equal
2321 to the tracepoint PC. If not, then the current frame was
2322 collected during single-stepping. */
2324 stepping_frame = (t->address != read_pc());
2326 for (action = t->actions; action; action = action->next)
2328 struct cmd_list_element *cmd;
2330 action_exp = action->action;
2331 while (isspace (*action_exp))
2334 /* The collection actions to be done while stepping are
2335 bracketed by the commands "while-stepping" and "end". */
2337 if (*action_exp == '#') /* comment line */
2340 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2342 error ("Bad action list item: %s", action_exp);
2344 if (cmd->function.cfunc == while_stepping_pseudocommand)
2345 stepping_actions = 1;
2346 else if (cmd->function.cfunc == end_actions_pseudocommand)
2347 stepping_actions = 0;
2348 else if (cmd->function.cfunc == collect_pseudocommand)
2350 /* Display the collected data.
2351 For the trap frame, display only what was collected at the trap.
2352 Likewise for stepping frames, display only what was collected
2353 while stepping. This means that the two boolean variables,
2354 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2355 if (stepping_frame == stepping_actions)
2357 do { /* repeat over a comma-separated list */
2359 if (*action_exp == ',')
2361 while (isspace (*action_exp))
2364 next_comma = strchr (action_exp, ',');
2366 if (0 == strncasecmp (action_exp, "$reg", 4))
2367 registers_info (NULL, from_tty);
2368 else if (0 == strncasecmp (action_exp, "$loc", 4))
2369 locals_info (NULL, from_tty);
2370 else if (0 == strncasecmp (action_exp, "$arg", 4))
2371 args_info (NULL, from_tty);
2372 else if (action_exp[0] == '$' && action_exp[1] == '(')
2374 long typecode, size;
2375 bfd_signed_vma offset;
2378 action_exp = parse_and_eval_memrange (action_exp,
2383 if (typecode != 0 && typecode != -1)
2384 offset += read_register (typecode);
2385 sprintf (fmt, "/%dxb 0x%x", size, offset);
2386 x_command (fmt, from_tty);
2387 next_comma = strchr (action_exp, ',');
2393 make_cleanup (replace_comma, next_comma);
2396 printf_filtered ("%s = ", action_exp);
2397 output_command (action_exp, from_tty);
2398 printf_filtered ("\n");
2402 action_exp = next_comma;
2403 } while (action_exp && *action_exp == ',');
2407 discard_cleanups (old_cleanups);
2410 /* module initialization */
2412 _initialize_tracepoint ()
2414 tracepoint_chain = 0;
2415 tracepoint_count = 0;
2416 traceframe_number = -1;
2417 tracepoint_number = -1;
2419 set_internalvar (lookup_internalvar ("tpnum"),
2420 value_from_longest (builtin_type_int, (LONGEST) 0));
2421 set_internalvar (lookup_internalvar ("trace_frame"),
2422 value_from_longest (builtin_type_int, (LONGEST) 0));
2424 if (tracepoint_list.list == NULL)
2426 tracepoint_list.listsize = 128;
2427 tracepoint_list.list = xmalloc
2428 (tracepoint_list.listsize * sizeof (struct memrange));
2430 if (stepping_list.list == NULL)
2432 stepping_list.listsize = 128;
2433 stepping_list.list = xmalloc
2434 (stepping_list.listsize * sizeof (struct memrange));
2437 add_info ("scope", scope_info,
2438 "List the variables local to a scope");
2440 add_cmd ("tracepoints", class_trace, NO_FUNCTION,
2441 "Tracing of program execution without stopping the program.",
2444 add_info ("tracepoints", tracepoints_info,
2445 "Status of tracepoints, or tracepoint number NUMBER.\n\
2446 Convenience variable \"$tpnum\" contains the number of the\n\
2447 last tracepoint set.");
2449 add_info_alias ("tp", "tracepoints", 1);
2451 add_com ("save-tracepoints", class_trace, tracepoint_save_command,
2452 "Save current tracepoint definitions as a script.\n\
2453 Use the 'source' command in another debug session to restore them.");
2455 add_com ("tdump", class_trace, trace_dump_command,
2456 "Print everything collected at the current tracepoint.");
2458 add_prefix_cmd ("tfind", class_trace, trace_find_command,
2459 "Select a trace frame;\n\
2460 No argument means forward by one frame; '-' meand backward by one frame.",
2461 &tfindlist, "tfind ", 1, &cmdlist);
2463 add_cmd ("outside", class_trace, trace_find_outside_command,
2464 "Select a trace frame whose PC is outside the given \
2465 range.\nUsage: tfind outside addr1, addr2",
2468 add_cmd ("range", class_trace, trace_find_range_command,
2469 "Select a trace frame whose PC is in the given range.\n\
2470 Usage: tfind range addr1,addr2",
2473 add_cmd ("line", class_trace, trace_find_line_command,
2474 "Select a trace frame by source line.\n\
2475 Argument can be a line number (with optional source file), \n\
2476 a function name, or '*' followed by an address.\n\
2477 Default argument is 'the next source line that was traced'.",
2480 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2481 "Select a trace frame by tracepoint number.\n\
2482 Default is the tracepoint for the current trace frame.",
2485 add_cmd ("pc", class_trace, trace_find_pc_command,
2486 "Select a trace frame by PC.\n\
2487 Default is the current PC, or the PC of the current trace frame.",
2490 add_cmd ("end", class_trace, trace_find_end_command,
2491 "Synonym for 'none'.\n\
2492 De-select any trace frame and resume 'live' debugging.",
2495 add_cmd ("none", class_trace, trace_find_none_command,
2496 "De-select any trace frame and resume 'live' debugging.",
2499 add_cmd ("start", class_trace, trace_find_start_command,
2500 "Select the first trace frame in the trace buffer.",
2503 add_com ("tstatus", class_trace, trace_status_command,
2504 "Display the status of the current trace data collection.");
2506 add_com ("tstop", class_trace, trace_stop_command,
2507 "Stop trace data collection.");
2509 add_com ("tstart", class_trace, trace_start_command,
2510 "Start trace data collection.");
2512 add_com ("passcount", class_trace, trace_pass_command,
2513 "Set the passcount for a tracepoint.\n\
2514 The trace will end when the tracepoint has been passed 'count' times.\n\
2515 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2516 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2518 add_com ("end", class_trace, end_actions_pseudocommand,
2519 "Ends a list of commands or actions.\n\
2520 Several GDB commands allow you to enter a list of commands or actions.\n\
2521 Entering \"end\" on a line by itself is the normal way to terminate\n\
2523 Note: the \"end\" command cannot be used at the gdb prompt.");
2525 add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
2526 "Specify single-stepping behavior at a tracepoint.\n\
2527 Argument is number of instructions to trace in single-step mode\n\
2528 following the tracepoint. This command is normally followed by\n\
2529 one or more \"collect\" commands, to specify what to collect\n\
2530 while single-stepping.\n\n\
2531 Note: this command can only be used in a tracepoint \"actions\" list.");
2533 add_com_alias ("ws", "while-stepping", class_alias, 0);
2534 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2536 add_com ("collect", class_trace, collect_pseudocommand,
2537 "Specify one or more data items to be collected at a tracepoint.\n\
2538 Accepts a comma-separated list of (one or more) arguments.\n\
2539 Things that may be collected include registers, variables, plus\n\
2540 the following special arguments:\n\
2541 $regs -- all registers.\n\
2542 $args -- all function arguments.\n\
2543 $locals -- all variables local to the block/function scope.\n\
2544 $(addr,len) -- a literal memory range.\n\
2545 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2546 Note: this command can only be used in a tracepoint \"actions\" list.");
2548 add_com ("actions", class_trace, trace_actions_command,
2549 "Specify the actions to be taken at a tracepoint.\n\
2550 Tracepoint actions may include collecting of specified data, \n\
2551 single-stepping, or enabling/disabling other tracepoints, \n\
2552 depending on target's capabilities.");
2554 add_cmd ("tracepoints", class_trace, delete_trace_command,
2555 "Delete specified tracepoints.\n\
2556 Arguments are tracepoint numbers, separated by spaces.\n\
2557 No argument means delete all tracepoints.",
2560 add_cmd ("tracepoints", class_trace, disable_trace_command,
2561 "Disable specified tracepoints.\n\
2562 Arguments are tracepoint numbers, separated by spaces.\n\
2563 No argument means disable all tracepoints.",
2566 add_cmd ("tracepoints", class_trace, enable_trace_command,
2567 "Enable specified tracepoints.\n\
2568 Arguments are tracepoint numbers, separated by spaces.\n\
2569 No argument means enable all tracepoints.",
2572 add_com ("trace", class_trace, trace_command,
2573 "Set a tracepoint at a specified line or function or address.\n\
2574 Argument may be a line number, function name, or '*' plus an address.\n\
2575 For a line number or function, trace at the start of its code.\n\
2576 If an address is specified, trace at that exact address.\n\n\
2577 Do \"help tracepoints\" for info on other tracepoint commands.");
2579 add_com_alias ("tp", "trace", class_alias, 0);
2580 add_com_alias ("tr", "trace", class_alias, 1);
2581 add_com_alias ("tra", "trace", class_alias, 1);
2582 add_com_alias ("trac", "trace", class_alias, 1);