1 /* Tracing functionality for remote targets in custom GDB protocol
2 Copyright 1997 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "tracepoint.h"
25 #include "expression.h"
31 /* readline include files */
35 /* readline defines this. */
42 extern int info_verbose
;
44 /* If this definition isn't overridden by the header files, assume
45 that isatty and fileno exist on this system. */
47 #define ISATTY(FP) (isatty (fileno (FP)))
50 /* Walk the following statement or block through all tracepoints.
51 ALL_TRACEPOINTS_SAFE does so even if the statment deletes the current
54 #define ALL_TRACEPOINTS(t) for (t = tracepoint_chain; t; t = t->next)
56 #define ALL_TRACEPOINTS_SAFE(t,tmp) \
57 for (t = tracepoint_chain; \
58 t ? (tmp = t->next, 1) : 0;\
61 /* Chain of all tracepoints defined. */
62 struct tracepoint
*tracepoint_chain
;
64 /* Number of last tracepoint made. */
65 static int tracepoint_count
;
67 /* Number of last traceframe collected. */
68 static int traceframe_number
;
70 /* Utility: returns true if "target remote" */
74 if (current_target
.to_shortname
&&
75 strcmp (current_target
.to_shortname
, "remote") == 0)
81 /* Utility: generate error from an incoming stub packet. */
87 return; /* not an error msg */
90 case '1': /* malformed packet error */
91 if (*++buf
== '0') /* general case: */
92 error ("tracepoint.c: badly formed packet.");
94 error ("tracepoint.c: badly formed packet at field #%d.",
97 error ("trace API error '%s'.", buf
);
99 error ("Target returns error code '%s'.", buf
);
103 /* Obsolete: collect regs from a trace frame */
105 trace_receive_regs (buf
)
109 char regbuf
[MAX_REGISTER_RAW_SIZE
], *tmp
, *p
= buf
;
113 regno
= strtol (p
, &tmp
, 16);
114 if (p
== tmp
|| *tmp
++ != ':')
115 error ("tracepoint.c: malformed 'R' packet");
118 for (i
= 0; i
< REGISTER_RAW_SIZE (regno
); i
++)
120 if (p
[0] == 0 || p
[1] == 0)
121 warning ("Remote reply is too short: %s", buf
);
122 regbuf
[i
] = fromhex (p
[0]) * 16 + fromhex (p
[1]);
127 error ("tracepoint.c: malformed 'R' packet");
129 supply_register (regno
, regbuf
);
133 /* Utility: wait for reply from stub, while accepting "O" packets */
135 remote_get_noisy_reply (buf
)
138 do /* loop on reply from remote stub */
142 error ("Target does not support this command.");
143 else if (buf
[0] == 'E')
145 else if (buf
[0] == 'R')
147 flush_cached_frames ();
148 registers_changed ();
149 select_frame (get_current_frame (), 0);
150 trace_receive_regs (buf
);
152 else if (buf
[0] == 'O' &&
154 remote_console_output (buf
+ 1); /* 'O' message from stub */
156 return; /* here's the actual reply */
160 /* Set tracepoint count to NUM. */
162 set_tracepoint_count (num
)
165 tracepoint_count
= num
;
166 set_internalvar (lookup_internalvar ("tpnum"),
167 value_from_longest (builtin_type_int
, (LONGEST
) num
));
170 /* Set traceframe number to NUM. */
172 set_traceframe_num (num
)
175 traceframe_number
= num
;
176 set_internalvar (lookup_internalvar ("trace_frame"),
177 value_from_longest (builtin_type_int
, (LONGEST
) num
));
180 /* Low level routine to set a tracepoint.
181 Returns the tracepoint object so caller can set other things.
182 Does not set the tracepoint number!
183 Does not print anything.
185 ==> This routine should not be called if there is a chance of later
186 error(); otherwise it leaves a bogus tracepoint on the chain. Validate
187 your arguments BEFORE calling this routine! */
189 static struct tracepoint
*
190 set_raw_tracepoint (sal
)
191 struct symtab_and_line sal
;
193 register struct tracepoint
*t
, *tc
;
194 struct cleanup
*old_chain
;
196 t
= (struct tracepoint
*) xmalloc (sizeof (struct tracepoint
));
197 old_chain
= make_cleanup (free
, t
);
198 memset (t
, 0, sizeof (*t
));
200 if (sal
.symtab
== NULL
)
201 t
->source_file
= NULL
;
203 t
->source_file
= savestring (sal
.symtab
->filename
,
204 strlen (sal
.symtab
->filename
));
205 t
->language
= current_language
->la_language
;
206 t
->input_radix
= input_radix
;
207 t
->line_number
= sal
.line
;
208 t
->enabled
= enabled
;
213 /* Add this tracepoint to the end of the chain
214 so that a list of tracepoints will come out in order
215 of increasing numbers. */
217 tc
= tracepoint_chain
;
219 tracepoint_chain
= t
;
226 discard_cleanups (old_chain
);
231 trace_command (arg
, from_tty
)
235 char **canonical
= (char **)NULL
;
236 struct symtabs_and_lines sals
;
237 struct symtab_and_line sal
;
238 struct tracepoint
*t
;
239 char *addr_start
= 0, *addr_end
= 0, *cond_start
= 0, *cond_end
= 0;
243 error ("trace command requires an argument");
245 if (from_tty
&& info_verbose
)
246 printf_filtered ("TRACE %s\n", arg
);
254 sals
= decode_line_1 (&arg
, 1, (struct symtab
*)NULL
, 0, &canonical
);
257 return; /* ??? Presumably decode_line_1 has already warned? */
259 /* Resolve all line numbers to PC's */
260 for (i
= 0; i
< sals
.nelts
; i
++)
261 resolve_sal_pc (&sals
.sals
[i
]);
263 /* Now set all the tracepoints. */
264 for (i
= 0; i
< sals
.nelts
; i
++)
268 t
= set_raw_tracepoint (sal
);
269 set_tracepoint_count (tracepoint_count
+ 1);
270 t
->number
= tracepoint_count
;
272 /* If a canonical line spec is needed use that instead of the
274 if (canonical
!= (char **)NULL
&& canonical
[i
] != NULL
)
275 t
->addr_string
= canonical
[i
];
277 t
->addr_string
= savestring (addr_start
, addr_end
- addr_start
);
279 t
->cond_string
= savestring (cond_start
, cond_end
- cond_start
);
284 printf_filtered ("Multiple tracepoints were set.\n");
285 printf_filtered ("Use the \"delete\" command to delete unwanted tracepoints.\n");
290 tracepoints_info (tpnum_exp
, from_tty
)
294 struct tracepoint
*t
;
295 struct action_line
*action
;
296 int found_a_tracepoint
= 0;
297 char wrap_indent
[80];
301 char *i1
= "\t", *i2
= "\t ";
302 char *indent
, *actionline
;;
306 tpnum
= parse_and_eval_address (tpnum_exp
);
309 if (tpnum
== -1 || tpnum
== t
->number
)
311 extern int addressprint
; /* print machine addresses? */
313 if (!found_a_tracepoint
++)
314 printf_filtered (" *** [info tracepoints header line] ***\n");
316 strcpy (wrap_indent
, " ");
318 strcat (wrap_indent
, " ");
320 printf_filtered ("%-3d %-10s ", t
->number
,
321 t
->enabled
== enabled
? "enabled" : "disabled");
323 { /* FIXME-32x64: need a print_address_numeric with field width */
324 printf_filtered ("%s ", local_hex_string_custom ((unsigned long) t
->address
, "08l"));
328 sym
= find_pc_function (t
->address
);
331 fputs_filtered ("in ", gdb_stdout
);
332 fputs_filtered (SYMBOL_SOURCE_NAME (sym
), gdb_stdout
);
333 wrap_here (wrap_indent
);
334 fputs_filtered (" at ", gdb_stdout
);
336 fputs_filtered (t
->source_file
, gdb_stdout
);
337 printf_filtered (":%d", t
->line_number
);
340 print_address_symbolic (t
->address
, gdb_stdout
, demangle
, " ");
342 if (t
->pass_count
!= 0)
343 printf_filtered (" passcount = %d", t
->pass_count
);
344 printf_filtered ("\n");
347 printf_filtered (" Actions for tracepoint %d: \n", t
->number
);
349 for (action
= t
->actions
; action
; action
= action
->next
)
352 actionline
= action
->action
;
353 while (isspace(*actionline
))
356 printf_filtered ("%s%s\n", indent
, actionline
);
357 if (0 == strncasecmp (actionline
, "while-stepping", 14))
359 else if (0 == strncasecmp (actionline
, "end", 3))
362 printf_filtered ("\t%s\n", action
->action
);
367 if (!found_a_tracepoint
)
370 printf_filtered ("No tracepoints.\n");
372 printf_filtered ("No tracepoint number %d.\n", tpnum
);
376 /* Optimization: the code to parse an enable, disable, or delete TP command
377 is virtually identical except for whether it performs an enable, disable,
378 or delete. Therefore I've combined them into one function with an opcode.
380 enum tracepoint_opcode
387 /* This function implements enable, disable and delete. */
389 tracepoint_operation (t
, from_tty
, opcode
)
390 struct tracepoint
*t
;
392 enum tracepoint_opcode opcode
;
394 struct tracepoint
*t2
;
395 struct action_line
*action
, *next
;
399 t
->enabled
= enabled
;
402 t
->enabled
= disabled
;
405 if (tracepoint_chain
== t
)
406 tracepoint_chain
= t
->next
;
415 free (t
->cond_string
);
417 free (t
->addr_string
);
419 free (t
->source_file
);
420 for (action
= t
->actions
; action
; action
= next
)
424 free (action
->action
);
432 /* Utility: parse a tracepoint number and look it up in the list. */
433 static struct tracepoint
*
434 get_tracepoint_by_number (arg
)
437 struct tracepoint
*t
;
443 error ("Bad tracepoint argument");
445 if (*arg
== 0 || **arg
== 0) /* empty arg means refer to last tp */
446 tpnum
= tracepoint_count
;
447 else if (**arg
== '$') /* handle convenience variable */
450 /* find end of convenience variable name */
451 while (**arg
&& **arg
!= ' ' && **arg
!= '\t')
453 /* null-terminate if necessary */
456 val
= value_of_internalvar (lookup_internalvar (cp
));
457 if (TYPE_CODE( VALUE_TYPE (val
)) != TYPE_CODE_INT
)
458 error ("Convenience variable must have integral type.");
459 tpnum
= (int) value_as_long (val
);
461 else /* handle tracepoint number */
463 tpnum
= strtol (*arg
, arg
, 10);
466 if (t
->number
== tpnum
)
470 warning ("No tracepoint number %d.\n", tpnum
);
474 /* Utility: parse a list of tracepoint numbers, and call a func for each. */
476 map_args_over_tracepoints (args
, from_tty
, opcode
)
479 enum tracepoint_opcode opcode
;
481 struct tracepoint
*t
;
485 if (args
== 0 || *args
== 0) /* do them all */
487 tracepoint_operation (t
, from_tty
, opcode
);
491 if (t
= get_tracepoint_by_number (&args
))
492 tracepoint_operation (t
, from_tty
, opcode
);
493 while (*args
== ' ' || *args
== '\t')
499 enable_trace_command (args
, from_tty
)
504 map_args_over_tracepoints (args
, from_tty
, enable
);
508 disable_trace_command (args
, from_tty
)
513 map_args_over_tracepoints (args
, from_tty
, disable
);
517 delete_trace_command (args
, from_tty
)
523 if (!query ("Delete all tracepoints? "))
526 map_args_over_tracepoints (args
, from_tty
, delete);
530 trace_pass_command (args
, from_tty
)
534 struct tracepoint
*t1
= (struct tracepoint
*) -1, *t2
;
537 if (args
== 0 || *args
== 0)
538 error ("PASS command requires an argument (count + optional TP num)");
540 count
= strtoul (args
, &args
, 10); /* count comes first, then TP num */
542 while (*args
&& isspace (*args
))
545 if (*args
&& strncasecmp (args
, "all", 3) == 0)
546 args
+= 3; /* skip special argument "all" */
548 t1
= get_tracepoint_by_number (&args
);
551 return; /* error, bad tracepoint number */
554 if (t1
== (struct tracepoint
*) -1 || t1
== t2
)
556 t2
->pass_count
= count
;
558 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
563 /* ACTIONS ACTIONS ACTIONS */
565 static void read_actions
PARAMS((struct tracepoint
*));
566 static void free_actions
PARAMS((struct tracepoint
*));
567 static int validate_actionline
PARAMS((char *, struct tracepoint
*));
570 trace_actions_command (args
, from_tty
)
574 struct tracepoint
*t
;
577 if (t
= get_tracepoint_by_number (&args
))
580 printf_filtered ("Enter actions for tracepoint %d, one per line.\n",
584 /* tracepoints_changed () */
586 /* else error, just return; */
599 struct tracepoint
*t
;
602 char *prompt1
= "> ", *prompt2
= " > ";
603 char *prompt
= prompt1
;
604 enum actionline_type linetype
;
605 extern FILE *instream
;
606 struct action_line
*next
= NULL
, *temp
;
607 struct cleanup
*old_chain
;
609 /* Control-C quits instantly if typed while in this loop
610 since it should not wait until the user types a newline. */
614 signal (STOP_SIGNAL
, stop_sig
);
616 old_chain
= make_cleanup (free_actions
, (void *) t
);
619 /* Make sure that all output has been output. Some machines may let
620 you get away with leaving out some of the gdb_flush, but not all. */
622 gdb_flush (gdb_stdout
);
623 gdb_flush (gdb_stderr
);
624 if (instream
== stdin
&& ISATTY (instream
))
625 line
= readline (prompt
);
627 line
= gdb_readline (0);
629 linetype
= validate_actionline (line
, t
);
630 if (linetype
== BADLINE
)
631 continue; /* already warned -- collect another line */
633 temp
= xmalloc (sizeof (struct action_line
));
637 if (next
== NULL
) /* first action for this tracepoint? */
638 t
->actions
= next
= temp
;
645 if (linetype
== STEPPING
) /* begin "while-stepping" */
646 if (prompt
== prompt2
)
648 warning ("Already processing 'while-stepping'");
652 prompt
= prompt2
; /* change prompt for stepping actions */
653 else if (linetype
== END
)
654 if (prompt
== prompt2
)
655 prompt
= prompt1
; /* end of single-stepping actions */
657 break; /* end of actions */
661 signal (STOP_SIGNAL
, SIG_DFL
);
664 discard_cleanups (old_chain
);
667 static enum actionline_type
668 validate_actionline (line
, t
)
670 struct tracepoint
*t
;
673 struct expression
*exp
;
674 value_ptr temp
, temp2
;
676 for (p
= line
; isspace (*p
); )
679 /* symbol lookup etc. */
680 if (*p
== '\0') /* empty line: just prompt for another line. */
682 else if (0 == strncasecmp (p
, "collect", 7))
685 do { /* repeat over a comma-separated list */
689 if (*p
== '$' && /* look for special pseudo-symbols */
690 ((0 == strncasecmp ("reg", p
+ 1, 3)) ||
691 (0 == strncasecmp ("arg", p
+ 1, 3)) ||
692 (0 == strncasecmp ("loc", p
+ 1, 3))))
693 p
= (char *) strchr (p
, ',');
696 exp
= parse_exp_1 (&p
, block_for_pc (t
->address
), 1);
697 if (exp
->elts
[0].opcode
!= OP_VAR_VALUE
&&
698 /*exp->elts[0].opcode != OP_LONG && */
699 /*exp->elts[0].opcode != UNOP_CAST && */
700 exp
->elts
[0].opcode
!= OP_REGISTER
)
702 warning ("collect: enter variable name or register.\n");
705 if (exp
->elts
[0].opcode
== OP_VAR_VALUE
)
706 if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_CONST
)
708 warning ("%s is constant (value %d): will not be collected.",
709 SYMBOL_NAME (exp
->elts
[2].symbol
),
710 SYMBOL_VALUE (exp
->elts
[2].symbol
));
713 else if (SYMBOL_CLASS (exp
->elts
[2].symbol
) == LOC_OPTIMIZED_OUT
)
715 warning ("%s is optimized away and cannot be collected.",
716 SYMBOL_NAME (exp
->elts
[2].symbol
));
720 } while (p
&& *p
++ == ',');
723 else if (0 == strncasecmp (p
, "while-stepping", 14))
725 char *steparg
; /* in case warning is necessary */
734 t
->step_count
= strtol (p
, &p
, 0);
735 if (t
->step_count
== 0)
737 warning ("'%s' evaluates to zero -- command ignored.");
745 else if (0 == strncasecmp (p
, "end", 3))
749 warning ("'%s' is not a supported tracepoint action.", p
);
756 struct tracepoint
*t
;
758 struct action_line
*line
, *next
;
760 for (line
= t
->actions
; line
; line
= next
)
769 int type
; /* 0 for absolute memory range, else basereg number */
770 bfd_signed_vma start
;
774 struct collection_list
{
775 unsigned char regs_mask
[8]; /* room for up to 256 regs */
778 struct memrange
*list
;
779 } tracepoint_list
, stepping_list
;
783 struct memrange
*a
, *b
;
785 if (a
->type
< b
->type
) return -1;
786 if (a
->type
> b
->type
) return 1;
789 if ((bfd_vma
) a
->start
< (bfd_vma
) b
->start
) return -1;
790 if ((bfd_vma
) a
->start
> (bfd_vma
) b
->start
) return 1;
794 if (a
->start
< b
->start
) return -1;
795 if (a
->start
> b
->start
) return 1;
801 memrange_sortmerge (memranges
)
802 struct collection_list
*memranges
;
806 qsort (memranges
->list
, memranges
->next_memrange
,
807 sizeof (struct memrange
), memrange_cmp
);
808 if (memranges
->next_memrange
> 0)
810 for (a
= 0, b
= 1; b
< memranges
->next_memrange
; b
++)
812 if (memranges
->list
[a
].type
== memranges
->list
[b
].type
&&
813 memranges
->list
[b
].start
- memranges
->list
[a
].end
<=
814 MAX_REGISTER_VIRTUAL_SIZE
)
816 memranges
->list
[a
].end
= memranges
->list
[b
].end
;
817 continue; /* next b, same a */
821 memcpy (&memranges
->list
[a
], &memranges
->list
[b
],
822 sizeof (struct memrange
));
824 memranges
->next_memrange
= a
+ 1;
829 add_register (collection
, regno
)
830 struct collection_list
*collection
;
834 printf_filtered ("collect register %d\n", regno
);
835 if (regno
> (8 * sizeof (collection
->regs_mask
)))
836 error ("Internal: register number %d too large for tracepoint",
838 collection
->regs_mask
[regno
/ 8] |= 1 << (regno
% 8);
842 add_memrange (memranges
, type
, base
, len
)
843 struct collection_list
*memranges
;
849 printf_filtered ("(%d,0x%x,%d)\n", type
, base
, len
);
850 /* type: 0 == memory, n == basereg */
851 memranges
->list
[memranges
->next_memrange
].type
= type
;
852 /* base: addr if memory, offset if reg relative. */
853 memranges
->list
[memranges
->next_memrange
].start
= base
;
854 /* len: we actually save end (base + len) for convenience */
855 memranges
->list
[memranges
->next_memrange
].end
= base
+ len
;
856 memranges
->next_memrange
++;
857 if (memranges
->next_memrange
>= memranges
->listsize
)
859 memranges
->listsize
*= 2;
860 memranges
->list
= xrealloc (memranges
->list
,
861 memranges
->listsize
);
864 if (type
!= 0) /* better collect the base register! */
865 add_register (memranges
, type
);
869 collect_symbol (collect
, sym
)
870 struct collection_list
*collect
;
875 bfd_signed_vma offset
;
877 len
= TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym
)));
878 switch (SYMBOL_CLASS (sym
)) {
880 printf_filtered ("%s: don't know symbol class %d\n",
881 SYMBOL_NAME (sym
), SYMBOL_CLASS (sym
));
884 printf_filtered ("%s is constant, value is %d: will not be collected.\n",
885 SYMBOL_NAME (sym
), SYMBOL_VALUE (sym
));
888 offset
= SYMBOL_VALUE_ADDRESS (sym
);
890 printf_filtered ("LOC_STATIC %s: collect %d bytes "
892 SYMBOL_NAME (sym
), len
, offset
);
893 add_memrange (collect
, 0, offset
, len
); /* 0 == memory */
897 reg
= SYMBOL_VALUE (sym
);
899 printf_filtered ("LOC_REG[parm] %s: ", SYMBOL_NAME (sym
));
900 add_register (collect
, reg
);
904 printf_filtered ("Sorry, don't know how to do LOC_ARGs yet.\n");
905 printf_filtered (" (will not collect %s)\n",
908 case LOC_REGPARM_ADDR
:
909 reg
= SYMBOL_VALUE (sym
);
913 printf_filtered ("LOC_REGPARM_ADDR %s: Collect %d bytes at offset %d from reg %d\n",
914 SYMBOL_NAME (sym
), len
, offset
, reg
);
916 add_memrange (collect
, reg
, offset
, len
);
920 offset
= SYMBOL_VALUE (sym
);
924 printf_filtered ("LOC_LOCAL %s: Collect %d bytes at offset %d from frame ptr reg %d\n",
925 SYMBOL_NAME (sym
), len
, offset
, reg
);
927 add_memrange (collect
, reg
, offset
, len
);
930 case LOC_BASEREG_ARG
:
931 reg
= SYMBOL_BASEREG (sym
);
932 offset
= SYMBOL_VALUE (sym
);
935 printf_filtered ("LOC_BASEREG %s: collect %d bytes at offset %d from basereg %d\n",
936 SYMBOL_NAME (sym
), len
, offset
, reg
);
938 add_memrange (collect
, reg
, offset
, len
);
941 printf_filtered ("Don't know LOC_UNRESOLVED %s\n", SYMBOL_NAME (sym
));
943 case LOC_OPTIMIZED_OUT
:
944 printf_filtered ("%s has been optimized out of existance.\n",
951 add_local_symbols (collect
, pc
, type
)
952 struct collection_list
*collect
;
958 int i
, nsyms
, count
= 0;
960 block
= block_for_pc (pc
);
963 nsyms
= BLOCK_NSYMS (block
);
964 for (i
= 0; i
< nsyms
; i
++)
966 sym
= BLOCK_SYM (block
, i
);
967 switch (SYMBOL_CLASS (sym
)) {
972 if (type
== 'L') /* collecting Locals */
975 collect_symbol (collect
, sym
);
982 case LOC_REGPARM_ADDR
:
983 case LOC_BASEREG_ARG
:
984 if (type
== 'A') /* collecting Arguments */
987 collect_symbol (collect
, sym
);
991 if (BLOCK_FUNCTION (block
))
994 block
= BLOCK_SUPERBLOCK (block
);
997 warning ("No %s found in scope.", type
== 'L' ? "locals" : "args");
1001 clear_collection_list (list
)
1002 struct collection_list
*list
;
1004 list
->next_memrange
= 0;
1005 memset (list
->regs_mask
, 0, sizeof (list
->regs_mask
));
1009 stringify_collection_list (list
, string
)
1010 struct collection_list
*list
;
1016 for (i
= sizeof (list
->regs_mask
) - 1; i
> 0; i
--)
1017 if (list
->regs_mask
[i
] != 0) /* skip leading zeroes in regs_mask */
1019 if (list
->regs_mask
[i
] != 0) /* prepare to send regs_mask to the stub */
1022 printf_filtered ("\nCollecting registers (mask): 0x");
1027 printf_filtered ("%02X", list
->regs_mask
[i
]);
1028 sprintf (end
, "%02X", list
->regs_mask
[i
]);
1033 printf_filtered ("\n");
1034 if (list
->next_memrange
> 0 && info_verbose
)
1035 printf_filtered ("Collecting memranges: \n");
1036 for (i
= 0; i
< list
->next_memrange
; i
++)
1039 printf_filtered ("(%d, 0x%x, %d)\n",
1041 list
->list
[i
].start
,
1042 list
->list
[i
].end
- list
->list
[i
].start
);
1043 sprintf (end
, "M%X,%X,%X",
1045 list
->list
[i
].start
,
1046 list
->list
[i
].end
- list
->list
[i
].start
);
1047 end
+= strlen (end
);
1056 encode_actions (t
, tdp_actions
, step_count
, stepping_actions
)
1057 struct tracepoint
*t
;
1059 unsigned long *step_count
;
1060 char **stepping_actions
;
1062 struct expression
*exp
;
1063 static char tdp_buff
[2048], step_buff
[2048];
1064 struct action_line
*action
;
1066 bfd_signed_vma offset
;
1068 struct collection_list
*collect
;
1070 clear_collection_list (&tracepoint_list
);
1071 clear_collection_list (&stepping_list
);
1072 collect
= &tracepoint_list
;
1074 *tdp_actions
= NULL
;
1075 *stepping_actions
= NULL
;
1077 for (action
= t
->actions
; action
; action
= action
->next
)
1079 action_exp
= action
->action
;
1080 while (isspace (*action_exp
))
1083 if (0 == strncasecmp (action_exp
, "collect", 7))
1085 action_exp
= action_exp
+ 7;
1086 do { /* repeat over a comma-separated list */
1087 while (isspace (*action_exp
))
1090 if (0 == strncasecmp ("$reg", action_exp
, 4))
1092 for (i
= 0; i
< NUM_REGS
; i
++)
1093 add_register (collect
, i
);
1094 action_exp
= (char *) strchr (action_exp
, ','); /* more? */
1096 else if (0 == strncasecmp ("$arg", action_exp
, 4))
1098 add_local_symbols (collect
, t
->address
, 'A');
1099 action_exp
= (char *) strchr (action_exp
, ','); /* more? */
1101 else if (0 == strncasecmp ("$loc", action_exp
, 4))
1103 add_local_symbols (collect
, t
->address
, 'L');
1104 action_exp
= (char *) strchr (action_exp
, ','); /* more? */
1108 unsigned long addr
, len
;
1110 exp
= parse_exp_1 (&action_exp
, block_for_pc (t
->address
), 1);
1111 switch (exp
->elts
[0].opcode
) {
1113 i
= exp
->elts
[1].longconst
;
1115 printf_filtered ("OP_REGISTER: ");
1116 add_register (collect
, i
);
1119 collect_symbol (collect
, exp
->elts
[2].symbol
);
1123 addr
= exp
->elts
[2].longconst
;
1124 if (*action_exp
== ':')
1126 exp
= parse_exp_1 (&action_exp
,
1127 block_for_pc (t
->address
),
1129 if (exp
->elts
[0].opcode
== OP_LONG
)
1130 len
= exp
->elts
[2].longconst
;
1132 error ("length field requires a literal long const");
1137 add_memrange (collect
, 0, addr
, len
);
1142 } while (action_exp
&& *action_exp
++ == ',');
1144 else if (0 == strncasecmp (action_exp
, "while-stepping", 14))
1146 collect
= &stepping_list
;
1148 else if (0 == strncasecmp (action_exp
, "end", 3))
1150 if (collect
== &stepping_list
) /* end stepping actions */
1151 collect
= &tracepoint_list
;
1153 break; /* end tracepoint actions */
1156 memrange_sortmerge (&tracepoint_list
);
1157 memrange_sortmerge (&stepping_list
);
1159 *tdp_actions
= stringify_collection_list (&tracepoint_list
, &tdp_buff
);
1160 *stepping_actions
= stringify_collection_list (&stepping_list
, &step_buff
);
1163 static char target_buf
[2048];
1166 trace_start_command (args
, from_tty
)
1169 { /* STUB_COMM MOSTLY_IMPLEMENTED */
1170 struct tracepoint
*t
;
1173 char *stepping_actions
;
1174 unsigned long step_count
;
1176 dont_repeat (); /* like "run", dangerous to repeat accidentally */
1178 if (target_is_remote ())
1181 remote_get_noisy_reply (target_buf
);
1182 if (strcmp (target_buf
, "OK"))
1183 error ("Target does not support this command.");
1187 int ss_count
; /* if actions include singlestepping */
1188 int disable_mask
; /* ??? */
1189 int enable_mask
; /* ??? */
1191 sprintf (buf
, "QTDP:%x:%x:%c:%x:%x", t
->number
, t
->address
,
1192 t
->enabled
== enabled
? 'E' : 'D',
1193 t
->step_count
, t
->pass_count
);
1196 encode_actions (t
, &tdp_actions
, &step_count
, &stepping_actions
);
1197 /* do_single_steps (t); */
1200 if (strlen (buf
) + strlen (tdp_actions
) >= sizeof (buf
))
1201 error ("Actions for tracepoint %d too complex; "
1202 "please simplify.", t
->number
);
1203 strcat (buf
, tdp_actions
);
1205 if (stepping_actions
)
1208 if (strlen (buf
) + strlen (stepping_actions
) >= sizeof (buf
))
1209 error ("Actions for tracepoint %d too complex; "
1210 "please simplify.", t
->number
);
1211 strcat (buf
, stepping_actions
);
1215 remote_get_noisy_reply (target_buf
);
1216 if (strcmp (target_buf
, "OK"))
1217 error ("Target does not support tracepoints.");
1220 remote_get_noisy_reply (target_buf
);
1221 if (strcmp (target_buf
, "OK"))
1222 error ("Bogus reply from target: %s", target_buf
);
1225 printf_filtered ("Trace can only be run on remote targets.\n");
1229 trace_stop_command (args
, from_tty
)
1232 { /* STUB_COMM IS_IMPLEMENTED */
1233 if (target_is_remote ())
1236 remote_get_noisy_reply (target_buf
);
1237 if (strcmp (target_buf
, "OK"))
1238 error ("Bogus reply from target: %s", target_buf
);
1241 error ("Trace can only be run on remote targets.");
1245 trace_status_command (args
, from_tty
)
1248 { /* STUB_COMM IS_IMPLEMENTED */
1249 if (target_is_remote ())
1251 putpkt ("qTStatus");
1252 remote_get_noisy_reply (target_buf
);
1253 if (strcmp (target_buf
, "OK"))
1254 error ("Bogus reply from target: %s", target_buf
);
1257 error ("Trace can only be run on remote targets.");
1261 trace_buff_command (args
, from_tty
)
1264 { /* STUB_COMM NOT_IMPLEMENTED */
1265 if (args
== 0 || *args
== 0)
1266 printf_filtered ("TBUFFER command requires argument (on or off)\n");
1267 else if (strcasecmp (args
, "on") == 0)
1268 printf_filtered ("tbuffer overflow on.\n");
1269 else if (strcasecmp (args
, "off") == 0)
1270 printf_filtered ("tbuffer overflow off.\n");
1272 printf_filtered ("TBUFFER: unknown argument (use on or off)\n");
1276 trace_limit_command (args
, from_tty
)
1279 { /* STUB_COMM NOT_IMPLEMENTED */
1280 printf_filtered ("Limit it to what?\n");
1284 trace_find_command (args
, from_tty
)
1287 { /* STUB_COMM PART_IMPLEMENTED */
1288 /* this should only be called with a numeric argument */
1289 int frameno
, target_frameno
;
1292 if (target_is_remote ())
1294 if (args
== 0 || *args
== 0)
1295 frameno
= traceframe_number
+ 1;
1296 else if (*args
!= '-' && !isdigit(*args
))
1297 error ("tfind requires a literal (for now): %s rejected.", args
);
1299 frameno
= strtol (args
, 0, 0); /* for now, literals only */
1301 sprintf (buf
, "QTFrame:%x", frameno
);
1303 remote_get_noisy_reply (target_buf
);
1305 if (target_buf
[0] != 'F')
1306 error ("Bogus reply from target: %s", target_buf
);
1307 target_frameno
= strtol (&target_buf
[1], &tmp
, 16);
1308 if (tmp
== &target_buf
[1])
1309 error ("Bogus reply from target: %s", target_buf
);
1310 if (target_frameno
!= frameno
)
1311 warning ("Target replied with different framenumber, %s != %x",
1312 target_buf
, frameno
);
1314 set_traceframe_num (target_frameno
);
1315 flush_cached_frames ();
1316 registers_changed ();
1317 select_frame (get_current_frame (), 0);
1320 error ("Trace can only be run on remote targets.");
1324 trace_find_pc_command (args
, from_tty
)
1327 { /* STUB_COMM PART_IMPLEMENTED */
1332 if (target_is_remote ())
1334 if (args
== 0 || *args
== 0)
1335 { /* TFIND PC <no args> is the same as TFIND <no args> */
1336 trace_find_command (args
, from_tty
);
1339 if (!isdigit(*args
))
1340 error ("tfind pc requires a literal argument (for now): %s rejected.",
1343 pc
= strtol (args
, 0, 0); /* for now, literals only */
1344 sprintf (buf
, "QTFrame:pc:%x", pc
);
1346 remote_get_noisy_reply (target_buf
);
1348 if (target_buf
[0] != 'F')
1349 error ("Bogus reply from target: %s", target_buf
);
1350 target_frameno
= strtol (&target_buf
[1], &tmp
, 16);
1351 if (tmp
== &target_buf
[1])
1352 error ("Bogus reply from target: %s", target_buf
);
1354 set_traceframe_num (target_frameno
);
1355 flush_cached_frames ();
1356 registers_changed ();
1357 select_frame (get_current_frame (), 0);
1360 error ("Trace can only be run on remote targets.");
1364 trace_find_tdp_command (args
, from_tty
)
1367 { /* STUB_COMM PART_IMPLEMENTED */
1368 int target_frameno
, tdp
;
1371 if (target_is_remote ())
1373 if (args
== 0 || *args
== 0)
1374 { /* TFIND TDP <no args> is the same as TFIND <no args> */
1375 trace_find_command (args
, from_tty
);
1378 if (!isdigit(*args
))
1379 error ("tfind tdp command requires a literal argument (for now): %s",
1382 tdp
= strtol (args
, 0, 0); /* for now, literals only */
1383 sprintf (buf
, "QTFrame:tdp:%x", tdp
);
1385 remote_get_noisy_reply (target_buf
);
1387 if (target_buf
[0] != 'F')
1388 error ("Bogus reply from target: %s", target_buf
);
1389 target_frameno
= strtol (&target_buf
[1], &tmp
, 16);
1390 if (tmp
== &target_buf
[1])
1391 error ("Bogus reply from target: %s", target_buf
);
1393 set_traceframe_num (target_frameno
);
1394 flush_cached_frames ();
1395 registers_changed ();
1396 select_frame (get_current_frame (), 0);
1399 error ("Trace can only be run on remote targets.");
1403 trace_find_range_command (args
, from_tty
)
1406 { /* STUB_COMM PART_IMPLEMENTED */
1407 static CORE_ADDR start
, stop
;
1411 if (target_is_remote ())
1413 if (args
== 0 || *args
== 0 || !isdigit(*args
))
1414 { /* XXX FIXME: what should default behavior be? */
1415 printf_filtered ("Usage: tfind range <address> <address>\n");
1419 start
= strtol (args
, &args
, 0); /* for now, literals only */
1420 while (args
&& *args
&& isspace (*args
))
1423 if (args
== 0 || *args
== 0 || !isdigit(*args
))
1425 printf_filtered ("Usage: tfind range <address> <address>\n");
1429 stop
= strtol (args
, &args
, 0); /* for now, literals only */
1431 sprintf (buf
, "QTFrame:range:%x:%x", start
, stop
);
1433 remote_get_noisy_reply (target_buf
);
1435 if (target_buf
[0] != 'F')
1436 error ("Bogus reply from target: %s", target_buf
);
1437 target_frameno
= strtol (&target_buf
[1], &tmp
, 16);
1438 if (tmp
== &target_buf
[1])
1439 error ("Bogus reply from target: %s", target_buf
);
1441 set_traceframe_num (target_frameno
);
1442 flush_cached_frames ();
1443 registers_changed ();
1444 select_frame (get_current_frame (), 0);
1447 error ("Trace can only be run on remote targets.");
1451 trace_find_outside_command (args
, from_tty
)
1454 { /* STUB_COMM PART_IMPLEMENTED */
1455 CORE_ADDR start
, stop
;
1459 if (target_is_remote ())
1461 if (args
== 0 || *args
== 0 || !isdigit(*args
))
1462 { /* XXX FIXME: what should default behavior be? */
1463 printf_filtered ("Usage: tfind outside <address> <address>\n");
1467 start
= strtol (args
, &args
, 0);
1468 while (args
&& *args
&& isspace (*args
))
1471 if (args
== 0 || *args
== 0 || !isdigit(*args
))
1473 printf_filtered ("Usage: tfind outside <address> <address>\n");
1477 stop
= strtol (args
, &args
, 0);
1479 sprintf (buf
, "QTFrame:outside:%x:%x", start
, stop
);
1481 remote_get_noisy_reply (target_buf
);
1483 if (target_buf
[0] != 'F')
1484 error ("Bogus reply from target: %s", target_buf
);
1485 target_frameno
= strtol (&target_buf
[1], &tmp
, 16);
1486 if (tmp
== &target_buf
[1])
1487 error ("Bogus reply from target: %s", target_buf
);
1489 set_traceframe_num (target_frameno
);
1490 flush_cached_frames ();
1491 registers_changed ();
1492 select_frame (get_current_frame (), 0);
1495 error ("Trace can only be run on remote targets.");
1499 trace_display_command (args
, from_tty
)
1502 { /* STUB_COMM NOT_IMPLEMENTED */
1503 if (!target_is_remote ())
1505 printf_filtered ("Trace can only be run on remote targets.\n");
1510 printf_filtered ("Displaying trace as %s.\n", args
);
1512 printf_filtered ("Displaying trace.\n");
1516 tracepoint_save_command (args
, from_tty
)
1520 struct tracepoint
*tp
;
1521 struct action_line
*line
;
1523 char *i1
= " ", *i2
= " ";
1524 char *indent
, *actionline
;
1526 if (args
== 0 || *args
== 0)
1527 error ("Argument required (file name in which to save tracepoints");
1529 if (tracepoint_chain
== 0)
1531 warning ("save-tracepoints: no tracepoints to save.\n");
1535 if (!(fp
= fopen (args
, "w")))
1536 error ("Unable to open file '%s' for saving tracepoints");
1538 ALL_TRACEPOINTS (tp
)
1540 if (tp
->addr_string
)
1541 fprintf (fp
, "trace %s\n", tp
->addr_string
);
1543 fprintf (fp
, "trace *0x%x\n", tp
->address
);
1546 fprintf (fp
, " passcount %d\n", tp
->pass_count
);
1550 fprintf (fp
, " actions\n");
1552 for (line
= tp
->actions
; line
; line
= line
->next
)
1554 actionline
= line
->action
;
1555 while (isspace(*actionline
))
1558 fprintf (fp
, "%s%s\n", indent
, actionline
);
1559 if (0 == strncasecmp (actionline
, "while-stepping", 14))
1561 else if (0 == strncasecmp (actionline
, "end", 3))
1568 printf_filtered ("Tracepoints saved to file '%s'.\n", args
);
1573 scope_info (args
, from_tty
)
1577 struct symtab_and_line sal
;
1578 struct symtabs_and_lines sals
;
1580 struct block
*block
;
1581 char **canonical
, *save_args
= args
, *symname
;
1582 int i
, nsyms
, count
= 0;
1583 enum address_class aclass
;
1585 if (args
== 0 || *args
== 0)
1586 error ("requires an argument (function, line or *addr) to define a scope");
1588 sals
= decode_line_1 (&args
, 1, NULL
, 0, &canonical
);
1589 if (sals
.nelts
== 0)
1590 return; /* presumably decode_line_1 has already warned */
1592 printf_filtered ("Block for %s", save_args
);
1593 /* Resolve all line numbers to PC's */
1594 for (i
= 0; i
< sals
.nelts
; i
++)
1595 resolve_sal_pc (&sals
.sals
[i
]);
1597 block
= block_for_pc (sals
.sals
[0].pc
);
1600 nsyms
= BLOCK_NSYMS (block
);
1601 for (i
= 0; i
< nsyms
; i
++)
1604 sym
= BLOCK_SYM (block
, i
);
1605 switch (SYMBOL_CLASS (sym
)) {
1607 case LOC_UNDEF
: /* messed up symbol? */
1608 symname
= SYMBOL_NAME (sym
);
1609 if (symname
&& *symname
) /* guard against messed up name */
1610 printf_filtered ("Bogus symbol %s, class %d\n",
1611 symname
, SYMBOL_CLASS (sym
));
1613 printf_filtered ("Completely bogus symbol, class %d.\n",
1614 SYMBOL_CLASS (sym
));
1615 count
--; /* don't count this one */
1617 case LOC_CONST
: printf_filtered ("\nConstant "); break;
1618 case LOC_STATIC
: printf_filtered ("\nStatic "); break;
1619 case LOC_REGISTER
: printf_filtered ("\nRegister "); break;
1620 case LOC_ARG
: printf_filtered ("\nArg "); break;
1621 case LOC_REF_ARG
: printf_filtered ("\nReference Arg "); break;
1622 case LOC_REGPARM
: printf_filtered ("\nRegister Arg "); break;
1623 case LOC_REGPARM_ADDR
:
1624 printf_filtered ("\nIndirect Register Arg "); break;
1625 case LOC_LOCAL
: printf_filtered ("\nStack Local "); break;
1626 case LOC_TYPEDEF
: printf_filtered ("\nLocal Typedef "); break;
1627 case LOC_LABEL
: printf_filtered ("\nLocal Label "); break;
1628 case LOC_BLOCK
: printf_filtered ("\nLocal Function "); break;
1629 case LOC_CONST_BYTES
: printf_filtered ("\nLoc. Byte Seq. "); break;
1630 case LOC_LOCAL_ARG
: printf_filtered ("\nStack Arg "); break;
1631 case LOC_BASEREG
: printf_filtered ("\nBasereg Local "); break;
1632 case LOC_BASEREG_ARG
: printf_filtered ("\nBasereg Arg "); break;
1633 case LOC_UNRESOLVED
:
1634 printf_filtered ("\nUnresolved Static "); break;
1635 case LOC_OPTIMIZED_OUT
: printf_filtered ("\nOptimized-Out "); break;
1637 type_print (SYMBOL_TYPE (sym
), SYMBOL_NAME (sym
), gdb_stdout
, -1);
1639 if (BLOCK_FUNCTION (block
))
1642 block
= BLOCK_SUPERBLOCK (block
);
1645 printf_filtered (" contains no locals or arguments.");
1646 printf_filtered ("\n");
1649 static struct cmd_list_element
*tfindlist
;
1650 static struct cmd_list_element
*tracelist
;
1653 _initialize_tracepoint ()
1655 tracepoint_chain
= 0;
1656 tracepoint_count
= 0;
1657 traceframe_number
= 0;
1659 set_internalvar (lookup_internalvar ("tpnum"),
1660 value_from_longest (builtin_type_int
, (LONGEST
) 0));
1661 set_internalvar (lookup_internalvar ("trace_frame"),
1662 value_from_longest (builtin_type_int
, (LONGEST
) 0));
1664 if (tracepoint_list
.list
== NULL
)
1666 tracepoint_list
.listsize
= 128;
1667 tracepoint_list
.list
= xmalloc
1668 (tracepoint_list
.listsize
* sizeof (struct memrange
));
1670 if (stepping_list
.list
== NULL
)
1672 stepping_list
.listsize
= 128;
1673 stepping_list
.list
= xmalloc
1674 (stepping_list
.listsize
* sizeof (struct memrange
));
1677 add_info ("scope", scope_info
,
1678 "List the variables local to a scope");
1681 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
1682 "Tracing program execution without stopping the program.",
1685 add_info ("tracepoints", tracepoints_info
,
1686 "Display tracepoints, or tracepoint number NUMBER.\n"
1687 "Convenience variable \"$tpnum\" contains the number of the\n"
1688 "last tracepoint set.");
1690 add_info_alias ("tp", "tracepoints", 1);
1692 add_com ("save-tracepoints", class_trace
, tracepoint_save_command
,
1693 "Save current tracepoint definitions as a script.\n"
1694 "Use the SOURCE command in another debug session to restore them.");
1696 add_com ("tlimit", class_trace
, trace_limit_command
,
1697 "Not sure what this should do yet....");
1699 add_com ("tbuffer", class_trace
, trace_buff_command
,
1700 "See also 'set trace buffer overflow'.");
1702 add_prefix_cmd ("tfind", class_trace
,
1704 "Select a trace frame (default by frame number).",
1705 &tfindlist
, "tfind ", 1, &cmdlist
);
1707 add_cmd ("outside", class_trace
, trace_find_outside_command
,
1708 "Select a trace frame by falling outside of a PC range",
1711 add_cmd ("range", class_trace
, trace_find_range_command
,
1712 "Select a trace frame by PC range", &tfindlist
);
1714 add_cmd ("tdp", class_trace
, trace_find_tdp_command
,
1715 "Select a trace frame by TDP", &tfindlist
);
1717 add_cmd ("pc", class_trace
, trace_find_pc_command
,
1718 "Select a trace frame by PC", &tfindlist
);
1720 add_com ("tdisplay", class_trace
, trace_display_command
,
1721 "Display the results of a trace");
1723 add_com ("tstatus", class_trace
, trace_status_command
,
1724 "Inquire about trace data collection status.");
1726 add_com ("tstop", class_trace
, trace_stop_command
,
1727 "Stop trace data collection.");
1729 add_com ("tstart", class_trace
, trace_start_command
,
1730 "Start trace data collection.");
1732 add_com ("passcount", class_trace
, trace_pass_command
,
1733 "Set the passcount for a tracepoint.\n"
1734 "The trace will end when the tracepoint has been passed "
1736 "Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\",\n"
1737 "or if omitted refers to the last tracepoint defined.");
1739 add_com ("actions", class_trace
, trace_actions_command
,
1740 "Specify the actions to be taken at a tracepoint.\n"
1741 "Actions can include collection of data, enabling or \n"
1742 "disabling other tracepoints, or ending the trace.");
1744 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
1745 "Delete specified tracepoints; or with no argument, delete all.",
1748 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
1749 "Disable specified tracepoints; or with no argument, disable all.",
1752 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
1753 "Enable specified tracepoints; or with no argument, enable all.",
1756 add_com ("trace", class_trace
, trace_command
,
1757 "Set a tracepoint at a specified line, function, or address.\n"
1758 "Argument may be a line number, function name, or "
1759 "'*' plus an address.\n"
1760 "For a line number or function, trace at the start of its code.\n"
1761 "If an address is specified, trace at that exact address.");
1763 add_com_alias ("tp", "trace", class_alias
, 0);
1764 add_com_alias ("tr", "trace", class_alias
, 1);
1765 add_com_alias ("tra", "trace", class_alias
, 1);
1766 add_com_alias ("trac", "trace", class_alias
, 1);
1769 #else /* command set based on TRACE as a prefix (incomplete) */
1770 add_cmd ("tracepoints", class_trace
, NO_FUNCTION
,
1771 "Tracing program execution without stopping the program.",
1774 add_prefix_cmd ("trace", class_trace
, trace_command
,
1775 "prefix for tracing commands",
1776 &tracelist
, "trace ", 1, &cmdlist
);
1778 add_cmd ("limit", class_trace
, trace_limit_command
,
1779 "Not sure what the hell this does....", &tracelist
);
1781 add_cmd ("buffer", class_trace
, trace_buff_command
,
1782 "See also 'set trace buffer overflow'.", &tracelist
);
1784 add_prefix_cmd ("find", class_trace
, trace_find_command
,
1785 "Select a trace frame (default by frame number).",
1786 &tfindlist
, "trace find ", 1, &tracelist
);
1788 add_cmd ("outside", class_trace
, trace_find_outside_command
,
1789 "Select a tracepoint by falling outside of a PC range.",
1792 add_cmd ("range", class_trace
, trace_find_range_command
,
1793 "Select a tracepoint by PC range.",
1796 add_cmd ("pc", class_trace
, trace_find_pc_command
,
1797 "Select a tracepoint by PC.",
1800 add_cmd ("display", class_trace
, trace_display_command
,
1801 "Display the results of a trace.", &tracelist
);
1803 add_cmd ("delete", class_trace
, delete_trace_command
,
1804 "Delete some tracepoints; no argument means all.", &tracelist
);
1806 add_cmd ("disable", class_trace
, disable_trace_command
,
1807 "Disable some tracepoints; no argument means all.", &tracelist
);
1809 add_cmd ("enable", class_trace
, enable_trace_command
,
1810 "Enable some tracepoints; no argument means all.", &tracelist
);
1812 add_cmd ("tracepoints", class_trace
, delete_trace_command
,
1813 "Delete some tracepoints; no argument means all.",
1816 add_cmd ("tracepoints", class_trace
, disable_trace_command
,
1817 "Disable some tracepoints; no argument means all.",
1820 add_cmd ("tracepoints", class_trace
, enable_trace_command
,
1821 "Enable some tracepoints; no argument means all.",
1824 add_cmd ("at", class_trace
, trace_command
,
1825 "Set a tracepoint at a specified line or function.\n"
1826 "Argument may be a line number, function name, or "
1827 "'*' and an address.\n"
1828 "For a line number or function, trace from the start of "
1830 "If an address is specified, trace at that exact address.\n"
1831 "With no arg, uses current execution address of "
1832 "selected stack frame.\n"
1833 "This is useful for breaking on return to a stack frame.",
1836 add_cmd ("status", class_trace
, trace_status_command
,
1837 "Inquire about trace data collection status.", &tracelist
);
1839 add_cmd ("stop", class_trace
, trace_stop_command
,
1840 "Stop trace data collection.", &tracelist
);
1842 add_cmd ("start", class_trace
, trace_start_command
,
1843 "Start trace data collection.", &tracelist
);
1845 add_cmd ("info", class_info
, tracepoints_info
,
1846 "Status of tracepoints, or tracepoint number NUMBER.\n"
1847 "The \"Address\" and \"What\" columns indicate the\n"
1848 "address and file/line number respectively.\n\n"
1849 "Convenience variable \"$tpnum\" contains the number of the\n"
1850 "last tracepoint set.",
1853 add_info ("tracepoints", tracepoints_info
,
1854 "Status of tracepoints, or tracepoint number NUMBER.\n"
1855 "The \"Address\" and \"What\" columns indicate the\n"
1856 "address and file/line number respectively.\n\n"
1857 "Convenience variable \"$tpnum\" contains the number of the\n"
1858 "last tracepoint set.");
1860 add_info_alias ("tp", "tracepoints", 1);