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 static void free_actions PARAMS((struct tracepoint *));
522 /* This function implements enable, disable and delete. */
524 tracepoint_operation (t, from_tty, opcode)
525 struct tracepoint *t;
527 enum tracepoint_opcode opcode;
529 struct tracepoint *t2;
533 t->enabled = enabled;
536 t->enabled = disabled;
539 if (tracepoint_chain == t)
540 tracepoint_chain = t->next;
549 /* Let the UI know of any deletions */
550 if (delete_tracepoint_hook)
551 delete_tracepoint_hook (t);
554 free (t->addr_string);
556 free (t->source_file);
565 /* Utility: parse a tracepoint number and look it up in the list. */
567 get_tracepoint_by_number (arg)
570 struct tracepoint *t;
576 error ("Bad tracepoint argument");
578 if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
579 tpnum = tracepoint_count;
580 else if (**arg == '$') /* handle convenience variable */
582 /* Make a copy of the name, so we can null-terminate it
583 to pass to lookup_internalvar(). */
585 while (isalnum(*end) || *end == '_')
587 copy = (char *) alloca (end - *arg);
588 strncpy (copy, *arg + 1, (end - *arg - 1));
589 copy[end - *arg - 1] = '\0';
592 val = value_of_internalvar (lookup_internalvar (copy));
593 if (TYPE_CODE( VALUE_TYPE (val)) != TYPE_CODE_INT)
594 error ("Convenience variable must have integral type.");
595 tpnum = (int) value_as_long (val);
597 else /* handle tracepoint number */
599 tpnum = strtol (*arg, arg, 10);
602 if (t->number == tpnum)
606 warning ("No tracepoint number %d.\n", tpnum);
610 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
612 map_args_over_tracepoints (args, from_tty, opcode)
615 enum tracepoint_opcode opcode;
617 struct tracepoint *t, *tmp;
621 if (args == 0 || *args == 0) /* do them all */
622 ALL_TRACEPOINTS_SAFE (t, tmp)
623 tracepoint_operation (t, from_tty, opcode);
627 if (t = get_tracepoint_by_number (&args))
628 tracepoint_operation (t, from_tty, opcode);
629 while (*args == ' ' || *args == '\t')
634 /* The 'enable trace' command enables tracepoints. Not supported by all targets. */
636 enable_trace_command (args, from_tty)
641 map_args_over_tracepoints (args, from_tty, enable);
644 /* The 'disable trace' command enables tracepoints. Not supported by all targets. */
646 disable_trace_command (args, from_tty)
651 map_args_over_tracepoints (args, from_tty, disable);
654 /* Remove a tracepoint (or all if no argument) */
656 delete_trace_command (args, from_tty)
662 if (!query ("Delete all tracepoints? "))
665 map_args_over_tracepoints (args, from_tty, delete);
668 /* Set passcount for tracepoint.
670 First command argument is passcount, second is tracepoint number.
671 If tracepoint number omitted, apply to most recently defined.
672 Also accepts special argument "all". */
675 trace_pass_command (args, from_tty)
679 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
682 if (args == 0 || *args == 0)
683 error ("PASS command requires an argument (count + optional TP num)");
685 count = strtoul (args, &args, 10); /* count comes first, then TP num */
687 while (*args && isspace (*args))
690 if (*args && strncasecmp (args, "all", 3) == 0)
691 args += 3; /* skip special argument "all" */
693 t1 = get_tracepoint_by_number (&args);
696 return; /* error, bad tracepoint number */
699 if (t1 == (struct tracepoint *) -1 || t1 == t2)
701 t2->pass_count = count;
703 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
708 /* ACTIONS functions: */
710 /* Prototypes for action-parsing utility commands */
711 static void read_actions PARAMS((struct tracepoint *));
712 static char *parse_and_eval_memrange PARAMS ((char *,
718 /* The three functions:
719 collect_pseudocommand,
720 while_stepping_pseudocommand, and
721 end_actions_pseudocommand
722 are placeholders for "commands" that are actually ONLY to be used
723 within a tracepoint action list. If the actual function is ever called,
724 it means that somebody issued the "command" at the top level,
725 which is always an error. */
728 end_actions_pseudocommand (args, from_tty)
732 error ("This command cannot be used at the top level.");
736 while_stepping_pseudocommand (args, from_tty)
740 error ("This command can only be used in a tracepoint actions list.");
744 collect_pseudocommand (args, from_tty)
748 error ("This command can only be used in a tracepoint actions list.");
751 /* Enter a list of actions for a tracepoint. */
753 trace_actions_command (args, from_tty)
757 struct tracepoint *t;
760 char *end_msg = "End with a line saying just \"end\".";
762 if (t = get_tracepoint_by_number (&args))
764 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
769 if (readline_begin_hook)
770 (*readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
771 else if (input_from_terminal_p ())
772 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
778 if (readline_end_hook)
779 (*readline_end_hook) ();
781 /* tracepoints_changed () */
783 /* else error, just return; */
794 static enum actionline_type validate_actionline PARAMS((char **,
795 struct tracepoint *));
797 /* worker function */
800 struct tracepoint *t;
803 char *prompt1 = "> ", *prompt2 = " > ";
804 char *prompt = prompt1;
805 enum actionline_type linetype;
806 extern FILE *instream;
807 struct action_line *next = NULL, *temp;
808 struct cleanup *old_chain;
810 /* Control-C quits instantly if typed while in this loop
811 since it should not wait until the user types a newline. */
815 signal (STOP_SIGNAL, stop_sig);
817 old_chain = make_cleanup (free_actions, (void *) t);
820 /* Make sure that all output has been output. Some machines may let
821 you get away with leaving out some of the gdb_flush, but not all. */
823 gdb_flush (gdb_stdout);
824 gdb_flush (gdb_stderr);
826 if (readline_hook && instream == NULL)
827 line = (*readline_hook) (prompt);
828 else if (instream == stdin && ISATTY (instream))
830 line = readline (prompt);
831 if (line && *line) /* add it to command history */
835 line = gdb_readline (0);
837 linetype = validate_actionline (&line, t);
838 if (linetype == BADLINE)
839 continue; /* already warned -- collect another line */
841 temp = xmalloc (sizeof (struct action_line));
845 if (next == NULL) /* first action for this tracepoint? */
846 t->actions = next = temp;
853 if (linetype == STEPPING) /* begin "while-stepping" */
854 if (prompt == prompt2)
856 warning ("Already processing 'while-stepping'");
860 prompt = prompt2; /* change prompt for stepping actions */
861 else if (linetype == END)
862 if (prompt == prompt2)
863 prompt = prompt1; /* end of single-stepping actions */
865 break; /* end of actions */
869 signal (STOP_SIGNAL, SIG_DFL);
872 discard_cleanups (old_chain);
875 /* worker function */
876 static enum actionline_type
877 validate_actionline (line, t)
879 struct tracepoint *t;
881 struct cmd_list_element *c;
882 struct expression *exp;
883 value_ptr temp, temp2;
886 for (p = *line; isspace (*p); )
889 /* symbol lookup etc. */
890 if (*p == '\0') /* empty line: just prompt for another line. */
893 if (*p == '#') /* comment line */
896 c = lookup_cmd (&p, cmdlist, "", -1, 1);
899 warning ("'%s' is not an action that I know, or is ambiguous.", p);
903 if (c->function.cfunc == collect_pseudocommand)
905 do { /* repeat over a comma-separated list */
909 if (*p == '$') /* look for special pseudo-symbols */
912 bfd_signed_vma offset;
914 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
915 (0 == strncasecmp ("arg", p + 1, 3)) ||
916 (0 == strncasecmp ("loc", p + 1, 3)))
919 else if (p[1] == '(') /* literal memrange */
921 char *temp, *newline;
923 newline = malloc (strlen (*line) + 32);
924 strcpy (newline, *line);
925 newline[p - *line] = '\0';
926 /* newline is now a copy of line, up to "p" (the memrange) */
927 temp = parse_and_eval_memrange (p, t->address,
928 &typecode, &offset, &size) + 1;
929 /* now compose the memrange as a literal value */
931 sprintf (newline + strlen (newline),
935 sprintf (newline + strlen (newline),
937 reg_names[typecode], offset, size);
938 /* now add the remainder of the old line to the new one */
939 p = newline + strlen (newline);
941 strcat (newline, temp);
948 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
950 if (exp->elts[0].opcode != OP_VAR_VALUE &&
951 exp->elts[0].opcode != UNOP_MEMVAL &&
952 /*exp->elts[0].opcode != OP_LONG && */
953 /*exp->elts[0].opcode != UNOP_CAST && */
954 exp->elts[0].opcode != OP_REGISTER)
956 warning ("collect requires a variable or register name.\n");
959 if (exp->elts[0].opcode == OP_VAR_VALUE)
960 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
962 warning ("%s is constant (value %d): will not be collected.",
963 SYMBOL_NAME (exp->elts[2].symbol),
964 SYMBOL_VALUE (exp->elts[2].symbol));
967 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
969 warning ("%s is optimized away and cannot be collected.",
970 SYMBOL_NAME (exp->elts[2].symbol));
974 } while (p && *p++ == ',');
977 else if (c->function.cfunc == while_stepping_pseudocommand)
979 char *steparg; /* in case warning is necessary */
987 t->step_count = strtol (p, &p, 0);
988 if (t->step_count == 0)
990 warning ("'%s' evaluates to zero -- command ignored.");
998 else if (c->function.cfunc == end_actions_pseudocommand)
1002 warning ("'%s' is not a supported tracepoint action.", *line);
1007 /* worker function */
1010 struct tracepoint *t;
1012 struct action_line *line, *next;
1014 for (line = t->actions; line; line = next)
1018 free (line->action);
1025 int type; /* 0 for absolute memory range, else basereg number */
1026 bfd_signed_vma start;
1030 struct collection_list {
1031 unsigned char regs_mask[8]; /* room for up to 256 regs */
1034 struct memrange *list;
1035 } tracepoint_list, stepping_list;
1037 /* MEMRANGE functions: */
1039 /* parse a memrange spec from command input */
1041 parse_and_eval_memrange (arg, addr, typecode, offset, size)
1044 long *typecode, *size;
1045 bfd_signed_vma *offset;
1048 struct expression *exp;
1051 if (*arg++ != '$' || *arg++ != '(')
1052 error ("Internal: bad argument to parse_and_eval_memrange: %s", start);
1054 if (*arg == '$') /* register for relative memrange? */
1056 exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
1057 if (exp->elts[0].opcode != OP_REGISTER)
1058 error ("Bad register operand for memrange: %s", start);
1060 error ("missing comma for memrange: %s", start);
1061 *typecode = exp->elts[1].longconst;
1064 *typecode = -1; /* absolute memrange; */
1066 exp = parse_exp_1 (&arg, 0, 1);
1067 *offset = value_as_pointer (evaluate_expression (exp));
1069 /* now parse the size */
1071 error ("missing comma for memrange: %s", start);
1073 exp = parse_exp_1 (&arg, 0, 0);
1074 *size = value_as_long (evaluate_expression (exp));
1077 printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n",
1078 *typecode, *offset, *size);
1083 /* compare memranges for qsort */
1086 struct memrange *a, *b;
1088 if (a->type < b->type) return -1;
1089 if (a->type > b->type) return 1;
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) return -1;
1098 if (a->start > b->start) return 1;
1103 /* Sort the memrange list using qsort, and merge adjacent memranges */
1105 memrange_sortmerge (memranges)
1106 struct collection_list *memranges;
1110 qsort (memranges->list, memranges->next_memrange,
1111 sizeof (struct memrange), memrange_cmp);
1112 if (memranges->next_memrange > 0)
1114 for (a = 0, b = 1; b < memranges->next_memrange; b++)
1116 if (memranges->list[a].type == memranges->list[b].type &&
1117 memranges->list[b].start - memranges->list[a].end <=
1118 MAX_REGISTER_VIRTUAL_SIZE)
1120 /* memrange b starts before memrange a ends; merge them. */
1121 if (memranges->list[b].end > memranges->list[a].end)
1122 memranges->list[a].end = memranges->list[b].end;
1123 continue; /* next b, same a */
1127 memcpy (&memranges->list[a], &memranges->list[b],
1128 sizeof (struct memrange));
1130 memranges->next_memrange = a + 1;
1134 /* Add a register to a collection list */
1136 add_register (collection, regno)
1137 struct collection_list *collection;
1138 unsigned long regno;
1141 printf_filtered ("collect register %d\n", regno);
1142 if (regno > (8 * sizeof (collection->regs_mask)))
1143 error ("Internal: register number %d too large for tracepoint",
1145 collection->regs_mask [regno / 8] |= 1 << (regno % 8);
1148 /* Add a memrange to a collection list */
1150 add_memrange (memranges, type, base, len)
1151 struct collection_list *memranges;
1153 bfd_signed_vma base;
1157 printf_filtered ("(%d,0x%x,%d)\n", type, base, len);
1158 /* type: 0 == memory, n == basereg */
1159 memranges->list[memranges->next_memrange].type = type;
1160 /* base: addr if memory, offset if reg relative. */
1161 memranges->list[memranges->next_memrange].start = base;
1162 /* len: we actually save end (base + len) for convenience */
1163 memranges->list[memranges->next_memrange].end = base + len;
1164 memranges->next_memrange++;
1165 if (memranges->next_memrange >= memranges->listsize)
1167 memranges->listsize *= 2;
1168 memranges->list = xrealloc (memranges->list,
1169 memranges->listsize);
1172 if (type != -1) /* better collect the base register! */
1173 add_register (memranges, type);
1176 /* Add a symbol to a collection list */
1178 collect_symbol (collect, sym)
1179 struct collection_list *collect;
1184 bfd_signed_vma offset;
1186 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1187 switch (SYMBOL_CLASS (sym)) {
1189 printf_filtered ("%s: don't know symbol class %d\n",
1190 SYMBOL_NAME (sym), SYMBOL_CLASS (sym));
1193 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
1194 SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1197 offset = SYMBOL_VALUE_ADDRESS (sym);
1199 printf_filtered ("LOC_STATIC %s: collect %d bytes "
1201 SYMBOL_NAME (sym), len, offset);
1202 add_memrange (collect, -1, offset, len); /* 0 == memory */
1206 reg = SYMBOL_VALUE (sym);
1208 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym));
1209 add_register (collect, reg);
1213 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
1214 printf_filtered (" (will not collect %s)\n",
1217 case LOC_REGPARM_ADDR:
1218 reg = SYMBOL_VALUE (sym);
1222 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
1223 SYMBOL_NAME (sym), len, offset, reg);
1225 add_memrange (collect, reg, offset, len);
1229 offset = SYMBOL_VALUE (sym);
1233 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
1234 SYMBOL_NAME (sym), len, offset, reg);
1236 add_memrange (collect, reg, offset, len);
1239 case LOC_BASEREG_ARG:
1240 reg = SYMBOL_BASEREG (sym);
1241 offset = SYMBOL_VALUE (sym);
1244 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
1245 SYMBOL_NAME (sym), len, offset, reg);
1247 add_memrange (collect, reg, offset, len);
1249 case LOC_UNRESOLVED:
1250 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym));
1252 case LOC_OPTIMIZED_OUT:
1253 printf_filtered ("%s has been optimized out of existance.\n",
1259 /* Add all locals (or args) symbols to collection list */
1261 add_local_symbols (collect, pc, type)
1262 struct collection_list *collect;
1267 struct block *block;
1268 int i, nsyms, count = 0;
1270 block = block_for_pc (pc);
1273 nsyms = BLOCK_NSYMS (block);
1274 for (i = 0; i < nsyms; i++)
1276 sym = BLOCK_SYM (block, i);
1277 switch (SYMBOL_CLASS (sym)) {
1282 if (type == 'L') /* collecting Locals */
1285 collect_symbol (collect, sym);
1292 case LOC_REGPARM_ADDR:
1293 case LOC_BASEREG_ARG:
1294 if (type == 'A') /* collecting Arguments */
1297 collect_symbol (collect, sym);
1301 if (BLOCK_FUNCTION (block))
1304 block = BLOCK_SUPERBLOCK (block);
1307 warning ("No %s found in scope.", type == 'L' ? "locals" : "args");
1310 /* worker function */
1312 clear_collection_list (list)
1313 struct collection_list *list;
1315 list->next_memrange = 0;
1316 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1319 /* reduce a collection list to string form (for gdb protocol) */
1321 stringify_collection_list (list, string)
1322 struct collection_list *list;
1328 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1329 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1331 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1334 printf_filtered ("\nCollecting registers (mask): 0x");
1339 printf_filtered ("%02X", list->regs_mask[i]);
1340 sprintf (end, "%02X", list->regs_mask[i]);
1345 printf_filtered ("\n");
1346 if (list->next_memrange > 0 && info_verbose)
1347 printf_filtered ("Collecting memranges: \n");
1348 for (i = 0; i < list->next_memrange; i++)
1351 printf_filtered ("(%d, 0x%x, %d)\n",
1353 list->list[i].start,
1354 list->list[i].end - list->list[i].start);
1355 sprintf (end, "M%X,%X,%X",
1357 list->list[i].start,
1358 list->list[i].end - list->list[i].start);
1359 end += strlen (end);
1367 /* render all actions into gdb protocol */
1369 encode_actions (t, tdp_actions, step_count, stepping_actions)
1370 struct tracepoint *t;
1372 unsigned long *step_count;
1373 char **stepping_actions;
1375 static char tdp_buff[2048], step_buff[2048];
1377 struct expression *exp;
1378 struct action_line *action;
1379 bfd_signed_vma offset;
1382 struct collection_list *collect;
1383 struct cmd_list_element *cmd;
1385 clear_collection_list (&tracepoint_list);
1386 clear_collection_list (&stepping_list);
1387 collect = &tracepoint_list;
1389 *tdp_actions = NULL;
1390 *stepping_actions = NULL;
1392 for (action = t->actions; action; action = action->next)
1394 action_exp = action->action;
1395 while (isspace (*action_exp))
1398 if (*action_exp == '#') /* comment line */
1401 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1403 error ("Bad action list item: %s", action_exp);
1405 if (cmd->function.cfunc == collect_pseudocommand)
1407 do { /* repeat over a comma-separated list */
1408 while (isspace (*action_exp))
1411 if (0 == strncasecmp ("$reg", action_exp, 4))
1413 for (i = 0; i < NUM_REGS; i++)
1414 add_register (collect, i);
1415 action_exp = strchr (action_exp, ','); /* more? */
1417 else if (0 == strncasecmp ("$arg", action_exp, 4))
1419 add_local_symbols (collect, t->address, 'A');
1420 action_exp = strchr (action_exp, ','); /* more? */
1422 else if (0 == strncasecmp ("$loc", action_exp, 4))
1424 add_local_symbols (collect, t->address, 'L');
1425 action_exp = strchr (action_exp, ','); /* more? */
1427 else if (action_exp[0] == '$' &&
1428 action_exp[1] == '(') /* literal memrange */
1430 long typecode, size;
1431 bfd_signed_vma offset;
1433 action_exp = parse_and_eval_memrange (action_exp,
1438 add_memrange (collect, typecode, offset, size);
1442 unsigned long addr, len;
1444 exp = parse_exp_1 (&action_exp, block_for_pc (t->address), 1);
1445 switch (exp->elts[0].opcode) {
1447 i = exp->elts[1].longconst;
1449 printf_filtered ("OP_REGISTER: ");
1450 add_register (collect, i);
1454 /* safe because we know it's a simple expression */
1455 tempval = evaluate_expression (exp);
1456 addr = VALUE_ADDRESS (tempval) + VALUE_OFFSET (tempval);
1457 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1458 add_memrange (collect, -1, addr, len);
1462 collect_symbol (collect, exp->elts[2].symbol);
1466 addr = exp->elts[2].longconst;
1467 if (*action_exp == ':')
1469 exp = parse_exp_1 (&action_exp,
1470 block_for_pc (t->address),
1472 if (exp->elts[0].opcode == OP_LONG)
1473 len = exp->elts[2].longconst;
1475 error ("length field requires a literal long const");
1480 add_memrange (collect, -1, addr, len);
1485 } while (action_exp && *action_exp++ == ',');
1487 else if (cmd->function.cfunc == while_stepping_pseudocommand)
1489 collect = &stepping_list;
1491 else if (cmd->function.cfunc == end_actions_pseudocommand)
1493 if (collect == &stepping_list) /* end stepping actions */
1494 collect = &tracepoint_list;
1496 break; /* end tracepoint actions */
1499 memrange_sortmerge (&tracepoint_list);
1500 memrange_sortmerge (&stepping_list);
1502 *tdp_actions = stringify_collection_list (&tracepoint_list, &tdp_buff);
1503 *stepping_actions = stringify_collection_list (&stepping_list, &step_buff);
1506 static char target_buf[2048];
1510 Tell target to lear any previous trace experiment.
1511 Walk the list of tracepoints, and send them (and their actions)
1512 to the target. If no errors,
1513 Tell target to start a new trace experiment. */
1516 trace_start_command (args, from_tty)
1519 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1520 struct tracepoint *t;
1523 char *stepping_actions;
1524 unsigned long step_count;
1526 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1528 if (target_is_remote ())
1531 remote_get_noisy_reply (target_buf);
1532 if (strcmp (target_buf, "OK"))
1533 error ("Target does not support this command.");
1537 int ss_count; /* if actions include singlestepping */
1538 int disable_mask; /* ??? */
1539 int enable_mask; /* ??? */
1541 sprintf (buf, "QTDP:%x:%x:%c:%x:%x", t->number, t->address,
1542 t->enabled == enabled ? 'E' : 'D',
1543 t->step_count, t->pass_count);
1546 encode_actions (t, &tdp_actions, &step_count, &stepping_actions);
1547 /* do_single_steps (t); */
1550 if (strlen (buf) + strlen (tdp_actions) >= sizeof (buf))
1551 error ("Actions for tracepoint %d too complex; "
1552 "please simplify.", t->number);
1553 strcat (buf, tdp_actions);
1555 if (stepping_actions)
1558 if (strlen (buf) + strlen (stepping_actions) >= sizeof (buf))
1559 error ("Actions for tracepoint %d too complex; "
1560 "please simplify.", t->number);
1561 strcat (buf, stepping_actions);
1565 remote_get_noisy_reply (target_buf);
1566 if (strcmp (target_buf, "OK"))
1567 error ("Target does not support tracepoints.");
1570 remote_get_noisy_reply (target_buf);
1571 if (strcmp (target_buf, "OK"))
1572 error ("Bogus reply from target: %s", target_buf);
1573 set_traceframe_num (-1); /* all old traceframes invalidated */
1574 set_tracepoint_num (-1);
1575 set_traceframe_context(-1);
1578 printf_filtered ("Trace can only be run on remote targets.\n");
1583 trace_stop_command (args, from_tty)
1586 { /* STUB_COMM IS_IMPLEMENTED */
1587 if (target_is_remote ())
1590 remote_get_noisy_reply (target_buf);
1591 if (strcmp (target_buf, "OK"))
1592 error ("Bogus reply from target: %s", target_buf);
1595 error ("Trace can only be run on remote targets.");
1598 /* tstatus command */
1600 trace_status_command (args, from_tty)
1603 { /* STUB_COMM IS_IMPLEMENTED */
1604 if (target_is_remote ())
1606 putpkt ("qTStatus");
1607 remote_get_noisy_reply (target_buf);
1608 if (strcmp (target_buf, "OK"))
1609 error ("Bogus reply from target: %s", target_buf);
1612 error ("Trace can only be run on remote targets.");
1615 /* Worker function for the various flavors of the tfind command */
1617 finish_tfind_command (msg, from_tty)
1621 int target_frameno = -1, target_tracept = -1;
1622 CORE_ADDR old_frame_addr;
1623 struct symbol *old_func;
1626 old_frame_addr = FRAME_FP (get_current_frame ());
1627 old_func = find_pc_function (read_pc ());
1630 reply = remote_get_noisy_reply (msg);
1632 while (reply && *reply)
1635 if ((target_frameno = strtol (++reply, &reply, 16)) == -1)
1637 /* A request for a non-existant trace frame has failed.
1638 Our response will be different, depending on FROM_TTY:
1640 If FROM_TTY is true, meaning that this command was
1641 typed interactively by the user, then give an error
1642 and DO NOT change the state of traceframe_number etc.
1644 However if FROM_TTY is false, meaning that we're either
1645 in a script, a loop, or a user-defined command, then
1646 DON'T give an error, but DO change the state of
1647 traceframe_number etc. to invalid.
1649 The rationalle is that if you typed the command, you
1650 might just have committed a typo or something, and you'd
1651 like to NOT lose your current debugging state. However
1652 if you're in a user-defined command or especially in a
1653 loop, then you need a way to detect that the command
1654 failed WITHOUT aborting. This allows you to write
1655 scripts that search thru the trace buffer until the end,
1656 and then continue on to do something else. */
1659 error ("Target failed to find requested trace frame.");
1663 printf_filtered ("End of trace buffer.\n");
1664 /* The following will not recurse, since it's special-cased */
1665 trace_find_command ("-1", from_tty);
1666 reply = NULL; /* break out of loop,
1667 (avoid recursive nonsense) */
1672 if ((target_tracept = strtol (++reply, &reply, 16)) == -1)
1673 error ("Target failed to find requested trace frame.");
1675 case 'O': /* "OK"? */
1676 if (reply[1] == 'K' && reply[2] == '\0')
1679 error ("Bogus reply from target: %s", reply);
1682 error ("Bogus reply from target: %s", reply);
1685 flush_cached_frames ();
1686 registers_changed ();
1687 select_frame (get_current_frame (), 0);
1688 set_traceframe_num (target_frameno);
1689 set_tracepoint_num (target_tracept);
1690 if (target_frameno == -1)
1691 set_traceframe_context (-1);
1693 set_traceframe_context (read_pc ());
1699 /* NOTE: in immitation of the step command, try to determine
1700 whether we have made a transition from one function to another.
1701 If so, we'll print the "stack frame" (ie. the new function and
1702 it's arguments) -- otherwise we'll just show the new source line.
1704 This determination is made by checking (1) whether the current
1705 function has changed, and (2) whether the current FP has changed.
1706 Hack: if the FP wasn't collected, either at the current or the
1707 previous frame, assume that the FP has NOT changed. */
1709 if (old_func == find_pc_function (read_pc ()) &&
1710 (old_frame_addr == 0 ||
1711 FRAME_FP (get_current_frame ()) == 0 ||
1712 old_frame_addr == FRAME_FP (get_current_frame ())))
1717 print_stack_frame (selected_frame, selected_frame_level, source_only);
1722 /* trace_find_command takes a trace frame number n,
1723 sends "QTFrame:<n>" to the target,
1724 and accepts a reply that may contain several optional pieces
1725 of information: a frame number, a tracepoint number, and an
1726 indication of whether this is a trap frame or a stepping frame.
1728 The minimal response is just "OK" (which indicates that the
1729 target does not give us a frame number or a tracepoint number).
1730 Instead of that, the target may send us a string containing
1732 F<hexnum> (gives the selected frame number)
1733 T<hexnum> (gives the selected tracepoint number)
1738 trace_find_command (args, from_tty)
1741 { /* STUB_COMM PART_IMPLEMENTED */
1742 /* this should only be called with a numeric argument */
1744 int target_frameno = -1, target_tracept = -1, target_stepfrm = 0;
1747 if (target_is_remote ())
1749 if (args == 0 || *args == 0)
1750 { /* TFIND with no args means find NEXT trace frame. */
1751 if (traceframe_number == -1)
1752 frameno = 0; /* "next" is first one */
1754 frameno = traceframe_number + 1;
1756 else if (0 == strcmp (args, "-"))
1758 if (traceframe_number == -1)
1759 error ("not debugging trace buffer");
1760 else if (from_tty && traceframe_number == 0)
1761 error ("already at start of trace buffer");
1763 frameno = traceframe_number - 1;
1766 frameno = parse_and_eval_address (args);
1768 sprintf (target_buf, "QTFrame:%x", frameno);
1770 putpkt (target_buf);
1771 tmp = remote_get_noisy_reply (target_buf);
1773 if (frameno == -1) /* end trace debugging */
1774 { /* hopefully the stub has complied! */
1775 if (0 != strcmp (tmp, "OK"))
1776 error ("Bogus response from target: %s", tmp);
1778 finish_tfind_command (NULL, from_tty);
1781 finish_tfind_command (tmp, from_tty);
1783 finish_tfind_command (target_buf, from_tty);
1787 error ("Trace can only be run on remote targets.");
1792 trace_find_end_command (args, from_tty)
1796 trace_find_command ("-1", from_tty);
1801 trace_find_none_command (args, from_tty)
1805 trace_find_command ("-1", from_tty);
1810 trace_find_start_command (args, from_tty)
1814 trace_find_command ("0", from_tty);
1817 /* tfind pc command */
1819 trace_find_pc_command (args, from_tty)
1822 { /* STUB_COMM PART_IMPLEMENTED */
1827 if (target_is_remote ())
1829 if (args == 0 || *args == 0)
1830 pc = read_pc (); /* default is current pc */
1832 pc = parse_and_eval_address (args);
1834 sprintf (target_buf, "QTFrame:pc:%x", pc);
1836 putpkt (target_buf);
1837 tmp = remote_get_noisy_reply (target_buf);
1839 finish_tfind_command (tmp, from_tty);
1841 finish_tfind_command (target_buf, from_tty);
1845 error ("Trace can only be run on remote targets.");
1848 /* tfind tracepoint command */
1850 trace_find_tracepoint_command (args, from_tty)
1853 { /* STUB_COMM PART_IMPLEMENTED */
1854 int target_frameno, tdp;
1857 if (target_is_remote ())
1859 if (args == 0 || *args == 0)
1860 if (tracepoint_number == -1)
1861 error ("No current tracepoint -- please supply an argument.");
1863 tdp = tracepoint_number; /* default is current TDP */
1865 tdp = parse_and_eval_address (args);
1867 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
1869 putpkt (target_buf);
1870 tmp = remote_get_noisy_reply (target_buf);
1872 finish_tfind_command (tmp, from_tty);
1874 finish_tfind_command (target_buf, from_tty);
1878 error ("Trace can only be run on remote targets.");
1881 /* TFIND LINE command:
1883 This command will take a sourceline for argument, just like BREAK
1884 or TRACE (ie. anything that "decode_line_1" can handle).
1886 With no argument, this command will find the next trace frame
1887 corresponding to a source line OTHER THAN THE CURRENT ONE. */
1890 trace_find_line_command (args, from_tty)
1893 { /* STUB_COMM PART_IMPLEMENTED */
1894 static CORE_ADDR start_pc, end_pc;
1895 struct symtabs_and_lines sals;
1896 struct symtab_and_line sal;
1899 struct cleanup *old_chain;
1901 if (target_is_remote ())
1903 if (args == 0 || *args == 0)
1905 sal = find_pc_line ((get_current_frame ())->pc, 0);
1907 sals.sals = (struct symtab_and_line *)
1908 xmalloc (sizeof (struct symtab_and_line));
1913 sals = decode_line_spec (args, 1);
1917 old_chain = make_cleanup (free, sals.sals);
1918 if (sal.symtab == 0)
1920 printf_filtered ("TFIND: No line number information available");
1923 /* This is useful for "info line *0x7f34". If we can't tell the
1924 user about a source line, at least let them have the symbolic
1926 printf_filtered (" for address ");
1928 print_address (sal.pc, gdb_stdout);
1929 printf_filtered (";\n -- will attempt to find by PC. \n");
1933 printf_filtered (".\n");
1934 return; /* no line, no PC; what can we do? */
1937 else if (sal.line > 0
1938 && find_line_pc_range (sal, &start_pc, &end_pc))
1940 if (start_pc == end_pc)
1942 printf_filtered ("Line %d of \"%s\"",
1943 sal.line, sal.symtab->filename);
1945 printf_filtered (" is at address ");
1946 print_address (start_pc, gdb_stdout);
1948 printf_filtered (" but contains no code.\n");
1949 sal = find_pc_line (start_pc, 0);
1951 find_line_pc_range (sal, &start_pc, &end_pc) &&
1953 printf_filtered ("Attempting to find line %d instead.\n",
1956 error ("Cannot find a good line.");
1960 /* Is there any case in which we get here, and have an address
1961 which the user would want to see? If we have debugging symbols
1962 and no line numbers? */
1963 error ("Line number %d is out of range for \"%s\".\n",
1964 sal.line, sal.symtab->filename);
1966 if (args && *args) /* find within range of stated line */
1967 sprintf (target_buf, "QTFrame:range:%x:%x", start_pc, end_pc - 1);
1968 else /* find OUTSIDE OF range of CURRENT line */
1969 sprintf (target_buf, "QTFrame:outside:%x:%x", start_pc, end_pc - 1);
1971 putpkt (target_buf);
1972 tmp = remote_get_noisy_reply (target_buf);
1974 finish_tfind_command (tmp, from_tty);
1976 finish_tfind_command (target_buf, from_tty);
1978 do_cleanups (old_chain);
1981 error ("Trace can only be run on remote targets.");
1984 /* tfind range command */
1986 trace_find_range_command (args, from_tty)
1989 { /* STUB_COMM PART_IMPLEMENTED */
1990 static CORE_ADDR start, stop;
1994 if (target_is_remote ())
1996 if (args == 0 || *args == 0)
1997 { /* XXX FIXME: what should default behavior be? */
1998 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2002 if (0 != (tmp = strchr (args, ',' )))
2004 *tmp++ = '\0'; /* terminate start address */
2005 while (isspace (*tmp))
2007 start = parse_and_eval_address (args);
2008 stop = parse_and_eval_address (tmp);
2011 { /* no explicit end address? */
2012 start = parse_and_eval_address (args);
2013 stop = start + 1; /* ??? */
2016 sprintf (target_buf, "QTFrame:range:%x:%x", start, stop);
2018 putpkt (target_buf);
2019 tmp = remote_get_noisy_reply (target_buf);
2021 finish_tfind_command (tmp, from_tty);
2023 finish_tfind_command (target_buf, from_tty);
2027 error ("Trace can only be run on remote targets.");
2030 /* tfind outside command */
2032 trace_find_outside_command (args, from_tty)
2035 { /* STUB_COMM PART_IMPLEMENTED */
2036 CORE_ADDR start, stop;
2040 if (target_is_remote ())
2042 if (args == 0 || *args == 0)
2043 { /* XXX FIXME: what should default behavior be? */
2044 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2048 if (0 != (tmp = strchr (args, ',' )))
2050 *tmp++ = '\0'; /* terminate start address */
2051 while (isspace (*tmp))
2053 start = parse_and_eval_address (args);
2054 stop = parse_and_eval_address (tmp);
2057 { /* no explicit end address? */
2058 start = parse_and_eval_address (args);
2059 stop = start + 1; /* ??? */
2062 sprintf (target_buf, "QTFrame:outside:%x:%x", start, stop);
2064 putpkt (target_buf);
2065 tmp = remote_get_noisy_reply (target_buf);
2067 finish_tfind_command (tmp, from_tty);
2069 finish_tfind_command (target_buf, from_tty);
2073 error ("Trace can only be run on remote targets.");
2076 /* save-tracepoints command */
2078 tracepoint_save_command (args, from_tty)
2082 struct tracepoint *tp;
2083 struct action_line *line;
2085 char *i1 = " ", *i2 = " ";
2086 char *indent, *actionline;
2088 if (args == 0 || *args == 0)
2089 error ("Argument required (file name in which to save tracepoints");
2091 if (tracepoint_chain == 0)
2093 warning ("save-tracepoints: no tracepoints to save.\n");
2097 if (!(fp = fopen (args, "w")))
2098 error ("Unable to open file '%s' for saving tracepoints");
2100 ALL_TRACEPOINTS (tp)
2102 if (tp->addr_string)
2103 fprintf (fp, "trace %s\n", tp->addr_string);
2105 fprintf (fp, "trace *0x%x\n", tp->address);
2108 fprintf (fp, " passcount %d\n", tp->pass_count);
2112 fprintf (fp, " actions\n");
2114 for (line = tp->actions; line; line = line->next)
2116 struct cmd_list_element *cmd;
2118 actionline = line->action;
2119 while (isspace(*actionline))
2122 fprintf (fp, "%s%s\n", indent, actionline);
2123 if (*actionline != '#') /* skip for comment lines */
2125 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2127 error ("Bad action list item: %s", actionline);
2128 if (cmd->function.cfunc == while_stepping_pseudocommand)
2130 else if (cmd->function.cfunc == end_actions_pseudocommand)
2138 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2142 /* info scope command: list the locals for a scope. */
2144 scope_info (args, from_tty)
2148 struct symtab_and_line sal;
2149 struct symtabs_and_lines sals;
2151 struct minimal_symbol *msym;
2152 struct block *block;
2153 char **canonical, *symname, *save_args = args;
2154 int i, nsyms, count = 0;
2156 if (args == 0 || *args == 0)
2157 error ("requires an argument (function, line or *addr) to define a scope");
2159 sals = decode_line_1 (&args, 1, NULL, 0, &canonical);
2160 if (sals.nelts == 0)
2161 return; /* presumably decode_line_1 has already warned */
2163 /* Resolve line numbers to PC */
2164 resolve_sal_pc (&sals.sals[0]);
2165 block = block_for_pc (sals.sals[0].pc);
2169 nsyms = BLOCK_NSYMS (block);
2170 for (i = 0; i < nsyms; i++)
2173 printf_filtered ("Scope for %s:\n", save_args);
2175 sym = BLOCK_SYM (block, i);
2176 symname = SYMBOL_NAME (sym);
2177 if (symname == NULL || *symname == '\0')
2178 continue; /* probably botched, certainly useless */
2180 printf_filtered ("Symbol %s is ", symname);
2181 switch (SYMBOL_CLASS (sym)) {
2183 case LOC_UNDEF: /* messed up symbol? */
2184 printf_filtered ("a bogus symbol, class %d.\n",
2185 SYMBOL_CLASS (sym));
2186 count--; /* don't count this one */
2189 printf_filtered ("a constant with value %d (0x%x)",
2190 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2192 case LOC_CONST_BYTES:
2193 printf_filtered ("constant bytes: ");
2194 if (SYMBOL_TYPE (sym))
2195 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (sym)); i++)
2196 fprintf_filtered (gdb_stdout, " %02x",
2197 (unsigned) SYMBOL_VALUE_BYTES (sym) [i]);
2200 printf_filtered ("in static storage at address ");
2201 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2204 printf_filtered ("a local variable in register $%s",
2205 reg_names [SYMBOL_VALUE (sym)]);
2209 printf_filtered ("an argument at stack/frame offset %ld",
2210 SYMBOL_VALUE (sym));
2213 printf_filtered ("a local variable at frame offset %ld",
2214 SYMBOL_VALUE (sym));
2217 printf_filtered ("a reference argument at offset %ld",
2218 SYMBOL_VALUE (sym));
2221 printf_filtered ("an argument in register $%s",
2222 reg_names[SYMBOL_VALUE (sym)]);
2224 case LOC_REGPARM_ADDR:
2225 printf_filtered ("the address of an argument, in register $%s",
2226 reg_names[SYMBOL_VALUE (sym)]);
2229 printf_filtered ("a typedef.\n");
2232 printf_filtered ("a label at address ");
2233 print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), 1, gdb_stdout);
2236 printf_filtered ("a function at address ");
2237 print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), 1,
2241 printf_filtered ("a variable at offset %d from register $%s",
2243 reg_names [SYMBOL_BASEREG (sym)]);
2245 case LOC_BASEREG_ARG:
2246 printf_filtered ("an argument at offset %d from register $%s",
2248 reg_names [SYMBOL_BASEREG (sym)]);
2250 case LOC_UNRESOLVED:
2251 msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, NULL);
2253 printf_filtered ("Unresolved Static");
2256 printf_filtered ("static storage at address ");
2257 print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2261 case LOC_OPTIMIZED_OUT:
2262 printf_filtered ("optimized out.\n");
2265 if (SYMBOL_TYPE (sym))
2266 printf_filtered (", length %d.\n",
2267 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2269 if (BLOCK_FUNCTION (block))
2272 block = BLOCK_SUPERBLOCK (block);
2275 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2279 /* worker function (cleanup) */
2281 replace_comma (comma)
2289 trace_dump_command (args, from_tty)
2293 struct tracepoint *t;
2294 struct action_line *action;
2295 char *action_exp, *next_comma;
2296 struct cleanup *old_cleanups;
2297 int stepping_actions = 0;
2298 int stepping_frame = 0;
2300 if (tracepoint_number == -1)
2302 warning ("No current trace frame.");
2307 if (t->number == tracepoint_number)
2311 error ("No known tracepoint matches 'current' tracepoint #%d.",
2314 old_cleanups = make_cleanup (null_cleanup, NULL);
2316 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2317 tracepoint_number, traceframe_number);
2319 /* The current frame is a trap frame if the frame PC is equal
2320 to the tracepoint PC. If not, then the current frame was
2321 collected during single-stepping. */
2323 stepping_frame = (t->address != read_pc());
2325 for (action = t->actions; action; action = action->next)
2327 struct cmd_list_element *cmd;
2329 action_exp = action->action;
2330 while (isspace (*action_exp))
2333 /* The collection actions to be done while stepping are
2334 bracketed by the commands "while-stepping" and "end". */
2336 if (*action_exp == '#') /* comment line */
2339 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2341 error ("Bad action list item: %s", action_exp);
2343 if (cmd->function.cfunc == while_stepping_pseudocommand)
2344 stepping_actions = 1;
2345 else if (cmd->function.cfunc == end_actions_pseudocommand)
2346 stepping_actions = 0;
2347 else if (cmd->function.cfunc == collect_pseudocommand)
2349 /* Display the collected data.
2350 For the trap frame, display only what was collected at the trap.
2351 Likewise for stepping frames, display only what was collected
2352 while stepping. This means that the two boolean variables,
2353 STEPPING_FRAME and STEPPING_ACTIONS should be equal. */
2354 if (stepping_frame == stepping_actions)
2356 do { /* repeat over a comma-separated list */
2358 if (*action_exp == ',')
2360 while (isspace (*action_exp))
2363 next_comma = strchr (action_exp, ',');
2365 if (0 == strncasecmp (action_exp, "$reg", 4))
2366 registers_info (NULL, from_tty);
2367 else if (0 == strncasecmp (action_exp, "$loc", 4))
2368 locals_info (NULL, from_tty);
2369 else if (0 == strncasecmp (action_exp, "$arg", 4))
2370 args_info (NULL, from_tty);
2371 else if (action_exp[0] == '$' && action_exp[1] == '(')
2373 long typecode, size;
2374 bfd_signed_vma offset;
2377 action_exp = parse_and_eval_memrange (action_exp,
2382 if (typecode != 0 && typecode != -1)
2383 offset += read_register (typecode);
2384 sprintf (fmt, "/%dxb 0x%x", size, offset);
2385 x_command (fmt, from_tty);
2386 next_comma = strchr (action_exp, ',');
2392 make_cleanup (replace_comma, next_comma);
2395 printf_filtered ("%s = ", action_exp);
2396 output_command (action_exp, from_tty);
2397 printf_filtered ("\n");
2401 action_exp = next_comma;
2402 } while (action_exp && *action_exp == ',');
2406 discard_cleanups (old_cleanups);
2409 /* module initialization */
2411 _initialize_tracepoint ()
2413 tracepoint_chain = 0;
2414 tracepoint_count = 0;
2415 traceframe_number = -1;
2416 tracepoint_number = -1;
2418 set_internalvar (lookup_internalvar ("tpnum"),
2419 value_from_longest (builtin_type_int, (LONGEST) 0));
2420 set_internalvar (lookup_internalvar ("trace_frame"),
2421 value_from_longest (builtin_type_int, (LONGEST) 0));
2423 if (tracepoint_list.list == NULL)
2425 tracepoint_list.listsize = 128;
2426 tracepoint_list.list = xmalloc
2427 (tracepoint_list.listsize * sizeof (struct memrange));
2429 if (stepping_list.list == NULL)
2431 stepping_list.listsize = 128;
2432 stepping_list.list = xmalloc
2433 (stepping_list.listsize * sizeof (struct memrange));
2436 add_info ("scope", scope_info,
2437 "List the variables local to a scope");
2439 add_cmd ("tracepoints", class_trace, NO_FUNCTION,
2440 "Tracing of program execution without stopping the program.",
2443 add_info ("tracepoints", tracepoints_info,
2444 "Status of tracepoints, or tracepoint number NUMBER.\n\
2445 Convenience variable \"$tpnum\" contains the number of the\n\
2446 last tracepoint set.");
2448 add_info_alias ("tp", "tracepoints", 1);
2450 add_com ("save-tracepoints", class_trace, tracepoint_save_command,
2451 "Save current tracepoint definitions as a script.\n\
2452 Use the 'source' command in another debug session to restore them.");
2454 add_com ("tdump", class_trace, trace_dump_command,
2455 "Print everything collected at the current tracepoint.");
2457 add_prefix_cmd ("tfind", class_trace, trace_find_command,
2458 "Select a trace frame;\n\
2459 No argument means forward by one frame; '-' meand backward by one frame.",
2460 &tfindlist, "tfind ", 1, &cmdlist);
2462 add_cmd ("outside", class_trace, trace_find_outside_command,
2463 "Select a trace frame whose PC is outside the given \
2464 range.\nUsage: tfind outside addr1, addr2",
2467 add_cmd ("range", class_trace, trace_find_range_command,
2468 "Select a trace frame whose PC is in the given range.\n\
2469 Usage: tfind range addr1,addr2",
2472 add_cmd ("line", class_trace, trace_find_line_command,
2473 "Select a trace frame by source line.\n\
2474 Argument can be a line number (with optional source file), \n\
2475 a function name, or '*' followed by an address.\n\
2476 Default argument is 'the next source line that was traced'.",
2479 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command,
2480 "Select a trace frame by tracepoint number.\n\
2481 Default is the tracepoint for the current trace frame.",
2484 add_cmd ("pc", class_trace, trace_find_pc_command,
2485 "Select a trace frame by PC.\n\
2486 Default is the current PC, or the PC of the current trace frame.",
2489 add_cmd ("end", class_trace, trace_find_end_command,
2490 "Synonym for 'none'.\n\
2491 De-select any trace frame and resume 'live' debugging.",
2494 add_cmd ("none", class_trace, trace_find_none_command,
2495 "De-select any trace frame and resume 'live' debugging.",
2498 add_cmd ("start", class_trace, trace_find_start_command,
2499 "Select the first trace frame in the trace buffer.",
2502 add_com ("tstatus", class_trace, trace_status_command,
2503 "Display the status of the current trace data collection.");
2505 add_com ("tstop", class_trace, trace_stop_command,
2506 "Stop trace data collection.");
2508 add_com ("tstart", class_trace, trace_start_command,
2509 "Start trace data collection.");
2511 add_com ("passcount", class_trace, trace_pass_command,
2512 "Set the passcount for a tracepoint.\n\
2513 The trace will end when the tracepoint has been passed 'count' times.\n\
2514 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2515 if TPNUM is omitted, passcount refers to the last tracepoint defined.");
2517 add_com ("end", class_trace, end_actions_pseudocommand,
2518 "Ends a list of commands or actions.\n\
2519 Several GDB commands allow you to enter a list of commands or actions.\n\
2520 Entering \"end\" on a line by itself is the normal way to terminate\n\
2522 Note: the \"end\" command cannot be used at the gdb prompt.");
2524 add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
2525 "Specify single-stepping behavior at a tracepoint.\n\
2526 Argument is number of instructions to trace in single-step mode\n\
2527 following the tracepoint. This command is normally followed by\n\
2528 one or more \"collect\" commands, to specify what to collect\n\
2529 while single-stepping.\n\n\
2530 Note: this command can only be used in a tracepoint \"actions\" list.");
2532 add_com_alias ("ws", "while-stepping", class_alias, 0);
2533 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2535 add_com ("collect", class_trace, collect_pseudocommand,
2536 "Specify one or more data items to be collected at a tracepoint.\n\
2537 Accepts a comma-separated list of (one or more) arguments.\n\
2538 Things that may be collected include registers, variables, plus\n\
2539 the following special arguments:\n\
2540 $regs -- all registers.\n\
2541 $args -- all function arguments.\n\
2542 $locals -- all variables local to the block/function scope.\n\
2543 $(addr,len) -- a literal memory range.\n\
2544 $($reg,addr,len) -- a register-relative literal memory range.\n\n\
2545 Note: this command can only be used in a tracepoint \"actions\" list.");
2547 add_com ("actions", class_trace, trace_actions_command,
2548 "Specify the actions to be taken at a tracepoint.\n\
2549 Tracepoint actions may include collecting of specified data, \n\
2550 single-stepping, or enabling/disabling other tracepoints, \n\
2551 depending on target's capabilities.");
2553 add_cmd ("tracepoints", class_trace, delete_trace_command,
2554 "Delete specified tracepoints.\n\
2555 Arguments are tracepoint numbers, separated by spaces.\n\
2556 No argument means delete all tracepoints.",
2559 add_cmd ("tracepoints", class_trace, disable_trace_command,
2560 "Disable specified tracepoints.\n\
2561 Arguments are tracepoint numbers, separated by spaces.\n\
2562 No argument means disable all tracepoints.",
2565 add_cmd ("tracepoints", class_trace, enable_trace_command,
2566 "Enable specified tracepoints.\n\
2567 Arguments are tracepoint numbers, separated by spaces.\n\
2568 No argument means enable all tracepoints.",
2571 add_com ("trace", class_trace, trace_command,
2572 "Set a tracepoint at a specified line or function or address.\n\
2573 Argument may be a line number, function name, or '*' plus an address.\n\
2574 For a line number or function, trace at the start of its code.\n\
2575 If an address is specified, trace at that exact address.\n\n\
2576 Do \"help tracepoints\" for info on other tracepoint commands.");
2578 add_com_alias ("tp", "trace", class_alias, 0);
2579 add_com_alias ("tr", "trace", class_alias, 1);
2580 add_com_alias ("tra", "trace", class_alias, 1);
2581 add_com_alias ("trac", "trace", class_alias, 1);