1 /* Tracing functionality for remote targets in custom GDB protocol
2
3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
4 Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 #include "defs.h"
24 #include "symtab.h"
25 #include "frame.h"
26 #include "gdbtypes.h"
27 #include "expression.h"
28 #include "gdbcmd.h"
29 #include "value.h"
30 #include "target.h"
31 #include "language.h"
32 #include "gdb_string.h"
33 #include "inferior.h"
34 #include "tracepoint.h"
35 #include "remote.h"
36 #include "linespec.h"
37 #include "regcache.h"
38 #include "completer.h"
39 #include "gdb-events.h"
40 #include "block.h"
41 #include "dictionary.h"
42
43 #include "ax.h"
44 #include "ax-gdb.h"
45
46 /* readline include files */
47 #include "readline/readline.h"
48 #include "readline/history.h"
49
50 /* readline defines this. */
51 #undef savestring
52
53 #include <ctype.h>
54
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58
59 /* Maximum length of an agent aexpression.
60 This accounts for the fact that packets are limited to 400 bytes
61 (which includes everything -- including the checksum), and assumes
62 the worst case of maximum length for each of the pieces of a
63 continuation packet.
64
65 NOTE: expressions get mem2hex'ed otherwise this would be twice as
66 large. (400 - 31)/2 == 184 */
67 #define MAX_AGENT_EXPR_LEN 184
68
69
70 extern void (*deprecated_readline_begin_hook) (char *, ...);
71 extern char *(*deprecated_readline_hook) (char *);
72 extern void (*deprecated_readline_end_hook) (void);
73 extern void x_command (char *, int);
74 extern int addressprint; /* Print machine addresses? */
75
76 /* GDB commands implemented in other modules:
77 */
78
79 extern void output_command (char *, int);
80
81 /*
82 Tracepoint.c:
83
84 This module defines the following debugger commands:
85 trace : set a tracepoint on a function, line, or address.
86 info trace : list all debugger-defined tracepoints.
87 delete trace : delete one or more tracepoints.
88 enable trace : enable one or more tracepoints.
89 disable trace : disable one or more tracepoints.
90 actions : specify actions to be taken at a tracepoint.
91 passcount : specify a pass count for a tracepoint.
92 tstart : start a trace experiment.
93 tstop : stop a trace experiment.
94 tstatus : query the status of a trace experiment.
95 tfind : find a trace frame in the trace buffer.
96 tdump : print everything collected at the current tracepoint.
97 save-tracepoints : write tracepoint setup into a file.
98
99 This module defines the following user-visible debugger variables:
100 $trace_frame : sequence number of trace frame currently being debugged.
101 $trace_line : source line of trace frame currently being debugged.
102 $trace_file : source file of trace frame currently being debugged.
103 $tracepoint : tracepoint number of trace frame currently being debugged.
104 */
105
106
107 /* ======= Important global variables: ======= */
108
109 /* Chain of all tracepoints defined. */
110 struct tracepoint *tracepoint_chain;
111
112 /* Number of last tracepoint made. */
113 static int tracepoint_count;
114
115 /* Number of last traceframe collected. */
116 static int traceframe_number;
117
118 /* Tracepoint for last traceframe collected. */
119 static int tracepoint_number;
120
121 /* Symbol for function for last traceframe collected */
122 static struct symbol *traceframe_fun;
123
124 /* Symtab and line for last traceframe collected */
125 static struct symtab_and_line traceframe_sal;
126
127 /* Tracing command lists */
128 static struct cmd_list_element *tfindlist;
129
130 /* ======= Important command functions: ======= */
131 static void trace_command (char *, int);
132 static void tracepoints_info (char *, int);
133 static void delete_trace_command (char *, int);
134 static void enable_trace_command (char *, int);
135 static void disable_trace_command (char *, int);
136 static void trace_pass_command (char *, int);
137 static void trace_actions_command (char *, int);
138 static void trace_start_command (char *, int);
139 static void trace_stop_command (char *, int);
140 static void trace_status_command (char *, int);
141 static void trace_find_command (char *, int);
142 static void trace_find_pc_command (char *, int);
143 static void trace_find_tracepoint_command (char *, int);
144 static void trace_find_line_command (char *, int);
145 static void trace_find_range_command (char *, int);
146 static void trace_find_outside_command (char *, int);
147 static void tracepoint_save_command (char *, int);
148 static void trace_dump_command (char *, int);
149
150 /* support routines */
151 static void trace_mention (struct tracepoint *);
152
153 struct collection_list;
154 static void add_aexpr (struct collection_list *, struct agent_expr *);
155 static char *mem2hex (gdb_byte *, char *, int);
156 static void add_register (struct collection_list *collection,
157 unsigned int regno);
158 static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
159 static void free_actions_list (char **actions_list);
160 static void free_actions_list_cleanup_wrapper (void *);
161
162 extern void _initialize_tracepoint (void);
163
164 /* Utility: returns true if "target remote" */
165 static int
target_is_remote(void)166 target_is_remote (void)
167 {
168 if (current_target.to_shortname &&
169 (strcmp (current_target.to_shortname, "remote") == 0
170 || strcmp (current_target.to_shortname, "extended-remote") == 0))
171 return 1;
172 else
173 return 0;
174 }
175
176 /* Utility: generate error from an incoming stub packet. */
177 static void
trace_error(char * buf)178 trace_error (char *buf)
179 {
180 if (*buf++ != 'E')
181 return; /* not an error msg */
182 switch (*buf)
183 {
184 case '1': /* malformed packet error */
185 if (*++buf == '0') /* general case: */
186 error (_("tracepoint.c: error in outgoing packet."));
187 else
188 error (_("tracepoint.c: error in outgoing packet at field #%ld."),
189 strtol (buf, NULL, 16));
190 case '2':
191 error (_("trace API error 0x%s."), ++buf);
192 default:
193 error (_("Target returns error code '%s'."), buf);
194 }
195 }
196
197 /* Utility: wait for reply from stub, while accepting "O" packets. */
198 static char *
remote_get_noisy_reply(char * buf,long sizeof_buf)199 remote_get_noisy_reply (char *buf,
200 long sizeof_buf)
201 {
202 do /* Loop on reply from remote stub. */
203 {
204 QUIT; /* allow user to bail out with ^C */
205 getpkt (buf, sizeof_buf, 0);
206 if (buf[0] == 0)
207 error (_("Target does not support this command."));
208 else if (buf[0] == 'E')
209 trace_error (buf);
210 else if (buf[0] == 'O' &&
211 buf[1] != 'K')
212 remote_console_output (buf + 1); /* 'O' message from stub */
213 else
214 return buf; /* here's the actual reply */
215 }
216 while (1);
217 }
218
219 /* Set tracepoint count to NUM. */
220 static void
set_tracepoint_count(int num)221 set_tracepoint_count (int num)
222 {
223 tracepoint_count = num;
224 set_internalvar (lookup_internalvar ("tpnum"),
225 value_from_longest (builtin_type_int, (LONGEST) num));
226 }
227
228 /* Set traceframe number to NUM. */
229 static void
set_traceframe_num(int num)230 set_traceframe_num (int num)
231 {
232 traceframe_number = num;
233 set_internalvar (lookup_internalvar ("trace_frame"),
234 value_from_longest (builtin_type_int, (LONGEST) num));
235 }
236
237 /* Set tracepoint number to NUM. */
238 static void
set_tracepoint_num(int num)239 set_tracepoint_num (int num)
240 {
241 tracepoint_number = num;
242 set_internalvar (lookup_internalvar ("tracepoint"),
243 value_from_longest (builtin_type_int,
244 (LONGEST) num));
245 }
246
247 /* Set externally visible debug variables for querying/printing
248 the traceframe context (line, function, file) */
249
250 static void
set_traceframe_context(CORE_ADDR trace_pc)251 set_traceframe_context (CORE_ADDR trace_pc)
252 {
253 static struct type *func_string, *file_string;
254 static struct type *func_range, *file_range;
255 struct value *func_val;
256 struct value *file_val;
257 static struct type *charstar;
258 int len;
259
260 if (charstar == (struct type *) NULL)
261 charstar = lookup_pointer_type (builtin_type_char);
262
263 if (trace_pc == -1) /* Cease debugging any trace buffers. */
264 {
265 traceframe_fun = 0;
266 traceframe_sal.pc = traceframe_sal.line = 0;
267 traceframe_sal.symtab = NULL;
268 set_internalvar (lookup_internalvar ("trace_func"),
269 value_from_pointer (charstar, (LONGEST) 0));
270 set_internalvar (lookup_internalvar ("trace_file"),
271 value_from_pointer (charstar, (LONGEST) 0));
272 set_internalvar (lookup_internalvar ("trace_line"),
273 value_from_longest (builtin_type_int,
274 (LONGEST) - 1));
275 return;
276 }
277
278 /* Save as globals for internal use. */
279 traceframe_sal = find_pc_line (trace_pc, 0);
280 traceframe_fun = find_pc_function (trace_pc);
281
282 /* Save linenumber as "$trace_line", a debugger variable visible to
283 users. */
284 set_internalvar (lookup_internalvar ("trace_line"),
285 value_from_longest (builtin_type_int,
286 (LONGEST) traceframe_sal.line));
287
288 /* Save func name as "$trace_func", a debugger variable visible to
289 users. */
290 if (traceframe_fun == NULL ||
291 DEPRECATED_SYMBOL_NAME (traceframe_fun) == NULL)
292 set_internalvar (lookup_internalvar ("trace_func"),
293 value_from_pointer (charstar, (LONGEST) 0));
294 else
295 {
296 len = strlen (DEPRECATED_SYMBOL_NAME (traceframe_fun));
297 func_range = create_range_type (func_range,
298 builtin_type_int, 0, len - 1);
299 func_string = create_array_type (func_string,
300 builtin_type_char, func_range);
301 func_val = allocate_value (func_string);
302 deprecated_set_value_type (func_val, func_string);
303 memcpy (value_contents_raw (func_val),
304 DEPRECATED_SYMBOL_NAME (traceframe_fun),
305 len);
306 deprecated_set_value_modifiable (func_val, 0);
307 set_internalvar (lookup_internalvar ("trace_func"), func_val);
308 }
309
310 /* Save file name as "$trace_file", a debugger variable visible to
311 users. */
312 if (traceframe_sal.symtab == NULL ||
313 traceframe_sal.symtab->filename == NULL)
314 set_internalvar (lookup_internalvar ("trace_file"),
315 value_from_pointer (charstar, (LONGEST) 0));
316 else
317 {
318 len = strlen (traceframe_sal.symtab->filename);
319 file_range = create_range_type (file_range,
320 builtin_type_int, 0, len - 1);
321 file_string = create_array_type (file_string,
322 builtin_type_char, file_range);
323 file_val = allocate_value (file_string);
324 deprecated_set_value_type (file_val, file_string);
325 memcpy (value_contents_raw (file_val),
326 traceframe_sal.symtab->filename,
327 len);
328 deprecated_set_value_modifiable (file_val, 0);
329 set_internalvar (lookup_internalvar ("trace_file"), file_val);
330 }
331 }
332
333 /* Low level routine to set a tracepoint.
334 Returns the tracepoint object so caller can set other things.
335 Does not set the tracepoint number!
336 Does not print anything.
337
338 ==> This routine should not be called if there is a chance of later
339 error(); otherwise it leaves a bogus tracepoint on the chain.
340 Validate your arguments BEFORE calling this routine! */
341
342 static struct tracepoint *
set_raw_tracepoint(struct symtab_and_line sal)343 set_raw_tracepoint (struct symtab_and_line sal)
344 {
345 struct tracepoint *t, *tc;
346 struct cleanup *old_chain;
347
348 t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
349 old_chain = make_cleanup (xfree, t);
350 memset (t, 0, sizeof (*t));
351 t->address = sal.pc;
352 if (sal.symtab == NULL)
353 t->source_file = NULL;
354 else
355 t->source_file = savestring (sal.symtab->filename,
356 strlen (sal.symtab->filename));
357
358 t->section = sal.section;
359 t->language = current_language->la_language;
360 t->input_radix = input_radix;
361 t->line_number = sal.line;
362 t->enabled_p = 1;
363 t->next = 0;
364 t->step_count = 0;
365 t->pass_count = 0;
366 t->addr_string = NULL;
367
368 /* Add this tracepoint to the end of the chain
369 so that a list of tracepoints will come out in order
370 of increasing numbers. */
371
372 tc = tracepoint_chain;
373 if (tc == 0)
374 tracepoint_chain = t;
375 else
376 {
377 while (tc->next)
378 tc = tc->next;
379 tc->next = t;
380 }
381 discard_cleanups (old_chain);
382 return t;
383 }
384
385 /* Set a tracepoint according to ARG (function, linenum or *address). */
386 static void
trace_command(char * arg,int from_tty)387 trace_command (char *arg, int from_tty)
388 {
389 char **canonical = (char **) NULL;
390 struct symtabs_and_lines sals;
391 struct symtab_and_line sal;
392 struct tracepoint *t;
393 char *addr_start = 0, *addr_end = 0;
394 int i;
395
396 if (!arg || !*arg)
397 error (_("trace command requires an argument"));
398
399 if (from_tty && info_verbose)
400 printf_filtered ("TRACE %s\n", arg);
401
402 addr_start = arg;
403 sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
404 0, &canonical, NULL);
405 addr_end = arg;
406 if (!sals.nelts)
407 return; /* ??? Presumably decode_line_1 has already warned? */
408
409 /* Resolve all line numbers to PC's */
410 for (i = 0; i < sals.nelts; i++)
411 resolve_sal_pc (&sals.sals[i]);
412
413 /* Now set all the tracepoints. */
414 for (i = 0; i < sals.nelts; i++)
415 {
416 sal = sals.sals[i];
417
418 t = set_raw_tracepoint (sal);
419 set_tracepoint_count (tracepoint_count + 1);
420 t->number = tracepoint_count;
421
422 /* If a canonical line spec is needed use that instead of the
423 command string. */
424 if (canonical != (char **) NULL && canonical[i] != NULL)
425 t->addr_string = canonical[i];
426 else if (addr_start)
427 t->addr_string = savestring (addr_start, addr_end - addr_start);
428
429 trace_mention (t);
430 }
431
432 if (sals.nelts > 1)
433 {
434 printf_filtered ("Multiple tracepoints were set.\n");
435 printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
436 }
437 }
438
439 /* Tell the user we have just set a tracepoint TP. */
440
441 static void
trace_mention(struct tracepoint * tp)442 trace_mention (struct tracepoint *tp)
443 {
444 printf_filtered ("Tracepoint %d", tp->number);
445
446 if (addressprint || (tp->source_file == NULL))
447 {
448 printf_filtered (" at ");
449 deprecated_print_address_numeric (tp->address, 1, gdb_stdout);
450 }
451 if (tp->source_file)
452 printf_filtered (": file %s, line %d.",
453 tp->source_file, tp->line_number);
454
455 printf_filtered ("\n");
456 }
457
458 /* Print information on tracepoint number TPNUM_EXP, or all if
459 omitted. */
460
461 static void
tracepoints_info(char * tpnum_exp,int from_tty)462 tracepoints_info (char *tpnum_exp, int from_tty)
463 {
464 struct tracepoint *t;
465 struct action_line *action;
466 int found_a_tracepoint = 0;
467 char wrap_indent[80];
468 struct symbol *sym;
469 int tpnum = -1;
470
471 if (tpnum_exp)
472 tpnum = parse_and_eval_long (tpnum_exp);
473
474 ALL_TRACEPOINTS (t)
475 if (tpnum == -1 || tpnum == t->number)
476 {
477 extern int addressprint; /* Print machine addresses? */
478
479 if (!found_a_tracepoint++)
480 {
481 printf_filtered ("Num Enb ");
482 if (addressprint)
483 {
484 if (TARGET_ADDR_BIT <= 32)
485 printf_filtered ("Address ");
486 else
487 printf_filtered ("Address ");
488 }
489 printf_filtered ("PassC StepC What\n");
490 }
491 strcpy (wrap_indent, " ");
492 if (addressprint)
493 {
494 if (TARGET_ADDR_BIT <= 32)
495 strcat (wrap_indent, " ");
496 else
497 strcat (wrap_indent, " ");
498 }
499
500 printf_filtered ("%-3d %-3s ", t->number,
501 t->enabled_p ? "y" : "n");
502 if (addressprint)
503 {
504 char *tmp;
505
506 if (TARGET_ADDR_BIT <= 32)
507 tmp = hex_string_custom (t->address & (CORE_ADDR) 0xffffffff,
508 8);
509 else
510 tmp = hex_string_custom (t->address, 16);
511
512 printf_filtered ("%s ", tmp);
513 }
514 printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count);
515
516 if (t->source_file)
517 {
518 sym = find_pc_sect_function (t->address, t->section);
519 if (sym)
520 {
521 fputs_filtered ("in ", gdb_stdout);
522 fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout);
523 wrap_here (wrap_indent);
524 fputs_filtered (" at ", gdb_stdout);
525 }
526 fputs_filtered (t->source_file, gdb_stdout);
527 printf_filtered (":%d", t->line_number);
528 }
529 else
530 print_address_symbolic (t->address, gdb_stdout, demangle, " ");
531
532 printf_filtered ("\n");
533 if (t->actions)
534 {
535 printf_filtered (" Actions for tracepoint %d: \n", t->number);
536 for (action = t->actions; action; action = action->next)
537 {
538 printf_filtered ("\t%s\n", action->action);
539 }
540 }
541 }
542 if (!found_a_tracepoint)
543 {
544 if (tpnum == -1)
545 printf_filtered ("No tracepoints.\n");
546 else
547 printf_filtered ("No tracepoint number %d.\n", tpnum);
548 }
549 }
550
551 /* Optimization: the code to parse an enable, disable, or delete TP
552 command is virtually identical except for whether it performs an
553 enable, disable, or delete. Therefore I've combined them into one
554 function with an opcode. */
555 enum tracepoint_opcode
556 {
557 enable_op,
558 disable_op,
559 delete_op
560 };
561
562 /* This function implements enable, disable and delete commands. */
563 static void
tracepoint_operation(struct tracepoint * t,int from_tty,enum tracepoint_opcode opcode)564 tracepoint_operation (struct tracepoint *t, int from_tty,
565 enum tracepoint_opcode opcode)
566 {
567 struct tracepoint *t2;
568
569 if (t == NULL) /* no tracepoint operand */
570 return;
571
572 switch (opcode)
573 {
574 case enable_op:
575 t->enabled_p = 1;
576 tracepoint_modify_event (t->number);
577 break;
578 case disable_op:
579 t->enabled_p = 0;
580 tracepoint_modify_event (t->number);
581 break;
582 case delete_op:
583 if (tracepoint_chain == t)
584 tracepoint_chain = t->next;
585
586 ALL_TRACEPOINTS (t2)
587 if (t2->next == t)
588 {
589 tracepoint_delete_event (t2->number);
590 t2->next = t->next;
591 break;
592 }
593
594 if (t->addr_string)
595 xfree (t->addr_string);
596 if (t->source_file)
597 xfree (t->source_file);
598 if (t->actions)
599 free_actions (t);
600
601 xfree (t);
602 break;
603 }
604 }
605
606 /* Utility: parse a tracepoint number and look it up in the list.
607 If MULTI_P is true, there might be a range of tracepoints in ARG.
608 if OPTIONAL_P is true, then if the argument is missing, the most
609 recent tracepoint (tracepoint_count) is returned. */
610 struct tracepoint *
get_tracepoint_by_number(char ** arg,int multi_p,int optional_p)611 get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
612 {
613 struct tracepoint *t;
614 int tpnum;
615 char *instring = arg == NULL ? NULL : *arg;
616
617 if (arg == NULL || *arg == NULL || ! **arg)
618 {
619 if (optional_p)
620 tpnum = tracepoint_count;
621 else
622 error_no_arg (_("tracepoint number"));
623 }
624 else
625 tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
626
627 if (tpnum <= 0)
628 {
629 if (instring && *instring)
630 printf_filtered ("bad tracepoint number at or near '%s'\n",
631 instring);
632 else
633 printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
634 return NULL;
635 }
636
637 ALL_TRACEPOINTS (t)
638 if (t->number == tpnum)
639 {
640 return t;
641 }
642
643 /* FIXME: if we are in the middle of a range we don't want to give
644 a message. The current interface to get_number_or_range doesn't
645 allow us to discover this. */
646 printf_unfiltered ("No tracepoint number %d.\n", tpnum);
647 return NULL;
648 }
649
650 /* Utility:
651 parse a list of tracepoint numbers, and call a func for each. */
652 static void
map_args_over_tracepoints(char * args,int from_tty,enum tracepoint_opcode opcode)653 map_args_over_tracepoints (char *args, int from_tty,
654 enum tracepoint_opcode opcode)
655 {
656 struct tracepoint *t, *tmp;
657
658 if (args == 0 || *args == 0) /* do them all */
659 ALL_TRACEPOINTS_SAFE (t, tmp)
660 tracepoint_operation (t, from_tty, opcode);
661 else
662 while (*args)
663 {
664 QUIT; /* Give user option to bail out with ^C. */
665 t = get_tracepoint_by_number (&args, 1, 0);
666 tracepoint_operation (t, from_tty, opcode);
667 while (*args == ' ' || *args == '\t')
668 args++;
669 }
670 }
671
672 /* The 'enable trace' command enables tracepoints.
673 Not supported by all targets. */
674 static void
enable_trace_command(char * args,int from_tty)675 enable_trace_command (char *args, int from_tty)
676 {
677 dont_repeat ();
678 map_args_over_tracepoints (args, from_tty, enable_op);
679 }
680
681 /* The 'disable trace' command disables tracepoints.
682 Not supported by all targets. */
683 static void
disable_trace_command(char * args,int from_tty)684 disable_trace_command (char *args, int from_tty)
685 {
686 dont_repeat ();
687 map_args_over_tracepoints (args, from_tty, disable_op);
688 }
689
690 /* Remove a tracepoint (or all if no argument) */
691 static void
delete_trace_command(char * args,int from_tty)692 delete_trace_command (char *args, int from_tty)
693 {
694 dont_repeat ();
695 if (!args || !*args) /* No args implies all tracepoints; */
696 if (from_tty) /* confirm only if from_tty... */
697 if (tracepoint_chain) /* and if there are tracepoints to
698 delete! */
699 if (!query ("Delete all tracepoints? "))
700 return;
701
702 map_args_over_tracepoints (args, from_tty, delete_op);
703 }
704
705 /* Set passcount for tracepoint.
706
707 First command argument is passcount, second is tracepoint number.
708 If tracepoint number omitted, apply to most recently defined.
709 Also accepts special argument "all". */
710
711 static void
trace_pass_command(char * args,int from_tty)712 trace_pass_command (char *args, int from_tty)
713 {
714 struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
715 unsigned int count;
716 int all = 0;
717
718 if (args == 0 || *args == 0)
719 error (_("passcount command requires an argument (count + optional TP num)"));
720
721 count = strtoul (args, &args, 10); /* Count comes first, then TP num. */
722
723 while (*args && isspace ((int) *args))
724 args++;
725
726 if (*args && strncasecmp (args, "all", 3) == 0)
727 {
728 args += 3; /* Skip special argument "all". */
729 all = 1;
730 if (*args)
731 error (_("Junk at end of arguments."));
732 }
733 else
734 t1 = get_tracepoint_by_number (&args, 1, 1);
735
736 do
737 {
738 if (t1)
739 {
740 ALL_TRACEPOINTS (t2)
741 if (t1 == (struct tracepoint *) -1 || t1 == t2)
742 {
743 t2->pass_count = count;
744 tracepoint_modify_event (t2->number);
745 if (from_tty)
746 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
747 t2->number, count);
748 }
749 if (! all && *args)
750 t1 = get_tracepoint_by_number (&args, 1, 0);
751 }
752 }
753 while (*args);
754 }
755
756 /* ACTIONS functions: */
757
758 /* Prototypes for action-parsing utility commands */
759 static void read_actions (struct tracepoint *);
760
761 /* The three functions:
762 collect_pseudocommand,
763 while_stepping_pseudocommand, and
764 end_actions_pseudocommand
765 are placeholders for "commands" that are actually ONLY to be used
766 within a tracepoint action list. If the actual function is ever called,
767 it means that somebody issued the "command" at the top level,
768 which is always an error. */
769
770 static void
end_actions_pseudocommand(char * args,int from_tty)771 end_actions_pseudocommand (char *args, int from_tty)
772 {
773 error (_("This command cannot be used at the top level."));
774 }
775
776 static void
while_stepping_pseudocommand(char * args,int from_tty)777 while_stepping_pseudocommand (char *args, int from_tty)
778 {
779 error (_("This command can only be used in a tracepoint actions list."));
780 }
781
782 static void
collect_pseudocommand(char * args,int from_tty)783 collect_pseudocommand (char *args, int from_tty)
784 {
785 error (_("This command can only be used in a tracepoint actions list."));
786 }
787
788 /* Enter a list of actions for a tracepoint. */
789 static void
trace_actions_command(char * args,int from_tty)790 trace_actions_command (char *args, int from_tty)
791 {
792 struct tracepoint *t;
793 char tmpbuf[128];
794 char *end_msg = "End with a line saying just \"end\".";
795
796 t = get_tracepoint_by_number (&args, 0, 1);
797 if (t)
798 {
799 sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
800 t->number);
801
802 if (from_tty)
803 {
804 if (deprecated_readline_begin_hook)
805 (*deprecated_readline_begin_hook) ("%s %s\n", tmpbuf, end_msg);
806 else if (input_from_terminal_p ())
807 printf_filtered ("%s\n%s\n", tmpbuf, end_msg);
808 }
809
810 free_actions (t);
811 t->step_count = 0; /* read_actions may set this */
812 read_actions (t);
813
814 if (deprecated_readline_end_hook)
815 (*deprecated_readline_end_hook) ();
816 /* tracepoints_changed () */
817 }
818 /* else just return */
819 }
820
821 /* worker function */
822 static void
read_actions(struct tracepoint * t)823 read_actions (struct tracepoint *t)
824 {
825 char *line;
826 char *prompt1 = "> ", *prompt2 = " > ";
827 char *prompt = prompt1;
828 enum actionline_type linetype;
829 extern FILE *instream;
830 struct action_line *next = NULL, *temp;
831 struct cleanup *old_chain;
832
833 /* Control-C quits instantly if typed while in this loop
834 since it should not wait until the user types a newline. */
835 immediate_quit++;
836 /* FIXME: kettenis/20010823: Something is wrong here. In this file
837 STOP_SIGNAL is never defined. So this code has been left out, at
838 least for quite a while now. Replacing STOP_SIGNAL with SIGTSTP
839 leads to compilation failures since the variable job_control
840 isn't declared. Leave this alone for now. */
841 #ifdef STOP_SIGNAL
842 if (job_control)
843 signal (STOP_SIGNAL, handle_stop_sig);
844 #endif
845 old_chain = make_cleanup_free_actions (t);
846 while (1)
847 {
848 /* Make sure that all output has been output. Some machines may
849 let you get away with leaving out some of the gdb_flush, but
850 not all. */
851 wrap_here ("");
852 gdb_flush (gdb_stdout);
853 gdb_flush (gdb_stderr);
854
855 if (deprecated_readline_hook && instream == NULL)
856 line = (*deprecated_readline_hook) (prompt);
857 else if (instream == stdin && ISATTY (instream))
858 {
859 line = gdb_readline_wrapper (prompt);
860 if (line && *line) /* add it to command history */
861 add_history (line);
862 }
863 else
864 line = gdb_readline (0);
865
866 if (!line)
867 line = "end";
868
869 linetype = validate_actionline (&line, t);
870 if (linetype == BADLINE)
871 continue; /* already warned -- collect another line */
872
873 temp = xmalloc (sizeof (struct action_line));
874 temp->next = NULL;
875 temp->action = line;
876
877 if (next == NULL) /* first action for this tracepoint? */
878 t->actions = next = temp;
879 else
880 {
881 next->next = temp;
882 next = temp;
883 }
884
885 if (linetype == STEPPING) /* begin "while-stepping" */
886 {
887 if (prompt == prompt2)
888 {
889 warning (_("Already processing 'while-stepping'"));
890 continue;
891 }
892 else
893 prompt = prompt2; /* change prompt for stepping actions */
894 }
895 else if (linetype == END)
896 {
897 if (prompt == prompt2)
898 {
899 prompt = prompt1; /* end of single-stepping actions */
900 }
901 else
902 { /* end of actions */
903 if (t->actions->next == NULL)
904 {
905 /* An "end" all by itself with no other actions
906 means this tracepoint has no actions.
907 Discard empty list. */
908 free_actions (t);
909 }
910 break;
911 }
912 }
913 }
914 #ifdef STOP_SIGNAL
915 if (job_control)
916 signal (STOP_SIGNAL, SIG_DFL);
917 #endif
918 immediate_quit--;
919 discard_cleanups (old_chain);
920 }
921
922 /* worker function */
923 enum actionline_type
validate_actionline(char ** line,struct tracepoint * t)924 validate_actionline (char **line, struct tracepoint *t)
925 {
926 struct cmd_list_element *c;
927 struct expression *exp = NULL;
928 struct cleanup *old_chain = NULL;
929 char *p;
930
931 /* if EOF is typed, *line is NULL */
932 if (*line == NULL)
933 return END;
934
935 for (p = *line; isspace ((int) *p);)
936 p++;
937
938 /* Symbol lookup etc. */
939 if (*p == '\0') /* empty line: just prompt for another line. */
940 return BADLINE;
941
942 if (*p == '#') /* comment line */
943 return GENERIC;
944
945 c = lookup_cmd (&p, cmdlist, "", -1, 1);
946 if (c == 0)
947 {
948 warning (_("'%s' is not an action that I know, or is ambiguous."),
949 p);
950 return BADLINE;
951 }
952
953 if (cmd_cfunc_eq (c, collect_pseudocommand))
954 {
955 struct agent_expr *aexpr;
956 struct agent_reqs areqs;
957
958 do
959 { /* repeat over a comma-separated list */
960 QUIT; /* allow user to bail out with ^C */
961 while (isspace ((int) *p))
962 p++;
963
964 if (*p == '$') /* look for special pseudo-symbols */
965 {
966 if ((0 == strncasecmp ("reg", p + 1, 3)) ||
967 (0 == strncasecmp ("arg", p + 1, 3)) ||
968 (0 == strncasecmp ("loc", p + 1, 3)))
969 {
970 p = strchr (p, ',');
971 continue;
972 }
973 /* else fall thru, treat p as an expression and parse it! */
974 }
975 exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
976 old_chain = make_cleanup (free_current_contents, &exp);
977
978 if (exp->elts[0].opcode == OP_VAR_VALUE)
979 {
980 if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_CONST)
981 {
982 warning (_("constant %s (value %ld) will not be collected."),
983 DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol),
984 SYMBOL_VALUE (exp->elts[2].symbol));
985 return BADLINE;
986 }
987 else if (SYMBOL_CLASS (exp->elts[2].symbol) == LOC_OPTIMIZED_OUT)
988 {
989 warning (_("%s is optimized away and cannot be collected."),
990 DEPRECATED_SYMBOL_NAME (exp->elts[2].symbol));
991 return BADLINE;
992 }
993 }
994
995 /* We have something to collect, make sure that the expr to
996 bytecode translator can handle it and that it's not too
997 long. */
998 aexpr = gen_trace_for_expr (t->address, exp);
999 make_cleanup_free_agent_expr (aexpr);
1000
1001 if (aexpr->len > MAX_AGENT_EXPR_LEN)
1002 error (_("expression too complicated, try simplifying"));
1003
1004 ax_reqs (aexpr, &areqs);
1005 (void) make_cleanup (xfree, areqs.reg_mask);
1006
1007 if (areqs.flaw != agent_flaw_none)
1008 error (_("malformed expression"));
1009
1010 if (areqs.min_height < 0)
1011 error (_("gdb: Internal error: expression has min height < 0"));
1012
1013 if (areqs.max_height > 20)
1014 error (_("expression too complicated, try simplifying"));
1015
1016 do_cleanups (old_chain);
1017 }
1018 while (p && *p++ == ',');
1019 return GENERIC;
1020 }
1021 else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
1022 {
1023 char *steparg; /* in case warning is necessary */
1024
1025 while (isspace ((int) *p))
1026 p++;
1027 steparg = p;
1028
1029 if (*p == '\0' ||
1030 (t->step_count = strtol (p, &p, 0)) == 0)
1031 {
1032 warning (_("'%s': bad step-count; command ignored."), *line);
1033 return BADLINE;
1034 }
1035 return STEPPING;
1036 }
1037 else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
1038 return END;
1039 else
1040 {
1041 warning (_("'%s' is not a supported tracepoint action."), *line);
1042 return BADLINE;
1043 }
1044 }
1045
1046 /* worker function */
1047 void
free_actions(struct tracepoint * t)1048 free_actions (struct tracepoint *t)
1049 {
1050 struct action_line *line, *next;
1051
1052 for (line = t->actions; line; line = next)
1053 {
1054 next = line->next;
1055 if (line->action)
1056 xfree (line->action);
1057 xfree (line);
1058 }
1059 t->actions = NULL;
1060 }
1061
1062 static void
do_free_actions_cleanup(void * t)1063 do_free_actions_cleanup (void *t)
1064 {
1065 free_actions (t);
1066 }
1067
1068 static struct cleanup *
make_cleanup_free_actions(struct tracepoint * t)1069 make_cleanup_free_actions (struct tracepoint *t)
1070 {
1071 return make_cleanup (do_free_actions_cleanup, t);
1072 }
1073
1074 struct memrange
1075 {
1076 int type; /* 0 for absolute memory range, else basereg number */
1077 bfd_signed_vma start;
1078 bfd_signed_vma end;
1079 };
1080
1081 struct collection_list
1082 {
1083 unsigned char regs_mask[32]; /* room for up to 256 regs */
1084 long listsize;
1085 long next_memrange;
1086 struct memrange *list;
1087 long aexpr_listsize; /* size of array pointed to by expr_list elt */
1088 long next_aexpr_elt;
1089 struct agent_expr **aexpr_list;
1090
1091 }
1092 tracepoint_list, stepping_list;
1093
1094 /* MEMRANGE functions: */
1095
1096 static int memrange_cmp (const void *, const void *);
1097
1098 /* compare memranges for qsort */
1099 static int
memrange_cmp(const void * va,const void * vb)1100 memrange_cmp (const void *va, const void *vb)
1101 {
1102 const struct memrange *a = va, *b = vb;
1103
1104 if (a->type < b->type)
1105 return -1;
1106 if (a->type > b->type)
1107 return 1;
1108 if (a->type == 0)
1109 {
1110 if ((bfd_vma) a->start < (bfd_vma) b->start)
1111 return -1;
1112 if ((bfd_vma) a->start > (bfd_vma) b->start)
1113 return 1;
1114 }
1115 else
1116 {
1117 if (a->start < b->start)
1118 return -1;
1119 if (a->start > b->start)
1120 return 1;
1121 }
1122 return 0;
1123 }
1124
1125 /* Sort the memrange list using qsort, and merge adjacent memranges. */
1126 static void
memrange_sortmerge(struct collection_list * memranges)1127 memrange_sortmerge (struct collection_list *memranges)
1128 {
1129 int a, b;
1130
1131 qsort (memranges->list, memranges->next_memrange,
1132 sizeof (struct memrange), memrange_cmp);
1133 if (memranges->next_memrange > 0)
1134 {
1135 for (a = 0, b = 1; b < memranges->next_memrange; b++)
1136 {
1137 if (memranges->list[a].type == memranges->list[b].type &&
1138 memranges->list[b].start - memranges->list[a].end <=
1139 MAX_REGISTER_SIZE)
1140 {
1141 /* memrange b starts before memrange a ends; merge them. */
1142 if (memranges->list[b].end > memranges->list[a].end)
1143 memranges->list[a].end = memranges->list[b].end;
1144 continue; /* next b, same a */
1145 }
1146 a++; /* next a */
1147 if (a != b)
1148 memcpy (&memranges->list[a], &memranges->list[b],
1149 sizeof (struct memrange));
1150 }
1151 memranges->next_memrange = a + 1;
1152 }
1153 }
1154
1155 /* Add a register to a collection list. */
1156 static void
add_register(struct collection_list * collection,unsigned int regno)1157 add_register (struct collection_list *collection, unsigned int regno)
1158 {
1159 if (info_verbose)
1160 printf_filtered ("collect register %d\n", regno);
1161 if (regno > (8 * sizeof (collection->regs_mask)))
1162 error (_("Internal: register number %d too large for tracepoint"),
1163 regno);
1164 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
1165 }
1166
1167 /* Add a memrange to a collection list */
1168 static void
add_memrange(struct collection_list * memranges,int type,bfd_signed_vma base,unsigned long len)1169 add_memrange (struct collection_list *memranges,
1170 int type, bfd_signed_vma base,
1171 unsigned long len)
1172 {
1173 if (info_verbose)
1174 {
1175 printf_filtered ("(%d,", type);
1176 printf_vma (base);
1177 printf_filtered (",%ld)\n", len);
1178 }
1179
1180 /* type: -1 == memory, n == basereg */
1181 memranges->list[memranges->next_memrange].type = type;
1182 /* base: addr if memory, offset if reg relative. */
1183 memranges->list[memranges->next_memrange].start = base;
1184 /* len: we actually save end (base + len) for convenience */
1185 memranges->list[memranges->next_memrange].end = base + len;
1186 memranges->next_memrange++;
1187 if (memranges->next_memrange >= memranges->listsize)
1188 {
1189 memranges->listsize *= 2;
1190 memranges->list = xrealloc (memranges->list,
1191 memranges->listsize);
1192 }
1193
1194 if (type != -1) /* Better collect the base register! */
1195 add_register (memranges, type);
1196 }
1197
1198 /* Add a symbol to a collection list. */
1199 static void
collect_symbol(struct collection_list * collect,struct symbol * sym,long frame_regno,long frame_offset)1200 collect_symbol (struct collection_list *collect,
1201 struct symbol *sym,
1202 long frame_regno, long frame_offset)
1203 {
1204 unsigned long len;
1205 unsigned int reg;
1206 bfd_signed_vma offset;
1207
1208 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1209 switch (SYMBOL_CLASS (sym))
1210 {
1211 default:
1212 printf_filtered ("%s: don't know symbol class %d\n",
1213 DEPRECATED_SYMBOL_NAME (sym),
1214 SYMBOL_CLASS (sym));
1215 break;
1216 case LOC_CONST:
1217 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1218 DEPRECATED_SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1219 break;
1220 case LOC_STATIC:
1221 offset = SYMBOL_VALUE_ADDRESS (sym);
1222 if (info_verbose)
1223 {
1224 char tmp[40];
1225
1226 sprintf_vma (tmp, offset);
1227 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1228 DEPRECATED_SYMBOL_NAME (sym), len,
1229 tmp /* address */);
1230 }
1231 add_memrange (collect, -1, offset, len); /* 0 == memory */
1232 break;
1233 case LOC_REGISTER:
1234 case LOC_REGPARM:
1235 reg = SYMBOL_VALUE (sym);
1236 if (info_verbose)
1237 printf_filtered ("LOC_REG[parm] %s: ",
1238 DEPRECATED_SYMBOL_NAME (sym));
1239 add_register (collect, reg);
1240 /* Check for doubles stored in two registers. */
1241 /* FIXME: how about larger types stored in 3 or more regs? */
1242 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
1243 len > register_size (current_gdbarch, reg))
1244 add_register (collect, reg + 1);
1245 break;
1246 case LOC_REF_ARG:
1247 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1248 printf_filtered (" (will not collect %s)\n",
1249 DEPRECATED_SYMBOL_NAME (sym));
1250 break;
1251 case LOC_ARG:
1252 reg = frame_regno;
1253 offset = frame_offset + SYMBOL_VALUE (sym);
1254 if (info_verbose)
1255 {
1256 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1257 DEPRECATED_SYMBOL_NAME (sym), len);
1258 printf_vma (offset);
1259 printf_filtered (" from frame ptr reg %d\n", reg);
1260 }
1261 add_memrange (collect, reg, offset, len);
1262 break;
1263 case LOC_REGPARM_ADDR:
1264 reg = SYMBOL_VALUE (sym);
1265 offset = 0;
1266 if (info_verbose)
1267 {
1268 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1269 DEPRECATED_SYMBOL_NAME (sym), len);
1270 printf_vma (offset);
1271 printf_filtered (" from reg %d\n", reg);
1272 }
1273 add_memrange (collect, reg, offset, len);
1274 break;
1275 case LOC_LOCAL:
1276 case LOC_LOCAL_ARG:
1277 reg = frame_regno;
1278 offset = frame_offset + SYMBOL_VALUE (sym);
1279 if (info_verbose)
1280 {
1281 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1282 DEPRECATED_SYMBOL_NAME (sym), len);
1283 printf_vma (offset);
1284 printf_filtered (" from frame ptr reg %d\n", reg);
1285 }
1286 add_memrange (collect, reg, offset, len);
1287 break;
1288 case LOC_BASEREG:
1289 case LOC_BASEREG_ARG:
1290 reg = SYMBOL_BASEREG (sym);
1291 offset = SYMBOL_VALUE (sym);
1292 if (info_verbose)
1293 {
1294 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1295 DEPRECATED_SYMBOL_NAME (sym), len);
1296 printf_vma (offset);
1297 printf_filtered (" from basereg %d\n", reg);
1298 }
1299 add_memrange (collect, reg, offset, len);
1300 break;
1301 case LOC_UNRESOLVED:
1302 printf_filtered ("Don't know LOC_UNRESOLVED %s\n",
1303 DEPRECATED_SYMBOL_NAME (sym));
1304 break;
1305 case LOC_OPTIMIZED_OUT:
1306 printf_filtered ("%s has been optimized out of existence.\n",
1307 DEPRECATED_SYMBOL_NAME (sym));
1308 break;
1309 }
1310 }
1311
1312 /* Add all locals (or args) symbols to collection list */
1313 static void
add_local_symbols(struct collection_list * collect,CORE_ADDR pc,long frame_regno,long frame_offset,int type)1314 add_local_symbols (struct collection_list *collect, CORE_ADDR pc,
1315 long frame_regno, long frame_offset, int type)
1316 {
1317 struct symbol *sym;
1318 struct block *block;
1319 struct dict_iterator iter;
1320 int count = 0;
1321
1322 block = block_for_pc (pc);
1323 while (block != 0)
1324 {
1325 QUIT; /* allow user to bail out with ^C */
1326 ALL_BLOCK_SYMBOLS (block, iter, sym)
1327 {
1328 switch (SYMBOL_CLASS (sym))
1329 {
1330 default:
1331 warning (_("don't know how to trace local symbol %s"),
1332 DEPRECATED_SYMBOL_NAME (sym));
1333 case LOC_LOCAL:
1334 case LOC_STATIC:
1335 case LOC_REGISTER:
1336 case LOC_BASEREG:
1337 if (type == 'L') /* collecting Locals */
1338 {
1339 count++;
1340 collect_symbol (collect, sym, frame_regno,
1341 frame_offset);
1342 }
1343 break;
1344 case LOC_ARG:
1345 case LOC_LOCAL_ARG:
1346 case LOC_REF_ARG:
1347 case LOC_REGPARM:
1348 case LOC_REGPARM_ADDR:
1349 case LOC_BASEREG_ARG:
1350 if (type == 'A') /* collecting Arguments */
1351 {
1352 count++;
1353 collect_symbol (collect, sym, frame_regno,
1354 frame_offset);
1355 }
1356 }
1357 }
1358 if (BLOCK_FUNCTION (block))
1359 break;
1360 else
1361 block = BLOCK_SUPERBLOCK (block);
1362 }
1363 if (count == 0)
1364 warning (_("No %s found in scope."),
1365 type == 'L' ? "locals" : "args");
1366 }
1367
1368 /* worker function */
1369 static void
clear_collection_list(struct collection_list * list)1370 clear_collection_list (struct collection_list *list)
1371 {
1372 int ndx;
1373
1374 list->next_memrange = 0;
1375 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1376 {
1377 free_agent_expr (list->aexpr_list[ndx]);
1378 list->aexpr_list[ndx] = NULL;
1379 }
1380 list->next_aexpr_elt = 0;
1381 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1382 }
1383
1384 /* reduce a collection list to string form (for gdb protocol) */
1385 static char **
stringify_collection_list(struct collection_list * list,char * string)1386 stringify_collection_list (struct collection_list *list, char *string)
1387 {
1388 char temp_buf[2048];
1389 char tmp2[40];
1390 int count;
1391 int ndx = 0;
1392 char *(*str_list)[];
1393 char *end;
1394 long i;
1395
1396 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
1397 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
1398
1399 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1400 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1401 break;
1402 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1403 {
1404 if (info_verbose)
1405 printf_filtered ("\nCollecting registers (mask): 0x");
1406 end = temp_buf;
1407 *end++ = 'R';
1408 for (; i >= 0; i--)
1409 {
1410 QUIT; /* allow user to bail out with ^C */
1411 if (info_verbose)
1412 printf_filtered ("%02X", list->regs_mask[i]);
1413 sprintf (end, "%02X", list->regs_mask[i]);
1414 end += 2;
1415 }
1416 (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
1417 ndx++;
1418 }
1419 if (info_verbose)
1420 printf_filtered ("\n");
1421 if (list->next_memrange > 0 && info_verbose)
1422 printf_filtered ("Collecting memranges: \n");
1423 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1424 {
1425 QUIT; /* allow user to bail out with ^C */
1426 sprintf_vma (tmp2, list->list[i].start);
1427 if (info_verbose)
1428 {
1429 printf_filtered ("(%d, %s, %ld)\n",
1430 list->list[i].type,
1431 tmp2,
1432 (long) (list->list[i].end - list->list[i].start));
1433 }
1434 if (count + 27 > MAX_AGENT_EXPR_LEN)
1435 {
1436 (*str_list)[ndx] = savestring (temp_buf, count);
1437 ndx++;
1438 count = 0;
1439 end = temp_buf;
1440 }
1441
1442 sprintf (end, "M%X,%s,%lX",
1443 list->list[i].type,
1444 tmp2,
1445 (long) (list->list[i].end - list->list[i].start));
1446
1447 count += strlen (end);
1448 end += count;
1449 }
1450
1451 for (i = 0; i < list->next_aexpr_elt; i++)
1452 {
1453 QUIT; /* allow user to bail out with ^C */
1454 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1455 {
1456 (*str_list)[ndx] = savestring (temp_buf, count);
1457 ndx++;
1458 count = 0;
1459 end = temp_buf;
1460 }
1461 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1462 end += 10; /* 'X' + 8 hex digits + ',' */
1463 count += 10;
1464
1465 end = mem2hex (list->aexpr_list[i]->buf,
1466 end, list->aexpr_list[i]->len);
1467 count += 2 * list->aexpr_list[i]->len;
1468 }
1469
1470 if (count != 0)
1471 {
1472 (*str_list)[ndx] = savestring (temp_buf, count);
1473 ndx++;
1474 count = 0;
1475 end = temp_buf;
1476 }
1477 (*str_list)[ndx] = NULL;
1478
1479 if (ndx == 0)
1480 return NULL;
1481 else
1482 return *str_list;
1483 }
1484
1485 static void
free_actions_list_cleanup_wrapper(void * al)1486 free_actions_list_cleanup_wrapper (void *al)
1487 {
1488 free_actions_list (al);
1489 }
1490
1491 static void
free_actions_list(char ** actions_list)1492 free_actions_list (char **actions_list)
1493 {
1494 int ndx;
1495
1496 if (actions_list == 0)
1497 return;
1498
1499 for (ndx = 0; actions_list[ndx]; ndx++)
1500 xfree (actions_list[ndx]);
1501
1502 xfree (actions_list);
1503 }
1504
1505 /* Render all actions into gdb protocol. */
1506 static void
encode_actions(struct tracepoint * t,char *** tdp_actions,char *** stepping_actions)1507 encode_actions (struct tracepoint *t, char ***tdp_actions,
1508 char ***stepping_actions)
1509 {
1510 static char tdp_buff[2048], step_buff[2048];
1511 char *action_exp;
1512 struct expression *exp = NULL;
1513 struct action_line *action;
1514 int i;
1515 struct value *tempval;
1516 struct collection_list *collect;
1517 struct cmd_list_element *cmd;
1518 struct agent_expr *aexpr;
1519 int frame_reg;
1520 LONGEST frame_offset;
1521
1522
1523 clear_collection_list (&tracepoint_list);
1524 clear_collection_list (&stepping_list);
1525 collect = &tracepoint_list;
1526
1527 *tdp_actions = NULL;
1528 *stepping_actions = NULL;
1529
1530 TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
1531
1532 for (action = t->actions; action; action = action->next)
1533 {
1534 QUIT; /* allow user to bail out with ^C */
1535 action_exp = action->action;
1536 while (isspace ((int) *action_exp))
1537 action_exp++;
1538
1539 if (*action_exp == '#') /* comment line */
1540 return;
1541
1542 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1543 if (cmd == 0)
1544 error (_("Bad action list item: %s"), action_exp);
1545
1546 if (cmd_cfunc_eq (cmd, collect_pseudocommand))
1547 {
1548 do
1549 { /* repeat over a comma-separated list */
1550 QUIT; /* allow user to bail out with ^C */
1551 while (isspace ((int) *action_exp))
1552 action_exp++;
1553
1554 if (0 == strncasecmp ("$reg", action_exp, 4))
1555 {
1556 for (i = 0; i < NUM_REGS; i++)
1557 add_register (collect, i);
1558 action_exp = strchr (action_exp, ','); /* more? */
1559 }
1560 else if (0 == strncasecmp ("$arg", action_exp, 4))
1561 {
1562 add_local_symbols (collect,
1563 t->address,
1564 frame_reg,
1565 frame_offset,
1566 'A');
1567 action_exp = strchr (action_exp, ','); /* more? */
1568 }
1569 else if (0 == strncasecmp ("$loc", action_exp, 4))
1570 {
1571 add_local_symbols (collect,
1572 t->address,
1573 frame_reg,
1574 frame_offset,
1575 'L');
1576 action_exp = strchr (action_exp, ','); /* more? */
1577 }
1578 else
1579 {
1580 unsigned long addr, len;
1581 struct cleanup *old_chain = NULL;
1582 struct cleanup *old_chain1 = NULL;
1583 struct agent_reqs areqs;
1584
1585 exp = parse_exp_1 (&action_exp,
1586 block_for_pc (t->address), 1);
1587 old_chain = make_cleanup (free_current_contents, &exp);
1588
1589 switch (exp->elts[0].opcode)
1590 {
1591 case OP_REGISTER:
1592 i = exp->elts[1].longconst;
1593 if (info_verbose)
1594 printf_filtered ("OP_REGISTER: ");
1595 add_register (collect, i);
1596 break;
1597
1598 case UNOP_MEMVAL:
1599 /* safe because we know it's a simple expression */
1600 tempval = evaluate_expression (exp);
1601 addr = VALUE_ADDRESS (tempval) + value_offset (tempval);
1602 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1603 add_memrange (collect, -1, addr, len);
1604 break;
1605
1606 case OP_VAR_VALUE:
1607 collect_symbol (collect,
1608 exp->elts[2].symbol,
1609 frame_reg,
1610 frame_offset);
1611 break;
1612
1613 default: /* full-fledged expression */
1614 aexpr = gen_trace_for_expr (t->address, exp);
1615
1616 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1617
1618 ax_reqs (aexpr, &areqs);
1619 if (areqs.flaw != agent_flaw_none)
1620 error (_("malformed expression"));
1621
1622 if (areqs.min_height < 0)
1623 error (_("gdb: Internal error: expression has min height < 0"));
1624 if (areqs.max_height > 20)
1625 error (_("expression too complicated, try simplifying"));
1626
1627 discard_cleanups (old_chain1);
1628 add_aexpr (collect, aexpr);
1629
1630 /* take care of the registers */
1631 if (areqs.reg_mask_len > 0)
1632 {
1633 int ndx1;
1634 int ndx2;
1635
1636 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1637 {
1638 QUIT; /* allow user to bail out with ^C */
1639 if (areqs.reg_mask[ndx1] != 0)
1640 {
1641 /* assume chars have 8 bits */
1642 for (ndx2 = 0; ndx2 < 8; ndx2++)
1643 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1644 /* it's used -- record it */
1645 add_register (collect,
1646 ndx1 * 8 + ndx2);
1647 }
1648 }
1649 }
1650 break;
1651 } /* switch */
1652 do_cleanups (old_chain);
1653 } /* do */
1654 }
1655 while (action_exp && *action_exp++ == ',');
1656 } /* if */
1657 else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
1658 {
1659 collect = &stepping_list;
1660 }
1661 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
1662 {
1663 if (collect == &stepping_list) /* end stepping actions */
1664 collect = &tracepoint_list;
1665 else
1666 break; /* end tracepoint actions */
1667 }
1668 } /* for */
1669 memrange_sortmerge (&tracepoint_list);
1670 memrange_sortmerge (&stepping_list);
1671
1672 *tdp_actions = stringify_collection_list (&tracepoint_list,
1673 tdp_buff);
1674 *stepping_actions = stringify_collection_list (&stepping_list,
1675 step_buff);
1676 }
1677
1678 static void
add_aexpr(struct collection_list * collect,struct agent_expr * aexpr)1679 add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
1680 {
1681 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1682 {
1683 collect->aexpr_list =
1684 xrealloc (collect->aexpr_list,
1685 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
1686 collect->aexpr_listsize *= 2;
1687 }
1688 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1689 collect->next_aexpr_elt++;
1690 }
1691
1692 static char target_buf[2048];
1693
1694 /* Set "transparent" memory ranges
1695
1696 Allow trace mechanism to treat text-like sections
1697 (and perhaps all read-only sections) transparently,
1698 i.e. don't reject memory requests from these address ranges
1699 just because they haven't been collected. */
1700
1701 static void
remote_set_transparent_ranges(void)1702 remote_set_transparent_ranges (void)
1703 {
1704 extern bfd *exec_bfd;
1705 asection *s;
1706 bfd_size_type size;
1707 bfd_vma lma;
1708 int anysecs = 0;
1709
1710 if (!exec_bfd)
1711 return; /* No information to give. */
1712
1713 strcpy (target_buf, "QTro");
1714 for (s = exec_bfd->sections; s; s = s->next)
1715 {
1716 char tmp1[40], tmp2[40];
1717
1718 if ((s->flags & SEC_LOAD) == 0 ||
1719 /* (s->flags & SEC_CODE) == 0 || */
1720 (s->flags & SEC_READONLY) == 0)
1721 continue;
1722
1723 anysecs = 1;
1724 lma = s->lma;
1725 size = bfd_get_section_size (s);
1726 sprintf_vma (tmp1, lma);
1727 sprintf_vma (tmp2, lma + size);
1728 sprintf (target_buf + strlen (target_buf),
1729 ":%s,%s", tmp1, tmp2);
1730 }
1731 if (anysecs)
1732 {
1733 putpkt (target_buf);
1734 getpkt (target_buf, sizeof (target_buf), 0);
1735 }
1736 }
1737
1738 /* tstart command:
1739
1740 Tell target to clear any previous trace experiment.
1741 Walk the list of tracepoints, and send them (and their actions)
1742 to the target. If no errors,
1743 Tell target to start a new trace experiment. */
1744
1745 static void
trace_start_command(char * args,int from_tty)1746 trace_start_command (char *args, int from_tty)
1747 {
1748 struct tracepoint *t;
1749 char buf[2048];
1750 char **tdp_actions;
1751 char **stepping_actions;
1752 int ndx;
1753 struct cleanup *old_chain = NULL;
1754
1755 dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
1756
1757 if (target_is_remote ())
1758 {
1759 putpkt ("QTinit");
1760 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1761 if (strcmp (target_buf, "OK"))
1762 error (_("Target does not support this command."));
1763
1764 ALL_TRACEPOINTS (t)
1765 {
1766 char tmp[40];
1767
1768 sprintf_vma (tmp, t->address);
1769 sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
1770 tmp, /* address */
1771 t->enabled_p ? 'E' : 'D',
1772 t->step_count, t->pass_count);
1773
1774 if (t->actions)
1775 strcat (buf, "-");
1776 putpkt (buf);
1777 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1778 if (strcmp (target_buf, "OK"))
1779 error (_("Target does not support tracepoints."));
1780
1781 if (t->actions)
1782 {
1783 encode_actions (t, &tdp_actions, &stepping_actions);
1784 old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
1785 tdp_actions);
1786 (void) make_cleanup (free_actions_list_cleanup_wrapper,
1787 stepping_actions);
1788
1789 /* do_single_steps (t); */
1790 if (tdp_actions)
1791 {
1792 for (ndx = 0; tdp_actions[ndx]; ndx++)
1793 {
1794 QUIT; /* allow user to bail out with ^C */
1795 sprintf (buf, "QTDP:-%x:%s:%s%c",
1796 t->number, tmp, /* address */
1797 tdp_actions[ndx],
1798 ((tdp_actions[ndx + 1] || stepping_actions)
1799 ? '-' : 0));
1800 putpkt (buf);
1801 remote_get_noisy_reply (target_buf,
1802 sizeof (target_buf));
1803 if (strcmp (target_buf, "OK"))
1804 error (_("Error on target while setting tracepoints."));
1805 }
1806 }
1807 if (stepping_actions)
1808 {
1809 for (ndx = 0; stepping_actions[ndx]; ndx++)
1810 {
1811 QUIT; /* allow user to bail out with ^C */
1812 sprintf (buf, "QTDP:-%x:%s:%s%s%s",
1813 t->number, tmp, /* address */
1814 ((ndx == 0) ? "S" : ""),
1815 stepping_actions[ndx],
1816 (stepping_actions[ndx + 1] ? "-" : ""));
1817 putpkt (buf);
1818 remote_get_noisy_reply (target_buf,
1819 sizeof (target_buf));
1820 if (strcmp (target_buf, "OK"))
1821 error (_("Error on target while setting tracepoints."));
1822 }
1823 }
1824
1825 do_cleanups (old_chain);
1826 }
1827 }
1828 /* Tell target to treat text-like sections as transparent. */
1829 remote_set_transparent_ranges ();
1830 /* Now insert traps and begin collecting data. */
1831 putpkt ("QTStart");
1832 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1833 if (strcmp (target_buf, "OK"))
1834 error (_("Bogus reply from target: %s"), target_buf);
1835 set_traceframe_num (-1); /* All old traceframes invalidated. */
1836 set_tracepoint_num (-1);
1837 set_traceframe_context (-1);
1838 trace_running_p = 1;
1839 if (deprecated_trace_start_stop_hook)
1840 deprecated_trace_start_stop_hook (1, from_tty);
1841
1842 }
1843 else
1844 error (_("Trace can only be run on remote targets."));
1845 }
1846
1847 /* tstop command */
1848 static void
trace_stop_command(char * args,int from_tty)1849 trace_stop_command (char *args, int from_tty)
1850 {
1851 if (target_is_remote ())
1852 {
1853 putpkt ("QTStop");
1854 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1855 if (strcmp (target_buf, "OK"))
1856 error (_("Bogus reply from target: %s"), target_buf);
1857 trace_running_p = 0;
1858 if (deprecated_trace_start_stop_hook)
1859 deprecated_trace_start_stop_hook (0, from_tty);
1860 }
1861 else
1862 error (_("Trace can only be run on remote targets."));
1863 }
1864
1865 unsigned long trace_running_p;
1866
1867 /* tstatus command */
1868 static void
trace_status_command(char * args,int from_tty)1869 trace_status_command (char *args, int from_tty)
1870 {
1871 if (target_is_remote ())
1872 {
1873 putpkt ("qTStatus");
1874 remote_get_noisy_reply (target_buf, sizeof (target_buf));
1875
1876 if (target_buf[0] != 'T' ||
1877 (target_buf[1] != '0' && target_buf[1] != '1'))
1878 error (_("Bogus reply from target: %s"), target_buf);
1879
1880 /* exported for use by the GUI */
1881 trace_running_p = (target_buf[1] == '1');
1882 }
1883 else
1884 error (_("Trace can only be run on remote targets."));
1885 }
1886
1887 /* Worker function for the various flavors of the tfind command. */
1888 static void
finish_tfind_command(char * msg,long sizeof_msg,int from_tty)1889 finish_tfind_command (char *msg,
1890 long sizeof_msg,
1891 int from_tty)
1892 {
1893 int target_frameno = -1, target_tracept = -1;
1894 CORE_ADDR old_frame_addr;
1895 struct symbol *old_func;
1896 char *reply;
1897
1898 old_frame_addr = get_frame_base (get_current_frame ());
1899 old_func = find_pc_function (read_pc ());
1900
1901 putpkt (msg);
1902 reply = remote_get_noisy_reply (msg, sizeof_msg);
1903
1904 while (reply && *reply)
1905 switch (*reply)
1906 {
1907 case 'F':
1908 if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
1909 {
1910 /* A request for a non-existant trace frame has failed.
1911 Our response will be different, depending on FROM_TTY:
1912
1913 If FROM_TTY is true, meaning that this command was
1914 typed interactively by the user, then give an error
1915 and DO NOT change the state of traceframe_number etc.
1916
1917 However if FROM_TTY is false, meaning that we're either
1918 in a script, a loop, or a user-defined command, then
1919 DON'T give an error, but DO change the state of
1920 traceframe_number etc. to invalid.
1921
1922 The rationalle is that if you typed the command, you
1923 might just have committed a typo or something, and you'd
1924 like to NOT lose your current debugging state. However
1925 if you're in a user-defined command or especially in a
1926 loop, then you need a way to detect that the command
1927 failed WITHOUT aborting. This allows you to write
1928 scripts that search thru the trace buffer until the end,
1929 and then continue on to do something else. */
1930
1931 if (from_tty)
1932 error (_("Target failed to find requested trace frame."));
1933 else
1934 {
1935 if (info_verbose)
1936 printf_filtered ("End of trace buffer.\n");
1937 /* The following will not recurse, since it's
1938 special-cased. */
1939 trace_find_command ("-1", from_tty);
1940 reply = NULL; /* Break out of loop
1941 (avoid recursive nonsense). */
1942 }
1943 }
1944 break;
1945 case 'T':
1946 if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
1947 error (_("Target failed to find requested trace frame."));
1948 break;
1949 case 'O': /* "OK"? */
1950 if (reply[1] == 'K' && reply[2] == '\0')
1951 reply += 2;
1952 else
1953 error (_("Bogus reply from target: %s"), reply);
1954 break;
1955 default:
1956 error (_("Bogus reply from target: %s"), reply);
1957 }
1958
1959 flush_cached_frames ();
1960 registers_changed ();
1961 select_frame (get_current_frame ());
1962 set_traceframe_num (target_frameno);
1963 set_tracepoint_num (target_tracept);
1964 if (target_frameno == -1)
1965 set_traceframe_context (-1);
1966 else
1967 set_traceframe_context (read_pc ());
1968
1969 if (from_tty)
1970 {
1971 enum print_what print_what;
1972
1973 /* NOTE: in immitation of the step command, try to determine
1974 whether we have made a transition from one function to
1975 another. If so, we'll print the "stack frame" (ie. the new
1976 function and it's arguments) -- otherwise we'll just show the
1977 new source line.
1978
1979 This determination is made by checking (1) whether the
1980 current function has changed, and (2) whether the current FP
1981 has changed. Hack: if the FP wasn't collected, either at the
1982 current or the previous frame, assume that the FP has NOT
1983 changed. */
1984
1985 if (old_func == find_pc_function (read_pc ()) &&
1986 (old_frame_addr == 0 ||
1987 get_frame_base (get_current_frame ()) == 0 ||
1988 old_frame_addr == get_frame_base (get_current_frame ())))
1989 print_what = SRC_LINE;
1990 else
1991 print_what = SRC_AND_LOC;
1992
1993 print_stack_frame (get_selected_frame (NULL), 1, print_what);
1994 do_displays ();
1995 }
1996 }
1997
1998 /* trace_find_command takes a trace frame number n,
1999 sends "QTFrame:<n>" to the target,
2000 and accepts a reply that may contain several optional pieces
2001 of information: a frame number, a tracepoint number, and an
2002 indication of whether this is a trap frame or a stepping frame.
2003
2004 The minimal response is just "OK" (which indicates that the
2005 target does not give us a frame number or a tracepoint number).
2006 Instead of that, the target may send us a string containing
2007 any combination of:
2008 F<hexnum> (gives the selected frame number)
2009 T<hexnum> (gives the selected tracepoint number)
2010 */
2011
2012 /* tfind command */
2013 static void
trace_find_command(char * args,int from_tty)2014 trace_find_command (char *args, int from_tty)
2015 { /* this should only be called with a numeric argument */
2016 int frameno = -1;
2017
2018 if (target_is_remote ())
2019 {
2020 if (deprecated_trace_find_hook)
2021 deprecated_trace_find_hook (args, from_tty);
2022
2023 if (args == 0 || *args == 0)
2024 { /* TFIND with no args means find NEXT trace frame. */
2025 if (traceframe_number == -1)
2026 frameno = 0; /* "next" is first one */
2027 else
2028 frameno = traceframe_number + 1;
2029 }
2030 else if (0 == strcmp (args, "-"))
2031 {
2032 if (traceframe_number == -1)
2033 error (_("not debugging trace buffer"));
2034 else if (from_tty && traceframe_number == 0)
2035 error (_("already at start of trace buffer"));
2036
2037 frameno = traceframe_number - 1;
2038 }
2039 else
2040 frameno = parse_and_eval_long (args);
2041
2042 if (frameno < -1)
2043 error (_("invalid input (%d is less than zero)"), frameno);
2044
2045 sprintf (target_buf, "QTFrame:%x", frameno);
2046 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2047 }
2048 else
2049 error (_("Trace can only be run on remote targets."));
2050 }
2051
2052 /* tfind end */
2053 static void
trace_find_end_command(char * args,int from_tty)2054 trace_find_end_command (char *args, int from_tty)
2055 {
2056 trace_find_command ("-1", from_tty);
2057 }
2058
2059 /* tfind none */
2060 static void
trace_find_none_command(char * args,int from_tty)2061 trace_find_none_command (char *args, int from_tty)
2062 {
2063 trace_find_command ("-1", from_tty);
2064 }
2065
2066 /* tfind start */
2067 static void
trace_find_start_command(char * args,int from_tty)2068 trace_find_start_command (char *args, int from_tty)
2069 {
2070 trace_find_command ("0", from_tty);
2071 }
2072
2073 /* tfind pc command */
2074 static void
trace_find_pc_command(char * args,int from_tty)2075 trace_find_pc_command (char *args, int from_tty)
2076 {
2077 CORE_ADDR pc;
2078 char tmp[40];
2079
2080 if (target_is_remote ())
2081 {
2082 if (args == 0 || *args == 0)
2083 pc = read_pc (); /* default is current pc */
2084 else
2085 pc = parse_and_eval_address (args);
2086
2087 sprintf_vma (tmp, pc);
2088 sprintf (target_buf, "QTFrame:pc:%s", tmp);
2089 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2090 }
2091 else
2092 error (_("Trace can only be run on remote targets."));
2093 }
2094
2095 /* tfind tracepoint command */
2096 static void
trace_find_tracepoint_command(char * args,int from_tty)2097 trace_find_tracepoint_command (char *args, int from_tty)
2098 {
2099 int tdp;
2100
2101 if (target_is_remote ())
2102 {
2103 if (args == 0 || *args == 0)
2104 {
2105 if (tracepoint_number == -1)
2106 error (_("No current tracepoint -- please supply an argument."));
2107 else
2108 tdp = tracepoint_number; /* default is current TDP */
2109 }
2110 else
2111 tdp = parse_and_eval_long (args);
2112
2113 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
2114 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2115 }
2116 else
2117 error (_("Trace can only be run on remote targets."));
2118 }
2119
2120 /* TFIND LINE command:
2121
2122 This command will take a sourceline for argument, just like BREAK
2123 or TRACE (ie. anything that "decode_line_1" can handle).
2124
2125 With no argument, this command will find the next trace frame
2126 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2127
2128 static void
trace_find_line_command(char * args,int from_tty)2129 trace_find_line_command (char *args, int from_tty)
2130 {
2131 static CORE_ADDR start_pc, end_pc;
2132 struct symtabs_and_lines sals;
2133 struct symtab_and_line sal;
2134 struct cleanup *old_chain;
2135 char startpc_str[40], endpc_str[40];
2136
2137 if (target_is_remote ())
2138 {
2139 if (args == 0 || *args == 0)
2140 {
2141 sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
2142 sals.nelts = 1;
2143 sals.sals = (struct symtab_and_line *)
2144 xmalloc (sizeof (struct symtab_and_line));
2145 sals.sals[0] = sal;
2146 }
2147 else
2148 {
2149 sals = decode_line_spec (args, 1);
2150 sal = sals.sals[0];
2151 }
2152
2153 old_chain = make_cleanup (xfree, sals.sals);
2154 if (sal.symtab == 0)
2155 {
2156 printf_filtered ("TFIND: No line number information available");
2157 if (sal.pc != 0)
2158 {
2159 /* This is useful for "info line *0x7f34". If we can't
2160 tell the user about a source line, at least let them
2161 have the symbolic address. */
2162 printf_filtered (" for address ");
2163 wrap_here (" ");
2164 print_address (sal.pc, gdb_stdout);
2165 printf_filtered (";\n -- will attempt to find by PC. \n");
2166 }
2167 else
2168 {
2169 printf_filtered (".\n");
2170 return; /* No line, no PC; what can we do? */
2171 }
2172 }
2173 else if (sal.line > 0
2174 && find_line_pc_range (sal, &start_pc, &end_pc))
2175 {
2176 if (start_pc == end_pc)
2177 {
2178 printf_filtered ("Line %d of \"%s\"",
2179 sal.line, sal.symtab->filename);
2180 wrap_here (" ");
2181 printf_filtered (" is at address ");
2182 print_address (start_pc, gdb_stdout);
2183 wrap_here (" ");
2184 printf_filtered (" but contains no code.\n");
2185 sal = find_pc_line (start_pc, 0);
2186 if (sal.line > 0 &&
2187 find_line_pc_range (sal, &start_pc, &end_pc) &&
2188 start_pc != end_pc)
2189 printf_filtered ("Attempting to find line %d instead.\n",
2190 sal.line);
2191 else
2192 error (_("Cannot find a good line."));
2193 }
2194 }
2195 else
2196 /* Is there any case in which we get here, and have an address
2197 which the user would want to see? If we have debugging
2198 symbols and no line numbers? */
2199 error (_("Line number %d is out of range for \"%s\"."),
2200 sal.line, sal.symtab->filename);
2201
2202 sprintf_vma (startpc_str, start_pc);
2203 sprintf_vma (endpc_str, end_pc - 1);
2204 /* Find within range of stated line. */
2205 if (args && *args)
2206 sprintf (target_buf, "QTFrame:range:%s:%s",
2207 startpc_str, endpc_str);
2208 /* Find OUTSIDE OF range of CURRENT line. */
2209 else
2210 sprintf (target_buf, "QTFrame:outside:%s:%s",
2211 startpc_str, endpc_str);
2212 finish_tfind_command (target_buf, sizeof (target_buf),
2213 from_tty);
2214 do_cleanups (old_chain);
2215 }
2216 else
2217 error (_("Trace can only be run on remote targets."));
2218 }
2219
2220 /* tfind range command */
2221 static void
trace_find_range_command(char * args,int from_tty)2222 trace_find_range_command (char *args, int from_tty)
2223 {
2224 static CORE_ADDR start, stop;
2225 char start_str[40], stop_str[40];
2226 char *tmp;
2227
2228 if (target_is_remote ())
2229 {
2230 if (args == 0 || *args == 0)
2231 { /* XXX FIXME: what should default behavior be? */
2232 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2233 return;
2234 }
2235
2236 if (0 != (tmp = strchr (args, ',')))
2237 {
2238 *tmp++ = '\0'; /* terminate start address */
2239 while (isspace ((int) *tmp))
2240 tmp++;
2241 start = parse_and_eval_address (args);
2242 stop = parse_and_eval_address (tmp);
2243 }
2244 else
2245 { /* no explicit end address? */
2246 start = parse_and_eval_address (args);
2247 stop = start + 1; /* ??? */
2248 }
2249
2250 sprintf_vma (start_str, start);
2251 sprintf_vma (stop_str, stop);
2252 sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
2253 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2254 }
2255 else
2256 error (_("Trace can only be run on remote targets."));
2257 }
2258
2259 /* tfind outside command */
2260 static void
trace_find_outside_command(char * args,int from_tty)2261 trace_find_outside_command (char *args, int from_tty)
2262 {
2263 CORE_ADDR start, stop;
2264 char start_str[40], stop_str[40];
2265 char *tmp;
2266
2267 if (target_is_remote ())
2268 {
2269 if (args == 0 || *args == 0)
2270 { /* XXX FIXME: what should default behavior be? */
2271 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2272 return;
2273 }
2274
2275 if (0 != (tmp = strchr (args, ',')))
2276 {
2277 *tmp++ = '\0'; /* terminate start address */
2278 while (isspace ((int) *tmp))
2279 tmp++;
2280 start = parse_and_eval_address (args);
2281 stop = parse_and_eval_address (tmp);
2282 }
2283 else
2284 { /* no explicit end address? */
2285 start = parse_and_eval_address (args);
2286 stop = start + 1; /* ??? */
2287 }
2288
2289 sprintf_vma (start_str, start);
2290 sprintf_vma (stop_str, stop);
2291 sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
2292 finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
2293 }
2294 else
2295 error (_("Trace can only be run on remote targets."));
2296 }
2297
2298 /* save-tracepoints command */
2299 static void
tracepoint_save_command(char * args,int from_tty)2300 tracepoint_save_command (char *args, int from_tty)
2301 {
2302 struct tracepoint *tp;
2303 struct action_line *line;
2304 FILE *fp;
2305 char *i1 = " ", *i2 = " ";
2306 char *indent, *actionline, *pathname;
2307 char tmp[40];
2308
2309 if (args == 0 || *args == 0)
2310 error (_("Argument required (file name in which to save tracepoints"));
2311
2312 if (tracepoint_chain == 0)
2313 {
2314 warning (_("save-tracepoints: no tracepoints to save."));
2315 return;
2316 }
2317
2318 pathname = tilde_expand (args);
2319 if (!(fp = fopen (pathname, "w")))
2320 error (_("Unable to open file '%s' for saving tracepoints (%s)"),
2321 args, safe_strerror (errno));
2322 xfree (pathname);
2323
2324 ALL_TRACEPOINTS (tp)
2325 {
2326 if (tp->addr_string)
2327 fprintf (fp, "trace %s\n", tp->addr_string);
2328 else
2329 {
2330 sprintf_vma (tmp, tp->address);
2331 fprintf (fp, "trace *0x%s\n", tmp);
2332 }
2333
2334 if (tp->pass_count)
2335 fprintf (fp, " passcount %d\n", tp->pass_count);
2336
2337 if (tp->actions)
2338 {
2339 fprintf (fp, " actions\n");
2340 indent = i1;
2341 for (line = tp->actions; line; line = line->next)
2342 {
2343 struct cmd_list_element *cmd;
2344
2345 QUIT; /* allow user to bail out with ^C */
2346 actionline = line->action;
2347 while (isspace ((int) *actionline))
2348 actionline++;
2349
2350 fprintf (fp, "%s%s\n", indent, actionline);
2351 if (*actionline != '#') /* skip for comment lines */
2352 {
2353 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2354 if (cmd == 0)
2355 error (_("Bad action list item: %s"), actionline);
2356 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2357 indent = i2;
2358 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2359 indent = i1;
2360 }
2361 }
2362 }
2363 }
2364 fclose (fp);
2365 if (from_tty)
2366 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2367 return;
2368 }
2369
2370 /* info scope command: list the locals for a scope. */
2371 static void
scope_info(char * args,int from_tty)2372 scope_info (char *args, int from_tty)
2373 {
2374 struct symtabs_and_lines sals;
2375 struct symbol *sym;
2376 struct minimal_symbol *msym;
2377 struct block *block;
2378 char **canonical, *symname, *save_args = args;
2379 struct dict_iterator iter;
2380 int j, count = 0;
2381
2382 if (args == 0 || *args == 0)
2383 error (_("requires an argument (function, line or *addr) to define a scope"));
2384
2385 sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
2386 if (sals.nelts == 0)
2387 return; /* presumably decode_line_1 has already warned */
2388
2389 /* Resolve line numbers to PC */
2390 resolve_sal_pc (&sals.sals[0]);
2391 block = block_for_pc (sals.sals[0].pc);
2392
2393 while (block != 0)
2394 {
2395 QUIT; /* allow user to bail out with ^C */
2396 ALL_BLOCK_SYMBOLS (block, iter, sym)
2397 {
2398 QUIT; /* allow user to bail out with ^C */
2399 if (count == 0)
2400 printf_filtered ("Scope for %s:\n", save_args);
2401 count++;
2402
2403 symname = DEPRECATED_SYMBOL_NAME (sym);
2404 if (symname == NULL || *symname == '\0')
2405 continue; /* probably botched, certainly useless */
2406
2407 printf_filtered ("Symbol %s is ", symname);
2408 switch (SYMBOL_CLASS (sym))
2409 {
2410 default:
2411 case LOC_UNDEF: /* messed up symbol? */
2412 printf_filtered ("a bogus symbol, class %d.\n",
2413 SYMBOL_CLASS (sym));
2414 count--; /* don't count this one */
2415 continue;
2416 case LOC_CONST:
2417 printf_filtered ("a constant with value %ld (0x%lx)",
2418 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2419 break;
2420 case LOC_CONST_BYTES:
2421 printf_filtered ("constant bytes: ");
2422 if (SYMBOL_TYPE (sym))
2423 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2424 fprintf_filtered (gdb_stdout, " %02x",
2425 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2426 break;
2427 case LOC_STATIC:
2428 printf_filtered ("in static storage at address ");
2429 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2430 1, gdb_stdout);
2431 break;
2432 case LOC_REGISTER:
2433 printf_filtered ("a local variable in register $%s",
2434 REGISTER_NAME (SYMBOL_VALUE (sym)));
2435 break;
2436 case LOC_ARG:
2437 case LOC_LOCAL_ARG:
2438 printf_filtered ("an argument at stack/frame offset %ld",
2439 SYMBOL_VALUE (sym));
2440 break;
2441 case LOC_LOCAL:
2442 printf_filtered ("a local variable at frame offset %ld",
2443 SYMBOL_VALUE (sym));
2444 break;
2445 case LOC_REF_ARG:
2446 printf_filtered ("a reference argument at offset %ld",
2447 SYMBOL_VALUE (sym));
2448 break;
2449 case LOC_REGPARM:
2450 printf_filtered ("an argument in register $%s",
2451 REGISTER_NAME (SYMBOL_VALUE (sym)));
2452 break;
2453 case LOC_REGPARM_ADDR:
2454 printf_filtered ("the address of an argument, in register $%s",
2455 REGISTER_NAME (SYMBOL_VALUE (sym)));
2456 break;
2457 case LOC_TYPEDEF:
2458 printf_filtered ("a typedef.\n");
2459 continue;
2460 case LOC_LABEL:
2461 printf_filtered ("a label at address ");
2462 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2463 1, gdb_stdout);
2464 break;
2465 case LOC_BLOCK:
2466 printf_filtered ("a function at address ");
2467 deprecated_print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
2468 1, gdb_stdout);
2469 break;
2470 case LOC_BASEREG:
2471 printf_filtered ("a variable at offset %ld from register $%s",
2472 SYMBOL_VALUE (sym),
2473 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2474 break;
2475 case LOC_BASEREG_ARG:
2476 printf_filtered ("an argument at offset %ld from register $%s",
2477 SYMBOL_VALUE (sym),
2478 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2479 break;
2480 case LOC_UNRESOLVED:
2481 msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym),
2482 NULL, NULL);
2483 if (msym == NULL)
2484 printf_filtered ("Unresolved Static");
2485 else
2486 {
2487 printf_filtered ("static storage at address ");
2488 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2489 gdb_stdout);
2490 }
2491 break;
2492 case LOC_OPTIMIZED_OUT:
2493 printf_filtered ("optimized out.\n");
2494 continue;
2495 case LOC_HP_THREAD_LOCAL_STATIC:
2496 printf_filtered ("HP thread local static ");
2497 break;
2498 case LOC_INDIRECT:
2499 printf_filtered ("extern (local indirect) at address ");
2500 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2501 1, gdb_stdout);
2502 break;
2503 case LOC_COMPUTED:
2504 case LOC_COMPUTED_ARG:
2505 SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
2506 break;
2507 }
2508 if (SYMBOL_TYPE (sym))
2509 printf_filtered (", length %d.\n",
2510 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2511 }
2512 if (BLOCK_FUNCTION (block))
2513 break;
2514 else
2515 block = BLOCK_SUPERBLOCK (block);
2516 }
2517 if (count <= 0)
2518 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2519 save_args);
2520 }
2521
2522 /* worker function (cleanup) */
2523 static void
replace_comma(void * data)2524 replace_comma (void *data)
2525 {
2526 char *comma = data;
2527 *comma = ',';
2528 }
2529
2530 /* tdump command */
2531 static void
trace_dump_command(char * args,int from_tty)2532 trace_dump_command (char *args, int from_tty)
2533 {
2534 struct tracepoint *t;
2535 struct action_line *action;
2536 char *action_exp, *next_comma;
2537 struct cleanup *old_cleanups;
2538 int stepping_actions = 0;
2539 int stepping_frame = 0;
2540
2541 if (!target_is_remote ())
2542 {
2543 error (_("Trace can only be run on remote targets."));
2544 return;
2545 }
2546
2547 if (tracepoint_number == -1)
2548 {
2549 warning (_("No current trace frame."));
2550 return;
2551 }
2552
2553 ALL_TRACEPOINTS (t)
2554 if (t->number == tracepoint_number)
2555 break;
2556
2557 if (t == NULL)
2558 error (_("No known tracepoint matches 'current' tracepoint #%d."),
2559 tracepoint_number);
2560
2561 old_cleanups = make_cleanup (null_cleanup, NULL);
2562
2563 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2564 tracepoint_number, traceframe_number);
2565
2566 /* The current frame is a trap frame if the frame PC is equal
2567 to the tracepoint PC. If not, then the current frame was
2568 collected during single-stepping. */
2569
2570 stepping_frame = (t->address != (read_pc () - DECR_PC_AFTER_BREAK));
2571
2572 for (action = t->actions; action; action = action->next)
2573 {
2574 struct cmd_list_element *cmd;
2575
2576 QUIT; /* allow user to bail out with ^C */
2577 action_exp = action->action;
2578 while (isspace ((int) *action_exp))
2579 action_exp++;
2580
2581 /* The collection actions to be done while stepping are
2582 bracketed by the commands "while-stepping" and "end". */
2583
2584 if (*action_exp == '#') /* comment line */
2585 continue;
2586
2587 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2588 if (cmd == 0)
2589 error (_("Bad action list item: %s"), action_exp);
2590
2591 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2592 stepping_actions = 1;
2593 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2594 stepping_actions = 0;
2595 else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
2596 {
2597 /* Display the collected data.
2598 For the trap frame, display only what was collected at
2599 the trap. Likewise for stepping frames, display only
2600 what was collected while stepping. This means that the
2601 two boolean variables, STEPPING_FRAME and
2602 STEPPING_ACTIONS should be equal. */
2603 if (stepping_frame == stepping_actions)
2604 {
2605 do
2606 { /* repeat over a comma-separated list */
2607 QUIT; /* allow user to bail out with ^C */
2608 if (*action_exp == ',')
2609 action_exp++;
2610 while (isspace ((int) *action_exp))
2611 action_exp++;
2612
2613 next_comma = strchr (action_exp, ',');
2614
2615 if (0 == strncasecmp (action_exp, "$reg", 4))
2616 registers_info (NULL, from_tty);
2617 else if (0 == strncasecmp (action_exp, "$loc", 4))
2618 locals_info (NULL, from_tty);
2619 else if (0 == strncasecmp (action_exp, "$arg", 4))
2620 args_info (NULL, from_tty);
2621 else
2622 { /* variable */
2623 if (next_comma)
2624 {
2625 make_cleanup (replace_comma, next_comma);
2626 *next_comma = '\0';
2627 }
2628 printf_filtered ("%s = ", action_exp);
2629 output_command (action_exp, from_tty);
2630 printf_filtered ("\n");
2631 }
2632 if (next_comma)
2633 *next_comma = ',';
2634 action_exp = next_comma;
2635 }
2636 while (action_exp && *action_exp == ',');
2637 }
2638 }
2639 }
2640 discard_cleanups (old_cleanups);
2641 }
2642
2643 /* Convert the memory pointed to by mem into hex, placing result in buf.
2644 * Return a pointer to the last char put in buf (null)
2645 * "stolen" from sparc-stub.c
2646 */
2647
2648 static const char hexchars[] = "0123456789abcdef";
2649
2650 static char *
mem2hex(gdb_byte * mem,char * buf,int count)2651 mem2hex (gdb_byte *mem, char *buf, int count)
2652 {
2653 gdb_byte ch;
2654
2655 while (count-- > 0)
2656 {
2657 ch = *mem++;
2658
2659 *buf++ = hexchars[ch >> 4];
2660 *buf++ = hexchars[ch & 0xf];
2661 }
2662
2663 *buf = 0;
2664
2665 return buf;
2666 }
2667
2668 int
get_traceframe_number(void)2669 get_traceframe_number (void)
2670 {
2671 return traceframe_number;
2672 }
2673
2674
2675 /* module initialization */
2676 void
_initialize_tracepoint(void)2677 _initialize_tracepoint (void)
2678 {
2679 struct cmd_list_element *c;
2680
2681 tracepoint_chain = 0;
2682 tracepoint_count = 0;
2683 traceframe_number = -1;
2684 tracepoint_number = -1;
2685
2686 set_internalvar (lookup_internalvar ("tpnum"),
2687 value_from_longest (builtin_type_int, (LONGEST) 0));
2688 set_internalvar (lookup_internalvar ("trace_frame"),
2689 value_from_longest (builtin_type_int, (LONGEST) - 1));
2690
2691 if (tracepoint_list.list == NULL)
2692 {
2693 tracepoint_list.listsize = 128;
2694 tracepoint_list.list = xmalloc
2695 (tracepoint_list.listsize * sizeof (struct memrange));
2696 }
2697 if (tracepoint_list.aexpr_list == NULL)
2698 {
2699 tracepoint_list.aexpr_listsize = 128;
2700 tracepoint_list.aexpr_list = xmalloc
2701 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
2702 }
2703
2704 if (stepping_list.list == NULL)
2705 {
2706 stepping_list.listsize = 128;
2707 stepping_list.list = xmalloc
2708 (stepping_list.listsize * sizeof (struct memrange));
2709 }
2710
2711 if (stepping_list.aexpr_list == NULL)
2712 {
2713 stepping_list.aexpr_listsize = 128;
2714 stepping_list.aexpr_list = xmalloc
2715 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
2716 }
2717
2718 add_info ("scope", scope_info,
2719 _("List the variables local to a scope"));
2720
2721 add_cmd ("tracepoints", class_trace, NULL,
2722 _("Tracing of program execution without stopping the program."),
2723 &cmdlist);
2724
2725 add_info ("tracepoints", tracepoints_info, _("\
2726 Status of tracepoints, or tracepoint number NUMBER.\n\
2727 Convenience variable \"$tpnum\" contains the number of the\n\
2728 last tracepoint set."));
2729
2730 add_info_alias ("tp", "tracepoints", 1);
2731
2732 c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
2733 Save current tracepoint definitions as a script.\n\
2734 Use the 'source' command in another debug session to restore them."));
2735 set_cmd_completer (c, filename_completer);
2736
2737 add_com ("tdump", class_trace, trace_dump_command,
2738 _("Print everything collected at the current tracepoint."));
2739
2740 add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
2741 Select a trace frame;\n\
2742 No argument means forward by one frame; '-' means backward by one frame."),
2743 &tfindlist, "tfind ", 1, &cmdlist);
2744
2745 add_cmd ("outside", class_trace, trace_find_outside_command, _("\
2746 Select a trace frame whose PC is outside the given range.\n\
2747 Usage: tfind outside addr1, addr2"),
2748 &tfindlist);
2749
2750 add_cmd ("range", class_trace, trace_find_range_command, _("\
2751 Select a trace frame whose PC is in the given range.\n\
2752 Usage: tfind range addr1,addr2"),
2753 &tfindlist);
2754
2755 add_cmd ("line", class_trace, trace_find_line_command, _("\
2756 Select a trace frame by source line.\n\
2757 Argument can be a line number (with optional source file), \n\
2758 a function name, or '*' followed by an address.\n\
2759 Default argument is 'the next source line that was traced'."),
2760 &tfindlist);
2761
2762 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
2763 Select a trace frame by tracepoint number.\n\
2764 Default is the tracepoint for the current trace frame."),
2765 &tfindlist);
2766
2767 add_cmd ("pc", class_trace, trace_find_pc_command, _("\
2768 Select a trace frame by PC.\n\
2769 Default is the current PC, or the PC of the current trace frame."),
2770 &tfindlist);
2771
2772 add_cmd ("end", class_trace, trace_find_end_command, _("\
2773 Synonym for 'none'.\n\
2774 De-select any trace frame and resume 'live' debugging."),
2775 &tfindlist);
2776
2777 add_cmd ("none", class_trace, trace_find_none_command,
2778 _("De-select any trace frame and resume 'live' debugging."),
2779 &tfindlist);
2780
2781 add_cmd ("start", class_trace, trace_find_start_command,
2782 _("Select the first trace frame in the trace buffer."),
2783 &tfindlist);
2784
2785 add_com ("tstatus", class_trace, trace_status_command,
2786 _("Display the status of the current trace data collection."));
2787
2788 add_com ("tstop", class_trace, trace_stop_command,
2789 _("Stop trace data collection."));
2790
2791 add_com ("tstart", class_trace, trace_start_command,
2792 _("Start trace data collection."));
2793
2794 add_com ("passcount", class_trace, trace_pass_command, _("\
2795 Set the passcount for a tracepoint.\n\
2796 The trace will end when the tracepoint has been passed 'count' times.\n\
2797 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2798 if TPNUM is omitted, passcount refers to the last tracepoint defined."));
2799
2800 add_com ("end", class_trace, end_actions_pseudocommand, _("\
2801 Ends a list of commands or actions.\n\
2802 Several GDB commands allow you to enter a list of commands or actions.\n\
2803 Entering \"end\" on a line by itself is the normal way to terminate\n\
2804 such a list.\n\n\
2805 Note: the \"end\" command cannot be used at the gdb prompt."));
2806
2807 add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
2808 Specify single-stepping behavior at a tracepoint.\n\
2809 Argument is number of instructions to trace in single-step mode\n\
2810 following the tracepoint. This command is normally followed by\n\
2811 one or more \"collect\" commands, to specify what to collect\n\
2812 while single-stepping.\n\n\
2813 Note: this command can only be used in a tracepoint \"actions\" list."));
2814
2815 add_com_alias ("ws", "while-stepping", class_alias, 0);
2816 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2817
2818 add_com ("collect", class_trace, collect_pseudocommand, _("\
2819 Specify one or more data items to be collected at a tracepoint.\n\
2820 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2821 collect all data (variables, registers) referenced by that expression.\n\
2822 Also accepts the following special arguments:\n\
2823 $regs -- all registers.\n\
2824 $args -- all function arguments.\n\
2825 $locals -- all variables local to the block/function scope.\n\
2826 Note: this command can only be used in a tracepoint \"actions\" list."));
2827
2828 add_com ("actions", class_trace, trace_actions_command, _("\
2829 Specify the actions to be taken at a tracepoint.\n\
2830 Tracepoint actions may include collecting of specified data, \n\
2831 single-stepping, or enabling/disabling other tracepoints, \n\
2832 depending on target's capabilities."));
2833
2834 add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
2835 Delete specified tracepoints.\n\
2836 Arguments are tracepoint numbers, separated by spaces.\n\
2837 No argument means delete all tracepoints."),
2838 &deletelist);
2839
2840 add_cmd ("tracepoints", class_trace, disable_trace_command, _("\
2841 Disable specified tracepoints.\n\
2842 Arguments are tracepoint numbers, separated by spaces.\n\
2843 No argument means disable all tracepoints."),
2844 &disablelist);
2845
2846 add_cmd ("tracepoints", class_trace, enable_trace_command, _("\
2847 Enable specified tracepoints.\n\
2848 Arguments are tracepoint numbers, separated by spaces.\n\
2849 No argument means enable all tracepoints."),
2850 &enablelist);
2851
2852 c = add_com ("trace", class_trace, trace_command, _("\
2853 Set a tracepoint at a specified line or function or address.\n\
2854 Argument may be a line number, function name, or '*' plus an address.\n\
2855 For a line number or function, trace at the start of its code.\n\
2856 If an address is specified, trace at that exact address.\n\n\
2857 Do \"help tracepoints\" for info on other tracepoint commands."));
2858 set_cmd_completer (c, location_completer);
2859
2860 add_com_alias ("tp", "trace", class_alias, 0);
2861 add_com_alias ("tr", "trace", class_alias, 1);
2862 add_com_alias ("tra", "trace", class_alias, 1);
2863 add_com_alias ("trac", "trace", class_alias, 1);
2864 }
2865