]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tracepoint.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[thirdparty/binutils-gdb.git] / gdb / tracepoint.c
1 /* Tracing functionality for remote targets in custom GDB protocol
2
3 Copyright (C) 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., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, 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 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56
57 /* Maximum length of an agent aexpression.
58 This accounts for the fact that packets are limited to 400 bytes
59 (which includes everything -- including the checksum), and assumes
60 the worst case of maximum length for each of the pieces of a
61 continuation packet.
62
63 NOTE: expressions get mem2hex'ed otherwise this would be twice as
64 large. (400 - 31)/2 == 184 */
65 #define MAX_AGENT_EXPR_LEN 184
66
67
68 extern void (*deprecated_readline_begin_hook) (char *, ...);
69 extern char *(*deprecated_readline_hook) (char *);
70 extern void (*deprecated_readline_end_hook) (void);
71 extern void x_command (char *, int);
72 extern int addressprint; /* Print machine addresses? */
73
74 /* GDB commands implemented in other modules:
75 */
76
77 extern void output_command (char *, int);
78
79 /*
80 Tracepoint.c:
81
82 This module defines the following debugger commands:
83 trace : set a tracepoint on a function, line, or address.
84 info trace : list all debugger-defined tracepoints.
85 delete trace : delete one or more tracepoints.
86 enable trace : enable one or more tracepoints.
87 disable trace : disable one or more tracepoints.
88 actions : specify actions to be taken at a tracepoint.
89 passcount : specify a pass count for a tracepoint.
90 tstart : start a trace experiment.
91 tstop : stop a trace experiment.
92 tstatus : query the status of a trace experiment.
93 tfind : find a trace frame in the trace buffer.
94 tdump : print everything collected at the current tracepoint.
95 save-tracepoints : write tracepoint setup into a file.
96
97 This module defines the following user-visible debugger variables:
98 $trace_frame : sequence number of trace frame currently being debugged.
99 $trace_line : source line of trace frame currently being debugged.
100 $trace_file : source file of trace frame currently being debugged.
101 $tracepoint : tracepoint number of trace frame currently being debugged.
102 */
103
104
105 /* ======= Important global variables: ======= */
106
107 /* Chain of all tracepoints defined. */
108 struct tracepoint *tracepoint_chain;
109
110 /* Number of last tracepoint made. */
111 static int tracepoint_count;
112
113 /* Number of last traceframe collected. */
114 static int traceframe_number;
115
116 /* Tracepoint for last traceframe collected. */
117 static int tracepoint_number;
118
119 /* Symbol for function for last traceframe collected */
120 static struct symbol *traceframe_fun;
121
122 /* Symtab and line for last traceframe collected */
123 static struct symtab_and_line traceframe_sal;
124
125 /* Tracing command lists */
126 static struct cmd_list_element *tfindlist;
127
128 /* ======= Important command functions: ======= */
129 static void trace_command (char *, int);
130 static void tracepoints_info (char *, int);
131 static void delete_trace_command (char *, int);
132 static void enable_trace_command (char *, int);
133 static void disable_trace_command (char *, int);
134 static void trace_pass_command (char *, int);
135 static void trace_actions_command (char *, int);
136 static void trace_start_command (char *, int);
137 static void trace_stop_command (char *, int);
138 static void trace_status_command (char *, int);
139 static void trace_find_command (char *, int);
140 static void trace_find_pc_command (char *, int);
141 static void trace_find_tracepoint_command (char *, int);
142 static void trace_find_line_command (char *, int);
143 static void trace_find_range_command (char *, int);
144 static void trace_find_outside_command (char *, int);
145 static void tracepoint_save_command (char *, int);
146 static void trace_dump_command (char *, int);
147
148 /* support routines */
149 static void trace_mention (struct tracepoint *);
150
151 struct collection_list;
152 static void add_aexpr (struct collection_list *, struct agent_expr *);
153 static char *mem2hex (gdb_byte *, char *, int);
154 static void add_register (struct collection_list *collection,
155 unsigned int regno);
156 static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
157 static void free_actions_list (char **actions_list);
158 static void free_actions_list_cleanup_wrapper (void *);
159
160 extern void _initialize_tracepoint (void);
161
162 /* Utility: returns true if "target remote" */
163 static int
164 target_is_remote (void)
165 {
166 if (current_target.to_shortname &&
167 (strcmp (current_target.to_shortname, "remote") == 0
168 || strcmp (current_target.to_shortname, "extended-remote") == 0))
169 return 1;
170 else
171 return 0;
172 }
173
174 /* Utility: generate error from an incoming stub packet. */
175 static void
176 trace_error (char *buf)
177 {
178 if (*buf++ != 'E')
179 return; /* not an error msg */
180 switch (*buf)
181 {
182 case '1': /* malformed packet error */
183 if (*++buf == '0') /* general case: */
184 error (_("tracepoint.c: error in outgoing packet."));
185 else
186 error (_("tracepoint.c: error in outgoing packet at field #%ld."),
187 strtol (buf, NULL, 16));
188 case '2':
189 error (_("trace API error 0x%s."), ++buf);
190 default:
191 error (_("Target returns error code '%s'."), buf);
192 }
193 }
194
195 /* Utility: wait for reply from stub, while accepting "O" packets. */
196 static char *
197 remote_get_noisy_reply (char **buf_p,
198 long *sizeof_buf)
199 {
200 do /* Loop on reply from remote stub. */
201 {
202 char *buf;
203 QUIT; /* allow user to bail out with ^C */
204 getpkt (buf_p, sizeof_buf, 0);
205 buf = *buf_p;
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
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
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
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
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 *
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
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
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
1063 do_free_actions_cleanup (void *t)
1064 {
1065 free_actions (t);
1066 }
1067
1068 static struct cleanup *
1069 make_cleanup_free_actions (struct tracepoint *t)
1070 {
1071 return make_cleanup (do_free_actions_cleanup, t);
1072 }
1073
1074 enum {
1075 memrange_absolute = -1
1076 };
1077
1078 struct memrange
1079 {
1080 int type; /* memrange_absolute for absolute memory range,
1081 else basereg number */
1082 bfd_signed_vma start;
1083 bfd_signed_vma end;
1084 };
1085
1086 struct collection_list
1087 {
1088 unsigned char regs_mask[32]; /* room for up to 256 regs */
1089 long listsize;
1090 long next_memrange;
1091 struct memrange *list;
1092 long aexpr_listsize; /* size of array pointed to by expr_list elt */
1093 long next_aexpr_elt;
1094 struct agent_expr **aexpr_list;
1095
1096 }
1097 tracepoint_list, stepping_list;
1098
1099 /* MEMRANGE functions: */
1100
1101 static int memrange_cmp (const void *, const void *);
1102
1103 /* compare memranges for qsort */
1104 static int
1105 memrange_cmp (const void *va, const void *vb)
1106 {
1107 const struct memrange *a = va, *b = vb;
1108
1109 if (a->type < b->type)
1110 return -1;
1111 if (a->type > b->type)
1112 return 1;
1113 if (a->type == memrange_absolute)
1114 {
1115 if ((bfd_vma) a->start < (bfd_vma) b->start)
1116 return -1;
1117 if ((bfd_vma) a->start > (bfd_vma) b->start)
1118 return 1;
1119 }
1120 else
1121 {
1122 if (a->start < b->start)
1123 return -1;
1124 if (a->start > b->start)
1125 return 1;
1126 }
1127 return 0;
1128 }
1129
1130 /* Sort the memrange list using qsort, and merge adjacent memranges. */
1131 static void
1132 memrange_sortmerge (struct collection_list *memranges)
1133 {
1134 int a, b;
1135
1136 qsort (memranges->list, memranges->next_memrange,
1137 sizeof (struct memrange), memrange_cmp);
1138 if (memranges->next_memrange > 0)
1139 {
1140 for (a = 0, b = 1; b < memranges->next_memrange; b++)
1141 {
1142 if (memranges->list[a].type == memranges->list[b].type &&
1143 memranges->list[b].start - memranges->list[a].end <=
1144 MAX_REGISTER_SIZE)
1145 {
1146 /* memrange b starts before memrange a ends; merge them. */
1147 if (memranges->list[b].end > memranges->list[a].end)
1148 memranges->list[a].end = memranges->list[b].end;
1149 continue; /* next b, same a */
1150 }
1151 a++; /* next a */
1152 if (a != b)
1153 memcpy (&memranges->list[a], &memranges->list[b],
1154 sizeof (struct memrange));
1155 }
1156 memranges->next_memrange = a + 1;
1157 }
1158 }
1159
1160 /* Add a register to a collection list. */
1161 static void
1162 add_register (struct collection_list *collection, unsigned int regno)
1163 {
1164 if (info_verbose)
1165 printf_filtered ("collect register %d\n", regno);
1166 if (regno > (8 * sizeof (collection->regs_mask)))
1167 error (_("Internal: register number %d too large for tracepoint"),
1168 regno);
1169 collection->regs_mask[regno / 8] |= 1 << (regno % 8);
1170 }
1171
1172 /* Add a memrange to a collection list */
1173 static void
1174 add_memrange (struct collection_list *memranges,
1175 int type, bfd_signed_vma base,
1176 unsigned long len)
1177 {
1178 if (info_verbose)
1179 {
1180 printf_filtered ("(%d,", type);
1181 printf_vma (base);
1182 printf_filtered (",%ld)\n", len);
1183 }
1184
1185 /* type: memrange_absolute == memory, other n == basereg */
1186 memranges->list[memranges->next_memrange].type = type;
1187 /* base: addr if memory, offset if reg relative. */
1188 memranges->list[memranges->next_memrange].start = base;
1189 /* len: we actually save end (base + len) for convenience */
1190 memranges->list[memranges->next_memrange].end = base + len;
1191 memranges->next_memrange++;
1192 if (memranges->next_memrange >= memranges->listsize)
1193 {
1194 memranges->listsize *= 2;
1195 memranges->list = xrealloc (memranges->list,
1196 memranges->listsize);
1197 }
1198
1199 if (type != memrange_absolute) /* Better collect the base register! */
1200 add_register (memranges, type);
1201 }
1202
1203 /* Add a symbol to a collection list. */
1204 static void
1205 collect_symbol (struct collection_list *collect,
1206 struct symbol *sym,
1207 long frame_regno, long frame_offset)
1208 {
1209 unsigned long len;
1210 unsigned int reg;
1211 bfd_signed_vma offset;
1212
1213 len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
1214 switch (SYMBOL_CLASS (sym))
1215 {
1216 default:
1217 printf_filtered ("%s: don't know symbol class %d\n",
1218 DEPRECATED_SYMBOL_NAME (sym),
1219 SYMBOL_CLASS (sym));
1220 break;
1221 case LOC_CONST:
1222 printf_filtered ("constant %s (value %ld) will not be collected.\n",
1223 DEPRECATED_SYMBOL_NAME (sym), SYMBOL_VALUE (sym));
1224 break;
1225 case LOC_STATIC:
1226 offset = SYMBOL_VALUE_ADDRESS (sym);
1227 if (info_verbose)
1228 {
1229 char tmp[40];
1230
1231 sprintf_vma (tmp, offset);
1232 printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n",
1233 DEPRECATED_SYMBOL_NAME (sym), len,
1234 tmp /* address */);
1235 }
1236 add_memrange (collect, memrange_absolute, offset, len);
1237 break;
1238 case LOC_REGISTER:
1239 case LOC_REGPARM:
1240 reg = SYMBOL_VALUE (sym);
1241 if (info_verbose)
1242 printf_filtered ("LOC_REG[parm] %s: ",
1243 DEPRECATED_SYMBOL_NAME (sym));
1244 add_register (collect, reg);
1245 /* Check for doubles stored in two registers. */
1246 /* FIXME: how about larger types stored in 3 or more regs? */
1247 if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FLT &&
1248 len > register_size (current_gdbarch, reg))
1249 add_register (collect, reg + 1);
1250 break;
1251 case LOC_REF_ARG:
1252 printf_filtered ("Sorry, don't know how to do LOC_REF_ARG yet.\n");
1253 printf_filtered (" (will not collect %s)\n",
1254 DEPRECATED_SYMBOL_NAME (sym));
1255 break;
1256 case LOC_ARG:
1257 reg = frame_regno;
1258 offset = frame_offset + SYMBOL_VALUE (sym);
1259 if (info_verbose)
1260 {
1261 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1262 DEPRECATED_SYMBOL_NAME (sym), len);
1263 printf_vma (offset);
1264 printf_filtered (" from frame ptr reg %d\n", reg);
1265 }
1266 add_memrange (collect, reg, offset, len);
1267 break;
1268 case LOC_REGPARM_ADDR:
1269 reg = SYMBOL_VALUE (sym);
1270 offset = 0;
1271 if (info_verbose)
1272 {
1273 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset ",
1274 DEPRECATED_SYMBOL_NAME (sym), len);
1275 printf_vma (offset);
1276 printf_filtered (" from reg %d\n", reg);
1277 }
1278 add_memrange (collect, reg, offset, len);
1279 break;
1280 case LOC_LOCAL:
1281 case LOC_LOCAL_ARG:
1282 reg = frame_regno;
1283 offset = frame_offset + SYMBOL_VALUE (sym);
1284 if (info_verbose)
1285 {
1286 printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset ",
1287 DEPRECATED_SYMBOL_NAME (sym), len);
1288 printf_vma (offset);
1289 printf_filtered (" from frame ptr reg %d\n", reg);
1290 }
1291 add_memrange (collect, reg, offset, len);
1292 break;
1293 case LOC_BASEREG:
1294 case LOC_BASEREG_ARG:
1295 reg = SYMBOL_BASEREG (sym);
1296 offset = SYMBOL_VALUE (sym);
1297 if (info_verbose)
1298 {
1299 printf_filtered ("LOC_BASEREG %s: collect %ld bytes at offset ",
1300 DEPRECATED_SYMBOL_NAME (sym), len);
1301 printf_vma (offset);
1302 printf_filtered (" from basereg %d\n", reg);
1303 }
1304 add_memrange (collect, reg, offset, len);
1305 break;
1306 case LOC_UNRESOLVED:
1307 printf_filtered ("Don't know LOC_UNRESOLVED %s\n",
1308 DEPRECATED_SYMBOL_NAME (sym));
1309 break;
1310 case LOC_OPTIMIZED_OUT:
1311 printf_filtered ("%s has been optimized out of existence.\n",
1312 DEPRECATED_SYMBOL_NAME (sym));
1313 break;
1314 }
1315 }
1316
1317 /* Add all locals (or args) symbols to collection list */
1318 static void
1319 add_local_symbols (struct collection_list *collect, CORE_ADDR pc,
1320 long frame_regno, long frame_offset, int type)
1321 {
1322 struct symbol *sym;
1323 struct block *block;
1324 struct dict_iterator iter;
1325 int count = 0;
1326
1327 block = block_for_pc (pc);
1328 while (block != 0)
1329 {
1330 QUIT; /* allow user to bail out with ^C */
1331 ALL_BLOCK_SYMBOLS (block, iter, sym)
1332 {
1333 switch (SYMBOL_CLASS (sym))
1334 {
1335 default:
1336 warning (_("don't know how to trace local symbol %s"),
1337 DEPRECATED_SYMBOL_NAME (sym));
1338 case LOC_LOCAL:
1339 case LOC_STATIC:
1340 case LOC_REGISTER:
1341 case LOC_BASEREG:
1342 if (type == 'L') /* collecting Locals */
1343 {
1344 count++;
1345 collect_symbol (collect, sym, frame_regno,
1346 frame_offset);
1347 }
1348 break;
1349 case LOC_ARG:
1350 case LOC_LOCAL_ARG:
1351 case LOC_REF_ARG:
1352 case LOC_REGPARM:
1353 case LOC_REGPARM_ADDR:
1354 case LOC_BASEREG_ARG:
1355 if (type == 'A') /* collecting Arguments */
1356 {
1357 count++;
1358 collect_symbol (collect, sym, frame_regno,
1359 frame_offset);
1360 }
1361 }
1362 }
1363 if (BLOCK_FUNCTION (block))
1364 break;
1365 else
1366 block = BLOCK_SUPERBLOCK (block);
1367 }
1368 if (count == 0)
1369 warning (_("No %s found in scope."),
1370 type == 'L' ? "locals" : "args");
1371 }
1372
1373 /* worker function */
1374 static void
1375 clear_collection_list (struct collection_list *list)
1376 {
1377 int ndx;
1378
1379 list->next_memrange = 0;
1380 for (ndx = 0; ndx < list->next_aexpr_elt; ndx++)
1381 {
1382 free_agent_expr (list->aexpr_list[ndx]);
1383 list->aexpr_list[ndx] = NULL;
1384 }
1385 list->next_aexpr_elt = 0;
1386 memset (list->regs_mask, 0, sizeof (list->regs_mask));
1387 }
1388
1389 /* reduce a collection list to string form (for gdb protocol) */
1390 static char **
1391 stringify_collection_list (struct collection_list *list, char *string)
1392 {
1393 char temp_buf[2048];
1394 char tmp2[40];
1395 int count;
1396 int ndx = 0;
1397 char *(*str_list)[];
1398 char *end;
1399 long i;
1400
1401 count = 1 + list->next_memrange + list->next_aexpr_elt + 1;
1402 str_list = (char *(*)[]) xmalloc (count * sizeof (char *));
1403
1404 for (i = sizeof (list->regs_mask) - 1; i > 0; i--)
1405 if (list->regs_mask[i] != 0) /* skip leading zeroes in regs_mask */
1406 break;
1407 if (list->regs_mask[i] != 0) /* prepare to send regs_mask to the stub */
1408 {
1409 if (info_verbose)
1410 printf_filtered ("\nCollecting registers (mask): 0x");
1411 end = temp_buf;
1412 *end++ = 'R';
1413 for (; i >= 0; i--)
1414 {
1415 QUIT; /* allow user to bail out with ^C */
1416 if (info_verbose)
1417 printf_filtered ("%02X", list->regs_mask[i]);
1418 sprintf (end, "%02X", list->regs_mask[i]);
1419 end += 2;
1420 }
1421 (*str_list)[ndx] = savestring (temp_buf, end - temp_buf);
1422 ndx++;
1423 }
1424 if (info_verbose)
1425 printf_filtered ("\n");
1426 if (list->next_memrange > 0 && info_verbose)
1427 printf_filtered ("Collecting memranges: \n");
1428 for (i = 0, count = 0, end = temp_buf; i < list->next_memrange; i++)
1429 {
1430 QUIT; /* allow user to bail out with ^C */
1431 sprintf_vma (tmp2, list->list[i].start);
1432 if (info_verbose)
1433 {
1434 printf_filtered ("(%d, %s, %ld)\n",
1435 list->list[i].type,
1436 tmp2,
1437 (long) (list->list[i].end - list->list[i].start));
1438 }
1439 if (count + 27 > MAX_AGENT_EXPR_LEN)
1440 {
1441 (*str_list)[ndx] = savestring (temp_buf, count);
1442 ndx++;
1443 count = 0;
1444 end = temp_buf;
1445 }
1446
1447 {
1448 bfd_signed_vma length = list->list[i].end - list->list[i].start;
1449
1450 /* The "%X" conversion specifier expects an unsigned argument,
1451 so passing -1 (memrange_absolute) to it directly gives you
1452 "FFFFFFFF" (or more, depending on sizeof (unsigned)).
1453 Special-case it. */
1454 if (list->list[i].type == memrange_absolute)
1455 sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
1456 else
1457 sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
1458 }
1459
1460 count += strlen (end);
1461 end = temp_buf + count;
1462 }
1463
1464 for (i = 0; i < list->next_aexpr_elt; i++)
1465 {
1466 QUIT; /* allow user to bail out with ^C */
1467 if ((count + 10 + 2 * list->aexpr_list[i]->len) > MAX_AGENT_EXPR_LEN)
1468 {
1469 (*str_list)[ndx] = savestring (temp_buf, count);
1470 ndx++;
1471 count = 0;
1472 end = temp_buf;
1473 }
1474 sprintf (end, "X%08X,", list->aexpr_list[i]->len);
1475 end += 10; /* 'X' + 8 hex digits + ',' */
1476 count += 10;
1477
1478 end = mem2hex (list->aexpr_list[i]->buf,
1479 end, list->aexpr_list[i]->len);
1480 count += 2 * list->aexpr_list[i]->len;
1481 }
1482
1483 if (count != 0)
1484 {
1485 (*str_list)[ndx] = savestring (temp_buf, count);
1486 ndx++;
1487 count = 0;
1488 end = temp_buf;
1489 }
1490 (*str_list)[ndx] = NULL;
1491
1492 if (ndx == 0)
1493 return NULL;
1494 else
1495 return *str_list;
1496 }
1497
1498 static void
1499 free_actions_list_cleanup_wrapper (void *al)
1500 {
1501 free_actions_list (al);
1502 }
1503
1504 static void
1505 free_actions_list (char **actions_list)
1506 {
1507 int ndx;
1508
1509 if (actions_list == 0)
1510 return;
1511
1512 for (ndx = 0; actions_list[ndx]; ndx++)
1513 xfree (actions_list[ndx]);
1514
1515 xfree (actions_list);
1516 }
1517
1518 /* Render all actions into gdb protocol. */
1519 static void
1520 encode_actions (struct tracepoint *t, char ***tdp_actions,
1521 char ***stepping_actions)
1522 {
1523 static char tdp_buff[2048], step_buff[2048];
1524 char *action_exp;
1525 struct expression *exp = NULL;
1526 struct action_line *action;
1527 int i;
1528 struct value *tempval;
1529 struct collection_list *collect;
1530 struct cmd_list_element *cmd;
1531 struct agent_expr *aexpr;
1532 int frame_reg;
1533 LONGEST frame_offset;
1534
1535
1536 clear_collection_list (&tracepoint_list);
1537 clear_collection_list (&stepping_list);
1538 collect = &tracepoint_list;
1539
1540 *tdp_actions = NULL;
1541 *stepping_actions = NULL;
1542
1543 TARGET_VIRTUAL_FRAME_POINTER (t->address, &frame_reg, &frame_offset);
1544
1545 for (action = t->actions; action; action = action->next)
1546 {
1547 QUIT; /* allow user to bail out with ^C */
1548 action_exp = action->action;
1549 while (isspace ((int) *action_exp))
1550 action_exp++;
1551
1552 if (*action_exp == '#') /* comment line */
1553 return;
1554
1555 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
1556 if (cmd == 0)
1557 error (_("Bad action list item: %s"), action_exp);
1558
1559 if (cmd_cfunc_eq (cmd, collect_pseudocommand))
1560 {
1561 do
1562 { /* repeat over a comma-separated list */
1563 QUIT; /* allow user to bail out with ^C */
1564 while (isspace ((int) *action_exp))
1565 action_exp++;
1566
1567 if (0 == strncasecmp ("$reg", action_exp, 4))
1568 {
1569 for (i = 0; i < NUM_REGS; i++)
1570 add_register (collect, i);
1571 action_exp = strchr (action_exp, ','); /* more? */
1572 }
1573 else if (0 == strncasecmp ("$arg", action_exp, 4))
1574 {
1575 add_local_symbols (collect,
1576 t->address,
1577 frame_reg,
1578 frame_offset,
1579 'A');
1580 action_exp = strchr (action_exp, ','); /* more? */
1581 }
1582 else if (0 == strncasecmp ("$loc", action_exp, 4))
1583 {
1584 add_local_symbols (collect,
1585 t->address,
1586 frame_reg,
1587 frame_offset,
1588 'L');
1589 action_exp = strchr (action_exp, ','); /* more? */
1590 }
1591 else
1592 {
1593 unsigned long addr, len;
1594 struct cleanup *old_chain = NULL;
1595 struct cleanup *old_chain1 = NULL;
1596 struct agent_reqs areqs;
1597
1598 exp = parse_exp_1 (&action_exp,
1599 block_for_pc (t->address), 1);
1600 old_chain = make_cleanup (free_current_contents, &exp);
1601
1602 switch (exp->elts[0].opcode)
1603 {
1604 case OP_REGISTER:
1605 i = exp->elts[1].longconst;
1606 if (info_verbose)
1607 printf_filtered ("OP_REGISTER: ");
1608 add_register (collect, i);
1609 break;
1610
1611 case UNOP_MEMVAL:
1612 /* safe because we know it's a simple expression */
1613 tempval = evaluate_expression (exp);
1614 addr = VALUE_ADDRESS (tempval) + value_offset (tempval);
1615 len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
1616 add_memrange (collect, memrange_absolute, addr, len);
1617 break;
1618
1619 case OP_VAR_VALUE:
1620 collect_symbol (collect,
1621 exp->elts[2].symbol,
1622 frame_reg,
1623 frame_offset);
1624 break;
1625
1626 default: /* full-fledged expression */
1627 aexpr = gen_trace_for_expr (t->address, exp);
1628
1629 old_chain1 = make_cleanup_free_agent_expr (aexpr);
1630
1631 ax_reqs (aexpr, &areqs);
1632 if (areqs.flaw != agent_flaw_none)
1633 error (_("malformed expression"));
1634
1635 if (areqs.min_height < 0)
1636 error (_("gdb: Internal error: expression has min height < 0"));
1637 if (areqs.max_height > 20)
1638 error (_("expression too complicated, try simplifying"));
1639
1640 discard_cleanups (old_chain1);
1641 add_aexpr (collect, aexpr);
1642
1643 /* take care of the registers */
1644 if (areqs.reg_mask_len > 0)
1645 {
1646 int ndx1;
1647 int ndx2;
1648
1649 for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
1650 {
1651 QUIT; /* allow user to bail out with ^C */
1652 if (areqs.reg_mask[ndx1] != 0)
1653 {
1654 /* assume chars have 8 bits */
1655 for (ndx2 = 0; ndx2 < 8; ndx2++)
1656 if (areqs.reg_mask[ndx1] & (1 << ndx2))
1657 /* it's used -- record it */
1658 add_register (collect,
1659 ndx1 * 8 + ndx2);
1660 }
1661 }
1662 }
1663 break;
1664 } /* switch */
1665 do_cleanups (old_chain);
1666 } /* do */
1667 }
1668 while (action_exp && *action_exp++ == ',');
1669 } /* if */
1670 else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
1671 {
1672 collect = &stepping_list;
1673 }
1674 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
1675 {
1676 if (collect == &stepping_list) /* end stepping actions */
1677 collect = &tracepoint_list;
1678 else
1679 break; /* end tracepoint actions */
1680 }
1681 } /* for */
1682 memrange_sortmerge (&tracepoint_list);
1683 memrange_sortmerge (&stepping_list);
1684
1685 *tdp_actions = stringify_collection_list (&tracepoint_list,
1686 tdp_buff);
1687 *stepping_actions = stringify_collection_list (&stepping_list,
1688 step_buff);
1689 }
1690
1691 static void
1692 add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
1693 {
1694 if (collect->next_aexpr_elt >= collect->aexpr_listsize)
1695 {
1696 collect->aexpr_list =
1697 xrealloc (collect->aexpr_list,
1698 2 * collect->aexpr_listsize * sizeof (struct agent_expr *));
1699 collect->aexpr_listsize *= 2;
1700 }
1701 collect->aexpr_list[collect->next_aexpr_elt] = aexpr;
1702 collect->next_aexpr_elt++;
1703 }
1704
1705 static char *target_buf;
1706 static long target_buf_size;
1707
1708 /* Set "transparent" memory ranges
1709
1710 Allow trace mechanism to treat text-like sections
1711 (and perhaps all read-only sections) transparently,
1712 i.e. don't reject memory requests from these address ranges
1713 just because they haven't been collected. */
1714
1715 static void
1716 remote_set_transparent_ranges (void)
1717 {
1718 extern bfd *exec_bfd;
1719 asection *s;
1720 bfd_size_type size;
1721 bfd_vma lma;
1722 int anysecs = 0;
1723
1724 if (!exec_bfd)
1725 return; /* No information to give. */
1726
1727 strcpy (target_buf, "QTro");
1728 for (s = exec_bfd->sections; s; s = s->next)
1729 {
1730 char tmp1[40], tmp2[40];
1731
1732 if ((s->flags & SEC_LOAD) == 0 ||
1733 /* (s->flags & SEC_CODE) == 0 || */
1734 (s->flags & SEC_READONLY) == 0)
1735 continue;
1736
1737 anysecs = 1;
1738 lma = s->lma;
1739 size = bfd_get_section_size (s);
1740 sprintf_vma (tmp1, lma);
1741 sprintf_vma (tmp2, lma + size);
1742 sprintf (target_buf + strlen (target_buf),
1743 ":%s,%s", tmp1, tmp2);
1744 }
1745 if (anysecs)
1746 {
1747 putpkt (target_buf);
1748 getpkt (&target_buf, &target_buf_size, 0);
1749 }
1750 }
1751
1752 /* tstart command:
1753
1754 Tell target to clear any previous trace experiment.
1755 Walk the list of tracepoints, and send them (and their actions)
1756 to the target. If no errors,
1757 Tell target to start a new trace experiment. */
1758
1759 static void
1760 trace_start_command (char *args, int from_tty)
1761 {
1762 struct tracepoint *t;
1763 char buf[2048];
1764 char **tdp_actions;
1765 char **stepping_actions;
1766 int ndx;
1767 struct cleanup *old_chain = NULL;
1768
1769 dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
1770
1771 if (target_is_remote ())
1772 {
1773 putpkt ("QTinit");
1774 remote_get_noisy_reply (&target_buf, &target_buf_size);
1775 if (strcmp (target_buf, "OK"))
1776 error (_("Target does not support this command."));
1777
1778 ALL_TRACEPOINTS (t)
1779 {
1780 char tmp[40];
1781
1782 sprintf_vma (tmp, t->address);
1783 sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
1784 tmp, /* address */
1785 t->enabled_p ? 'E' : 'D',
1786 t->step_count, t->pass_count);
1787
1788 if (t->actions)
1789 strcat (buf, "-");
1790 putpkt (buf);
1791 remote_get_noisy_reply (&target_buf, &target_buf_size);
1792 if (strcmp (target_buf, "OK"))
1793 error (_("Target does not support tracepoints."));
1794
1795 if (t->actions)
1796 {
1797 encode_actions (t, &tdp_actions, &stepping_actions);
1798 old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
1799 tdp_actions);
1800 (void) make_cleanup (free_actions_list_cleanup_wrapper,
1801 stepping_actions);
1802
1803 /* do_single_steps (t); */
1804 if (tdp_actions)
1805 {
1806 for (ndx = 0; tdp_actions[ndx]; ndx++)
1807 {
1808 QUIT; /* allow user to bail out with ^C */
1809 sprintf (buf, "QTDP:-%x:%s:%s%c",
1810 t->number, tmp, /* address */
1811 tdp_actions[ndx],
1812 ((tdp_actions[ndx + 1] || stepping_actions)
1813 ? '-' : 0));
1814 putpkt (buf);
1815 remote_get_noisy_reply (&target_buf,
1816 &target_buf_size);
1817 if (strcmp (target_buf, "OK"))
1818 error (_("Error on target while setting tracepoints."));
1819 }
1820 }
1821 if (stepping_actions)
1822 {
1823 for (ndx = 0; stepping_actions[ndx]; ndx++)
1824 {
1825 QUIT; /* allow user to bail out with ^C */
1826 sprintf (buf, "QTDP:-%x:%s:%s%s%s",
1827 t->number, tmp, /* address */
1828 ((ndx == 0) ? "S" : ""),
1829 stepping_actions[ndx],
1830 (stepping_actions[ndx + 1] ? "-" : ""));
1831 putpkt (buf);
1832 remote_get_noisy_reply (&target_buf,
1833 &target_buf_size);
1834 if (strcmp (target_buf, "OK"))
1835 error (_("Error on target while setting tracepoints."));
1836 }
1837 }
1838
1839 do_cleanups (old_chain);
1840 }
1841 }
1842 /* Tell target to treat text-like sections as transparent. */
1843 remote_set_transparent_ranges ();
1844 /* Now insert traps and begin collecting data. */
1845 putpkt ("QTStart");
1846 remote_get_noisy_reply (&target_buf, &target_buf_size);
1847 if (strcmp (target_buf, "OK"))
1848 error (_("Bogus reply from target: %s"), target_buf);
1849 set_traceframe_num (-1); /* All old traceframes invalidated. */
1850 set_tracepoint_num (-1);
1851 set_traceframe_context (-1);
1852 trace_running_p = 1;
1853 if (deprecated_trace_start_stop_hook)
1854 deprecated_trace_start_stop_hook (1, from_tty);
1855
1856 }
1857 else
1858 error (_("Trace can only be run on remote targets."));
1859 }
1860
1861 /* tstop command */
1862 static void
1863 trace_stop_command (char *args, int from_tty)
1864 {
1865 if (target_is_remote ())
1866 {
1867 putpkt ("QTStop");
1868 remote_get_noisy_reply (&target_buf, &target_buf_size);
1869 if (strcmp (target_buf, "OK"))
1870 error (_("Bogus reply from target: %s"), target_buf);
1871 trace_running_p = 0;
1872 if (deprecated_trace_start_stop_hook)
1873 deprecated_trace_start_stop_hook (0, from_tty);
1874 }
1875 else
1876 error (_("Trace can only be run on remote targets."));
1877 }
1878
1879 unsigned long trace_running_p;
1880
1881 /* tstatus command */
1882 static void
1883 trace_status_command (char *args, int from_tty)
1884 {
1885 if (target_is_remote ())
1886 {
1887 putpkt ("qTStatus");
1888 remote_get_noisy_reply (&target_buf, &target_buf_size);
1889
1890 if (target_buf[0] != 'T' ||
1891 (target_buf[1] != '0' && target_buf[1] != '1'))
1892 error (_("Bogus reply from target: %s"), target_buf);
1893
1894 /* exported for use by the GUI */
1895 trace_running_p = (target_buf[1] == '1');
1896 }
1897 else
1898 error (_("Trace can only be run on remote targets."));
1899 }
1900
1901 /* Worker function for the various flavors of the tfind command. */
1902 static void
1903 finish_tfind_command (char **msg,
1904 long *sizeof_msg,
1905 int from_tty)
1906 {
1907 int target_frameno = -1, target_tracept = -1;
1908 CORE_ADDR old_frame_addr;
1909 struct symbol *old_func;
1910 char *reply;
1911
1912 old_frame_addr = get_frame_base (get_current_frame ());
1913 old_func = find_pc_function (read_pc ());
1914
1915 putpkt (*msg);
1916 reply = remote_get_noisy_reply (msg, sizeof_msg);
1917
1918 while (reply && *reply)
1919 switch (*reply)
1920 {
1921 case 'F':
1922 if ((target_frameno = (int) strtol (++reply, &reply, 16)) == -1)
1923 {
1924 /* A request for a non-existant trace frame has failed.
1925 Our response will be different, depending on FROM_TTY:
1926
1927 If FROM_TTY is true, meaning that this command was
1928 typed interactively by the user, then give an error
1929 and DO NOT change the state of traceframe_number etc.
1930
1931 However if FROM_TTY is false, meaning that we're either
1932 in a script, a loop, or a user-defined command, then
1933 DON'T give an error, but DO change the state of
1934 traceframe_number etc. to invalid.
1935
1936 The rationalle is that if you typed the command, you
1937 might just have committed a typo or something, and you'd
1938 like to NOT lose your current debugging state. However
1939 if you're in a user-defined command or especially in a
1940 loop, then you need a way to detect that the command
1941 failed WITHOUT aborting. This allows you to write
1942 scripts that search thru the trace buffer until the end,
1943 and then continue on to do something else. */
1944
1945 if (from_tty)
1946 error (_("Target failed to find requested trace frame."));
1947 else
1948 {
1949 if (info_verbose)
1950 printf_filtered ("End of trace buffer.\n");
1951 /* The following will not recurse, since it's
1952 special-cased. */
1953 trace_find_command ("-1", from_tty);
1954 reply = NULL; /* Break out of loop
1955 (avoid recursive nonsense). */
1956 }
1957 }
1958 break;
1959 case 'T':
1960 if ((target_tracept = (int) strtol (++reply, &reply, 16)) == -1)
1961 error (_("Target failed to find requested trace frame."));
1962 break;
1963 case 'O': /* "OK"? */
1964 if (reply[1] == 'K' && reply[2] == '\0')
1965 reply += 2;
1966 else
1967 error (_("Bogus reply from target: %s"), reply);
1968 break;
1969 default:
1970 error (_("Bogus reply from target: %s"), reply);
1971 }
1972
1973 flush_cached_frames ();
1974 registers_changed ();
1975 select_frame (get_current_frame ());
1976 set_traceframe_num (target_frameno);
1977 set_tracepoint_num (target_tracept);
1978 if (target_frameno == -1)
1979 set_traceframe_context (-1);
1980 else
1981 set_traceframe_context (read_pc ());
1982
1983 if (from_tty)
1984 {
1985 enum print_what print_what;
1986
1987 /* NOTE: in immitation of the step command, try to determine
1988 whether we have made a transition from one function to
1989 another. If so, we'll print the "stack frame" (ie. the new
1990 function and it's arguments) -- otherwise we'll just show the
1991 new source line.
1992
1993 This determination is made by checking (1) whether the
1994 current function has changed, and (2) whether the current FP
1995 has changed. Hack: if the FP wasn't collected, either at the
1996 current or the previous frame, assume that the FP has NOT
1997 changed. */
1998
1999 if (old_func == find_pc_function (read_pc ()) &&
2000 (old_frame_addr == 0 ||
2001 get_frame_base (get_current_frame ()) == 0 ||
2002 old_frame_addr == get_frame_base (get_current_frame ())))
2003 print_what = SRC_LINE;
2004 else
2005 print_what = SRC_AND_LOC;
2006
2007 print_stack_frame (get_selected_frame (NULL), 1, print_what);
2008 do_displays ();
2009 }
2010 }
2011
2012 /* trace_find_command takes a trace frame number n,
2013 sends "QTFrame:<n>" to the target,
2014 and accepts a reply that may contain several optional pieces
2015 of information: a frame number, a tracepoint number, and an
2016 indication of whether this is a trap frame or a stepping frame.
2017
2018 The minimal response is just "OK" (which indicates that the
2019 target does not give us a frame number or a tracepoint number).
2020 Instead of that, the target may send us a string containing
2021 any combination of:
2022 F<hexnum> (gives the selected frame number)
2023 T<hexnum> (gives the selected tracepoint number)
2024 */
2025
2026 /* tfind command */
2027 static void
2028 trace_find_command (char *args, int from_tty)
2029 { /* this should only be called with a numeric argument */
2030 int frameno = -1;
2031
2032 if (target_is_remote ())
2033 {
2034 if (deprecated_trace_find_hook)
2035 deprecated_trace_find_hook (args, from_tty);
2036
2037 if (args == 0 || *args == 0)
2038 { /* TFIND with no args means find NEXT trace frame. */
2039 if (traceframe_number == -1)
2040 frameno = 0; /* "next" is first one */
2041 else
2042 frameno = traceframe_number + 1;
2043 }
2044 else if (0 == strcmp (args, "-"))
2045 {
2046 if (traceframe_number == -1)
2047 error (_("not debugging trace buffer"));
2048 else if (from_tty && traceframe_number == 0)
2049 error (_("already at start of trace buffer"));
2050
2051 frameno = traceframe_number - 1;
2052 }
2053 else
2054 frameno = parse_and_eval_long (args);
2055
2056 if (frameno < -1)
2057 error (_("invalid input (%d is less than zero)"), frameno);
2058
2059 sprintf (target_buf, "QTFrame:%x", frameno);
2060 finish_tfind_command (&target_buf, &target_buf_size, from_tty);
2061 }
2062 else
2063 error (_("Trace can only be run on remote targets."));
2064 }
2065
2066 /* tfind end */
2067 static void
2068 trace_find_end_command (char *args, int from_tty)
2069 {
2070 trace_find_command ("-1", from_tty);
2071 }
2072
2073 /* tfind none */
2074 static void
2075 trace_find_none_command (char *args, int from_tty)
2076 {
2077 trace_find_command ("-1", from_tty);
2078 }
2079
2080 /* tfind start */
2081 static void
2082 trace_find_start_command (char *args, int from_tty)
2083 {
2084 trace_find_command ("0", from_tty);
2085 }
2086
2087 /* tfind pc command */
2088 static void
2089 trace_find_pc_command (char *args, int from_tty)
2090 {
2091 CORE_ADDR pc;
2092 char tmp[40];
2093
2094 if (target_is_remote ())
2095 {
2096 if (args == 0 || *args == 0)
2097 pc = read_pc (); /* default is current pc */
2098 else
2099 pc = parse_and_eval_address (args);
2100
2101 sprintf_vma (tmp, pc);
2102 sprintf (target_buf, "QTFrame:pc:%s", tmp);
2103 finish_tfind_command (&target_buf, &target_buf_size, from_tty);
2104 }
2105 else
2106 error (_("Trace can only be run on remote targets."));
2107 }
2108
2109 /* tfind tracepoint command */
2110 static void
2111 trace_find_tracepoint_command (char *args, int from_tty)
2112 {
2113 int tdp;
2114
2115 if (target_is_remote ())
2116 {
2117 if (args == 0 || *args == 0)
2118 {
2119 if (tracepoint_number == -1)
2120 error (_("No current tracepoint -- please supply an argument."));
2121 else
2122 tdp = tracepoint_number; /* default is current TDP */
2123 }
2124 else
2125 tdp = parse_and_eval_long (args);
2126
2127 sprintf (target_buf, "QTFrame:tdp:%x", tdp);
2128 finish_tfind_command (&target_buf, &target_buf_size, from_tty);
2129 }
2130 else
2131 error (_("Trace can only be run on remote targets."));
2132 }
2133
2134 /* TFIND LINE command:
2135
2136 This command will take a sourceline for argument, just like BREAK
2137 or TRACE (ie. anything that "decode_line_1" can handle).
2138
2139 With no argument, this command will find the next trace frame
2140 corresponding to a source line OTHER THAN THE CURRENT ONE. */
2141
2142 static void
2143 trace_find_line_command (char *args, int from_tty)
2144 {
2145 static CORE_ADDR start_pc, end_pc;
2146 struct symtabs_and_lines sals;
2147 struct symtab_and_line sal;
2148 struct cleanup *old_chain;
2149 char startpc_str[40], endpc_str[40];
2150
2151 if (target_is_remote ())
2152 {
2153 if (args == 0 || *args == 0)
2154 {
2155 sal = find_pc_line (get_frame_pc (get_current_frame ()), 0);
2156 sals.nelts = 1;
2157 sals.sals = (struct symtab_and_line *)
2158 xmalloc (sizeof (struct symtab_and_line));
2159 sals.sals[0] = sal;
2160 }
2161 else
2162 {
2163 sals = decode_line_spec (args, 1);
2164 sal = sals.sals[0];
2165 }
2166
2167 old_chain = make_cleanup (xfree, sals.sals);
2168 if (sal.symtab == 0)
2169 {
2170 printf_filtered ("TFIND: No line number information available");
2171 if (sal.pc != 0)
2172 {
2173 /* This is useful for "info line *0x7f34". If we can't
2174 tell the user about a source line, at least let them
2175 have the symbolic address. */
2176 printf_filtered (" for address ");
2177 wrap_here (" ");
2178 print_address (sal.pc, gdb_stdout);
2179 printf_filtered (";\n -- will attempt to find by PC. \n");
2180 }
2181 else
2182 {
2183 printf_filtered (".\n");
2184 return; /* No line, no PC; what can we do? */
2185 }
2186 }
2187 else if (sal.line > 0
2188 && find_line_pc_range (sal, &start_pc, &end_pc))
2189 {
2190 if (start_pc == end_pc)
2191 {
2192 printf_filtered ("Line %d of \"%s\"",
2193 sal.line, sal.symtab->filename);
2194 wrap_here (" ");
2195 printf_filtered (" is at address ");
2196 print_address (start_pc, gdb_stdout);
2197 wrap_here (" ");
2198 printf_filtered (" but contains no code.\n");
2199 sal = find_pc_line (start_pc, 0);
2200 if (sal.line > 0 &&
2201 find_line_pc_range (sal, &start_pc, &end_pc) &&
2202 start_pc != end_pc)
2203 printf_filtered ("Attempting to find line %d instead.\n",
2204 sal.line);
2205 else
2206 error (_("Cannot find a good line."));
2207 }
2208 }
2209 else
2210 /* Is there any case in which we get here, and have an address
2211 which the user would want to see? If we have debugging
2212 symbols and no line numbers? */
2213 error (_("Line number %d is out of range for \"%s\"."),
2214 sal.line, sal.symtab->filename);
2215
2216 sprintf_vma (startpc_str, start_pc);
2217 sprintf_vma (endpc_str, end_pc - 1);
2218 /* Find within range of stated line. */
2219 if (args && *args)
2220 sprintf (target_buf, "QTFrame:range:%s:%s",
2221 startpc_str, endpc_str);
2222 /* Find OUTSIDE OF range of CURRENT line. */
2223 else
2224 sprintf (target_buf, "QTFrame:outside:%s:%s",
2225 startpc_str, endpc_str);
2226 finish_tfind_command (&target_buf, &target_buf_size,
2227 from_tty);
2228 do_cleanups (old_chain);
2229 }
2230 else
2231 error (_("Trace can only be run on remote targets."));
2232 }
2233
2234 /* tfind range command */
2235 static void
2236 trace_find_range_command (char *args, int from_tty)
2237 {
2238 static CORE_ADDR start, stop;
2239 char start_str[40], stop_str[40];
2240 char *tmp;
2241
2242 if (target_is_remote ())
2243 {
2244 if (args == 0 || *args == 0)
2245 { /* XXX FIXME: what should default behavior be? */
2246 printf_filtered ("Usage: tfind range <startaddr>,<endaddr>\n");
2247 return;
2248 }
2249
2250 if (0 != (tmp = strchr (args, ',')))
2251 {
2252 *tmp++ = '\0'; /* terminate start address */
2253 while (isspace ((int) *tmp))
2254 tmp++;
2255 start = parse_and_eval_address (args);
2256 stop = parse_and_eval_address (tmp);
2257 }
2258 else
2259 { /* no explicit end address? */
2260 start = parse_and_eval_address (args);
2261 stop = start + 1; /* ??? */
2262 }
2263
2264 sprintf_vma (start_str, start);
2265 sprintf_vma (stop_str, stop);
2266 sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
2267 finish_tfind_command (&target_buf, &target_buf_size, from_tty);
2268 }
2269 else
2270 error (_("Trace can only be run on remote targets."));
2271 }
2272
2273 /* tfind outside command */
2274 static void
2275 trace_find_outside_command (char *args, int from_tty)
2276 {
2277 CORE_ADDR start, stop;
2278 char start_str[40], stop_str[40];
2279 char *tmp;
2280
2281 if (target_is_remote ())
2282 {
2283 if (args == 0 || *args == 0)
2284 { /* XXX FIXME: what should default behavior be? */
2285 printf_filtered ("Usage: tfind outside <startaddr>,<endaddr>\n");
2286 return;
2287 }
2288
2289 if (0 != (tmp = strchr (args, ',')))
2290 {
2291 *tmp++ = '\0'; /* terminate start address */
2292 while (isspace ((int) *tmp))
2293 tmp++;
2294 start = parse_and_eval_address (args);
2295 stop = parse_and_eval_address (tmp);
2296 }
2297 else
2298 { /* no explicit end address? */
2299 start = parse_and_eval_address (args);
2300 stop = start + 1; /* ??? */
2301 }
2302
2303 sprintf_vma (start_str, start);
2304 sprintf_vma (stop_str, stop);
2305 sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
2306 finish_tfind_command (&target_buf, &target_buf_size, from_tty);
2307 }
2308 else
2309 error (_("Trace can only be run on remote targets."));
2310 }
2311
2312 /* save-tracepoints command */
2313 static void
2314 tracepoint_save_command (char *args, int from_tty)
2315 {
2316 struct tracepoint *tp;
2317 struct action_line *line;
2318 FILE *fp;
2319 char *i1 = " ", *i2 = " ";
2320 char *indent, *actionline, *pathname;
2321 char tmp[40];
2322
2323 if (args == 0 || *args == 0)
2324 error (_("Argument required (file name in which to save tracepoints)"));
2325
2326 if (tracepoint_chain == 0)
2327 {
2328 warning (_("save-tracepoints: no tracepoints to save."));
2329 return;
2330 }
2331
2332 pathname = tilde_expand (args);
2333 if (!(fp = fopen (pathname, "w")))
2334 error (_("Unable to open file '%s' for saving tracepoints (%s)"),
2335 args, safe_strerror (errno));
2336 xfree (pathname);
2337
2338 ALL_TRACEPOINTS (tp)
2339 {
2340 if (tp->addr_string)
2341 fprintf (fp, "trace %s\n", tp->addr_string);
2342 else
2343 {
2344 sprintf_vma (tmp, tp->address);
2345 fprintf (fp, "trace *0x%s\n", tmp);
2346 }
2347
2348 if (tp->pass_count)
2349 fprintf (fp, " passcount %d\n", tp->pass_count);
2350
2351 if (tp->actions)
2352 {
2353 fprintf (fp, " actions\n");
2354 indent = i1;
2355 for (line = tp->actions; line; line = line->next)
2356 {
2357 struct cmd_list_element *cmd;
2358
2359 QUIT; /* allow user to bail out with ^C */
2360 actionline = line->action;
2361 while (isspace ((int) *actionline))
2362 actionline++;
2363
2364 fprintf (fp, "%s%s\n", indent, actionline);
2365 if (*actionline != '#') /* skip for comment lines */
2366 {
2367 cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
2368 if (cmd == 0)
2369 error (_("Bad action list item: %s"), actionline);
2370 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2371 indent = i2;
2372 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2373 indent = i1;
2374 }
2375 }
2376 }
2377 }
2378 fclose (fp);
2379 if (from_tty)
2380 printf_filtered ("Tracepoints saved to file '%s'.\n", args);
2381 return;
2382 }
2383
2384 /* info scope command: list the locals for a scope. */
2385 static void
2386 scope_info (char *args, int from_tty)
2387 {
2388 struct symtabs_and_lines sals;
2389 struct symbol *sym;
2390 struct minimal_symbol *msym;
2391 struct block *block;
2392 char **canonical, *symname, *save_args = args;
2393 struct dict_iterator iter;
2394 int j, count = 0;
2395
2396 if (args == 0 || *args == 0)
2397 error (_("requires an argument (function, line or *addr) to define a scope"));
2398
2399 sals = decode_line_1 (&args, 1, NULL, 0, &canonical, NULL);
2400 if (sals.nelts == 0)
2401 return; /* presumably decode_line_1 has already warned */
2402
2403 /* Resolve line numbers to PC */
2404 resolve_sal_pc (&sals.sals[0]);
2405 block = block_for_pc (sals.sals[0].pc);
2406
2407 while (block != 0)
2408 {
2409 QUIT; /* allow user to bail out with ^C */
2410 ALL_BLOCK_SYMBOLS (block, iter, sym)
2411 {
2412 QUIT; /* allow user to bail out with ^C */
2413 if (count == 0)
2414 printf_filtered ("Scope for %s:\n", save_args);
2415 count++;
2416
2417 symname = DEPRECATED_SYMBOL_NAME (sym);
2418 if (symname == NULL || *symname == '\0')
2419 continue; /* probably botched, certainly useless */
2420
2421 printf_filtered ("Symbol %s is ", symname);
2422 switch (SYMBOL_CLASS (sym))
2423 {
2424 default:
2425 case LOC_UNDEF: /* messed up symbol? */
2426 printf_filtered ("a bogus symbol, class %d.\n",
2427 SYMBOL_CLASS (sym));
2428 count--; /* don't count this one */
2429 continue;
2430 case LOC_CONST:
2431 printf_filtered ("a constant with value %ld (0x%lx)",
2432 SYMBOL_VALUE (sym), SYMBOL_VALUE (sym));
2433 break;
2434 case LOC_CONST_BYTES:
2435 printf_filtered ("constant bytes: ");
2436 if (SYMBOL_TYPE (sym))
2437 for (j = 0; j < TYPE_LENGTH (SYMBOL_TYPE (sym)); j++)
2438 fprintf_filtered (gdb_stdout, " %02x",
2439 (unsigned) SYMBOL_VALUE_BYTES (sym)[j]);
2440 break;
2441 case LOC_STATIC:
2442 printf_filtered ("in static storage at address ");
2443 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2444 1, gdb_stdout);
2445 break;
2446 case LOC_REGISTER:
2447 printf_filtered ("a local variable in register $%s",
2448 REGISTER_NAME (SYMBOL_VALUE (sym)));
2449 break;
2450 case LOC_ARG:
2451 case LOC_LOCAL_ARG:
2452 printf_filtered ("an argument at stack/frame offset %ld",
2453 SYMBOL_VALUE (sym));
2454 break;
2455 case LOC_LOCAL:
2456 printf_filtered ("a local variable at frame offset %ld",
2457 SYMBOL_VALUE (sym));
2458 break;
2459 case LOC_REF_ARG:
2460 printf_filtered ("a reference argument at offset %ld",
2461 SYMBOL_VALUE (sym));
2462 break;
2463 case LOC_REGPARM:
2464 printf_filtered ("an argument in register $%s",
2465 REGISTER_NAME (SYMBOL_VALUE (sym)));
2466 break;
2467 case LOC_REGPARM_ADDR:
2468 printf_filtered ("the address of an argument, in register $%s",
2469 REGISTER_NAME (SYMBOL_VALUE (sym)));
2470 break;
2471 case LOC_TYPEDEF:
2472 printf_filtered ("a typedef.\n");
2473 continue;
2474 case LOC_LABEL:
2475 printf_filtered ("a label at address ");
2476 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2477 1, gdb_stdout);
2478 break;
2479 case LOC_BLOCK:
2480 printf_filtered ("a function at address ");
2481 deprecated_print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
2482 1, gdb_stdout);
2483 break;
2484 case LOC_BASEREG:
2485 printf_filtered ("a variable at offset %ld from register $%s",
2486 SYMBOL_VALUE (sym),
2487 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2488 break;
2489 case LOC_BASEREG_ARG:
2490 printf_filtered ("an argument at offset %ld from register $%s",
2491 SYMBOL_VALUE (sym),
2492 REGISTER_NAME (SYMBOL_BASEREG (sym)));
2493 break;
2494 case LOC_UNRESOLVED:
2495 msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym),
2496 NULL, NULL);
2497 if (msym == NULL)
2498 printf_filtered ("Unresolved Static");
2499 else
2500 {
2501 printf_filtered ("static storage at address ");
2502 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (msym), 1,
2503 gdb_stdout);
2504 }
2505 break;
2506 case LOC_OPTIMIZED_OUT:
2507 printf_filtered ("optimized out.\n");
2508 continue;
2509 case LOC_HP_THREAD_LOCAL_STATIC:
2510 printf_filtered ("HP thread local static ");
2511 break;
2512 case LOC_INDIRECT:
2513 printf_filtered ("extern (local indirect) at address ");
2514 deprecated_print_address_numeric (SYMBOL_VALUE_ADDRESS (sym),
2515 1, gdb_stdout);
2516 break;
2517 case LOC_COMPUTED:
2518 case LOC_COMPUTED_ARG:
2519 SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
2520 break;
2521 }
2522 if (SYMBOL_TYPE (sym))
2523 printf_filtered (", length %d.\n",
2524 TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym))));
2525 }
2526 if (BLOCK_FUNCTION (block))
2527 break;
2528 else
2529 block = BLOCK_SUPERBLOCK (block);
2530 }
2531 if (count <= 0)
2532 printf_filtered ("Scope for %s contains no locals or arguments.\n",
2533 save_args);
2534 }
2535
2536 /* worker function (cleanup) */
2537 static void
2538 replace_comma (void *data)
2539 {
2540 char *comma = data;
2541 *comma = ',';
2542 }
2543
2544 /* tdump command */
2545 static void
2546 trace_dump_command (char *args, int from_tty)
2547 {
2548 struct tracepoint *t;
2549 struct action_line *action;
2550 char *action_exp, *next_comma;
2551 struct cleanup *old_cleanups;
2552 int stepping_actions = 0;
2553 int stepping_frame = 0;
2554
2555 if (!target_is_remote ())
2556 {
2557 error (_("Trace can only be run on remote targets."));
2558 return;
2559 }
2560
2561 if (tracepoint_number == -1)
2562 {
2563 warning (_("No current trace frame."));
2564 return;
2565 }
2566
2567 ALL_TRACEPOINTS (t)
2568 if (t->number == tracepoint_number)
2569 break;
2570
2571 if (t == NULL)
2572 error (_("No known tracepoint matches 'current' tracepoint #%d."),
2573 tracepoint_number);
2574
2575 old_cleanups = make_cleanup (null_cleanup, NULL);
2576
2577 printf_filtered ("Data collected at tracepoint %d, trace frame %d:\n",
2578 tracepoint_number, traceframe_number);
2579
2580 /* The current frame is a trap frame if the frame PC is equal
2581 to the tracepoint PC. If not, then the current frame was
2582 collected during single-stepping. */
2583
2584 stepping_frame = (t->address != (read_pc () - DECR_PC_AFTER_BREAK));
2585
2586 for (action = t->actions; action; action = action->next)
2587 {
2588 struct cmd_list_element *cmd;
2589
2590 QUIT; /* allow user to bail out with ^C */
2591 action_exp = action->action;
2592 while (isspace ((int) *action_exp))
2593 action_exp++;
2594
2595 /* The collection actions to be done while stepping are
2596 bracketed by the commands "while-stepping" and "end". */
2597
2598 if (*action_exp == '#') /* comment line */
2599 continue;
2600
2601 cmd = lookup_cmd (&action_exp, cmdlist, "", -1, 1);
2602 if (cmd == 0)
2603 error (_("Bad action list item: %s"), action_exp);
2604
2605 if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
2606 stepping_actions = 1;
2607 else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
2608 stepping_actions = 0;
2609 else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
2610 {
2611 /* Display the collected data.
2612 For the trap frame, display only what was collected at
2613 the trap. Likewise for stepping frames, display only
2614 what was collected while stepping. This means that the
2615 two boolean variables, STEPPING_FRAME and
2616 STEPPING_ACTIONS should be equal. */
2617 if (stepping_frame == stepping_actions)
2618 {
2619 do
2620 { /* repeat over a comma-separated list */
2621 QUIT; /* allow user to bail out with ^C */
2622 if (*action_exp == ',')
2623 action_exp++;
2624 while (isspace ((int) *action_exp))
2625 action_exp++;
2626
2627 next_comma = strchr (action_exp, ',');
2628
2629 if (0 == strncasecmp (action_exp, "$reg", 4))
2630 registers_info (NULL, from_tty);
2631 else if (0 == strncasecmp (action_exp, "$loc", 4))
2632 locals_info (NULL, from_tty);
2633 else if (0 == strncasecmp (action_exp, "$arg", 4))
2634 args_info (NULL, from_tty);
2635 else
2636 { /* variable */
2637 if (next_comma)
2638 {
2639 make_cleanup (replace_comma, next_comma);
2640 *next_comma = '\0';
2641 }
2642 printf_filtered ("%s = ", action_exp);
2643 output_command (action_exp, from_tty);
2644 printf_filtered ("\n");
2645 }
2646 if (next_comma)
2647 *next_comma = ',';
2648 action_exp = next_comma;
2649 }
2650 while (action_exp && *action_exp == ',');
2651 }
2652 }
2653 }
2654 discard_cleanups (old_cleanups);
2655 }
2656
2657 /* Convert the memory pointed to by mem into hex, placing result in buf.
2658 * Return a pointer to the last char put in buf (null)
2659 * "stolen" from sparc-stub.c
2660 */
2661
2662 static const char hexchars[] = "0123456789abcdef";
2663
2664 static char *
2665 mem2hex (gdb_byte *mem, char *buf, int count)
2666 {
2667 gdb_byte ch;
2668
2669 while (count-- > 0)
2670 {
2671 ch = *mem++;
2672
2673 *buf++ = hexchars[ch >> 4];
2674 *buf++ = hexchars[ch & 0xf];
2675 }
2676
2677 *buf = 0;
2678
2679 return buf;
2680 }
2681
2682 int
2683 get_traceframe_number (void)
2684 {
2685 return traceframe_number;
2686 }
2687
2688
2689 /* module initialization */
2690 void
2691 _initialize_tracepoint (void)
2692 {
2693 struct cmd_list_element *c;
2694
2695 tracepoint_chain = 0;
2696 tracepoint_count = 0;
2697 traceframe_number = -1;
2698 tracepoint_number = -1;
2699
2700 if (tracepoint_list.list == NULL)
2701 {
2702 tracepoint_list.listsize = 128;
2703 tracepoint_list.list = xmalloc
2704 (tracepoint_list.listsize * sizeof (struct memrange));
2705 }
2706 if (tracepoint_list.aexpr_list == NULL)
2707 {
2708 tracepoint_list.aexpr_listsize = 128;
2709 tracepoint_list.aexpr_list = xmalloc
2710 (tracepoint_list.aexpr_listsize * sizeof (struct agent_expr *));
2711 }
2712
2713 if (stepping_list.list == NULL)
2714 {
2715 stepping_list.listsize = 128;
2716 stepping_list.list = xmalloc
2717 (stepping_list.listsize * sizeof (struct memrange));
2718 }
2719
2720 if (stepping_list.aexpr_list == NULL)
2721 {
2722 stepping_list.aexpr_listsize = 128;
2723 stepping_list.aexpr_list = xmalloc
2724 (stepping_list.aexpr_listsize * sizeof (struct agent_expr *));
2725 }
2726
2727 add_info ("scope", scope_info,
2728 _("List the variables local to a scope"));
2729
2730 add_cmd ("tracepoints", class_trace, NULL,
2731 _("Tracing of program execution without stopping the program."),
2732 &cmdlist);
2733
2734 add_info ("tracepoints", tracepoints_info, _("\
2735 Status of tracepoints, or tracepoint number NUMBER.\n\
2736 Convenience variable \"$tpnum\" contains the number of the\n\
2737 last tracepoint set."));
2738
2739 add_info_alias ("tp", "tracepoints", 1);
2740
2741 c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
2742 Save current tracepoint definitions as a script.\n\
2743 Use the 'source' command in another debug session to restore them."));
2744 set_cmd_completer (c, filename_completer);
2745
2746 add_com ("tdump", class_trace, trace_dump_command,
2747 _("Print everything collected at the current tracepoint."));
2748
2749 add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
2750 Select a trace frame;\n\
2751 No argument means forward by one frame; '-' means backward by one frame."),
2752 &tfindlist, "tfind ", 1, &cmdlist);
2753
2754 add_cmd ("outside", class_trace, trace_find_outside_command, _("\
2755 Select a trace frame whose PC is outside the given range.\n\
2756 Usage: tfind outside addr1, addr2"),
2757 &tfindlist);
2758
2759 add_cmd ("range", class_trace, trace_find_range_command, _("\
2760 Select a trace frame whose PC is in the given range.\n\
2761 Usage: tfind range addr1,addr2"),
2762 &tfindlist);
2763
2764 add_cmd ("line", class_trace, trace_find_line_command, _("\
2765 Select a trace frame by source line.\n\
2766 Argument can be a line number (with optional source file), \n\
2767 a function name, or '*' followed by an address.\n\
2768 Default argument is 'the next source line that was traced'."),
2769 &tfindlist);
2770
2771 add_cmd ("tracepoint", class_trace, trace_find_tracepoint_command, _("\
2772 Select a trace frame by tracepoint number.\n\
2773 Default is the tracepoint for the current trace frame."),
2774 &tfindlist);
2775
2776 add_cmd ("pc", class_trace, trace_find_pc_command, _("\
2777 Select a trace frame by PC.\n\
2778 Default is the current PC, or the PC of the current trace frame."),
2779 &tfindlist);
2780
2781 add_cmd ("end", class_trace, trace_find_end_command, _("\
2782 Synonym for 'none'.\n\
2783 De-select any trace frame and resume 'live' debugging."),
2784 &tfindlist);
2785
2786 add_cmd ("none", class_trace, trace_find_none_command,
2787 _("De-select any trace frame and resume 'live' debugging."),
2788 &tfindlist);
2789
2790 add_cmd ("start", class_trace, trace_find_start_command,
2791 _("Select the first trace frame in the trace buffer."),
2792 &tfindlist);
2793
2794 add_com ("tstatus", class_trace, trace_status_command,
2795 _("Display the status of the current trace data collection."));
2796
2797 add_com ("tstop", class_trace, trace_stop_command,
2798 _("Stop trace data collection."));
2799
2800 add_com ("tstart", class_trace, trace_start_command,
2801 _("Start trace data collection."));
2802
2803 add_com ("passcount", class_trace, trace_pass_command, _("\
2804 Set the passcount for a tracepoint.\n\
2805 The trace will end when the tracepoint has been passed 'count' times.\n\
2806 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
2807 if TPNUM is omitted, passcount refers to the last tracepoint defined."));
2808
2809 add_com ("end", class_trace, end_actions_pseudocommand, _("\
2810 Ends a list of commands or actions.\n\
2811 Several GDB commands allow you to enter a list of commands or actions.\n\
2812 Entering \"end\" on a line by itself is the normal way to terminate\n\
2813 such a list.\n\n\
2814 Note: the \"end\" command cannot be used at the gdb prompt."));
2815
2816 add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
2817 Specify single-stepping behavior at a tracepoint.\n\
2818 Argument is number of instructions to trace in single-step mode\n\
2819 following the tracepoint. This command is normally followed by\n\
2820 one or more \"collect\" commands, to specify what to collect\n\
2821 while single-stepping.\n\n\
2822 Note: this command can only be used in a tracepoint \"actions\" list."));
2823
2824 add_com_alias ("ws", "while-stepping", class_alias, 0);
2825 add_com_alias ("stepping", "while-stepping", class_alias, 0);
2826
2827 add_com ("collect", class_trace, collect_pseudocommand, _("\
2828 Specify one or more data items to be collected at a tracepoint.\n\
2829 Accepts a comma-separated list of (one or more) expressions. GDB will\n\
2830 collect all data (variables, registers) referenced by that expression.\n\
2831 Also accepts the following special arguments:\n\
2832 $regs -- all registers.\n\
2833 $args -- all function arguments.\n\
2834 $locals -- all variables local to the block/function scope.\n\
2835 Note: this command can only be used in a tracepoint \"actions\" list."));
2836
2837 add_com ("actions", class_trace, trace_actions_command, _("\
2838 Specify the actions to be taken at a tracepoint.\n\
2839 Tracepoint actions may include collecting of specified data, \n\
2840 single-stepping, or enabling/disabling other tracepoints, \n\
2841 depending on target's capabilities."));
2842
2843 add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
2844 Delete specified tracepoints.\n\
2845 Arguments are tracepoint numbers, separated by spaces.\n\
2846 No argument means delete all tracepoints."),
2847 &deletelist);
2848
2849 add_cmd ("tracepoints", class_trace, disable_trace_command, _("\
2850 Disable specified tracepoints.\n\
2851 Arguments are tracepoint numbers, separated by spaces.\n\
2852 No argument means disable all tracepoints."),
2853 &disablelist);
2854
2855 add_cmd ("tracepoints", class_trace, enable_trace_command, _("\
2856 Enable specified tracepoints.\n\
2857 Arguments are tracepoint numbers, separated by spaces.\n\
2858 No argument means enable all tracepoints."),
2859 &enablelist);
2860
2861 c = add_com ("trace", class_trace, trace_command, _("\
2862 Set a tracepoint at a specified line or function or address.\n\
2863 Argument may be a line number, function name, or '*' plus an address.\n\
2864 For a line number or function, trace at the start of its code.\n\
2865 If an address is specified, trace at that exact address.\n\n\
2866 Do \"help tracepoints\" for info on other tracepoint commands."));
2867 set_cmd_completer (c, location_completer);
2868
2869 add_com_alias ("tp", "trace", class_alias, 0);
2870 add_com_alias ("tr", "trace", class_alias, 1);
2871 add_com_alias ("tra", "trace", class_alias, 1);
2872 add_com_alias ("trac", "trace", class_alias, 1);
2873
2874 target_buf_size = 2048;
2875 target_buf = xmalloc (target_buf_size);
2876 }