2009-03-30 Stan Shebs <stan@codesourcery.com>

Make tracepoints into a type of breakpoint.
	* breakpoint.h (enum bptype): Add bp_tracepoint.
	(struct breakpoint): Add fields step_count, pass_count, actions.
	(get_tracepoint, get_tracepoint_by_number): Declare.
	(all_tracepoints): Declare.
	* breakpoint.c: Include tracepoint.h, readline.h.
	(ALL_TRACEPOINTS): Move here from tracepoint.c.
	(tracepoint_count): Ditto.
	(should_be_inserted): GDB does not insert tracepoints itself.
	(print_it_typical): Add tracepoint case.
	(bpstat_what): Ditto.
	(print_one_breakpoint_location): Ditto, and add printing for
	pass count, step count, and action list.
	(user_settable_breakpoint): Add tracepoint case.
	(allocate_bp_location): Ditto.
	(set_breakpoint_location_function): Ditto.
	(disable_breakpoints_in_shlibs): Ditto.
	(mention): Ditto.
	(break_command_really): Add argument traceflag, use to choose
	basic breakpoint type.
	(break_command_1): Pass extra argument.
	(set_breakpoint, handle_gnu_v3_exceptions): Ditto.
	(breakpoint_re_set_one): Add tracepoint case.
	(disable_command, enable_command): Ditto.
	(set_tracepoint_count): Move here from tracepoint.c.
	(trace_command): Move here from tracepoint.c and use
	break_command_really.
	(tracepoints_info): Move here from tracepoint.c and call
	breakpoints_info.
	(enable_trace_command): Move here from tracepoint.c and call
	enable_command.
	(disable_trace_command): Move here from tracepoint.c and call
	disable_command.
	(delete_trace_command): Move here from tracepoint.c and call
	delete_breakpoint.
	(trace_pass_command): Move here from tracepoint.c.
	(get_tracepoint_by_number): Ditto.
	(tracepoint_save_command): Ditto.
	(get_tracepoint): New function.
	(all_tracepoints): New function.
	(_initialize_breakpoint): Move tracepoint init from tracepoint.c,
	deprecate "enable trace" and "disable trace" commands.
	* tracepoint.h (struct tracepoint): Remove.
	(tracepoint_chain): Remove decl.
	(deprecated_create_tracepoint_hook): Remove decl.
	(deprecated_delete_tracepoint_hook): Remove decl.
	(deprecated_modify_tracepoint_hook): Remove decl.
	(ALL_TRACEPOINTS, ALL_TRACEPOINTS_SAFE): Remove.
	(free_actions): Update signature.
	(validate_actionline): Update signature.
	(end_actions_pseudocommand): Declare.
	(while_stepping_pseudocommand): Declare.
	* tracepoint.c: Include breakpoint.h.
	(tracepoint_chain, tracepoint_count): Remove.
	(free_actions, make_cleanup_free_actions): Update signature.
	(trace_command, set_raw_tracepoint): Remove.
	(trace_mention): Remove.
	(tracepoints_info): Remove.
	(tracepoint_operation, map_args_over_tracepoints): Remove.
	(get_tracepoint_by_number): Remove.
	(enable_trace_command, disable_trace_command): Remove.
	(delete_trace_command, trace_pass_command): Remove.
	(trace_actions_command, read_actions): Update signature.
	(validate_actionline): Update signature, use bp loc.
	(encode_actions): Ditto.
	(download_tracepoint): New function, body of trace_start_command.
	(trace_start_command): Call it, use all_tracepoints.
	(tracepoint_save_command): Remove.
	(tracepoint_dump_command): Use get_tracepoint.
	(end_actions_pseudocommand): Make globally visible.
	(while_stepping_pseudocommand): Ditto.
	(_initialize_tracepoint): Move command definitions to breakpoint.c.

	doc/
	* gdb.texinfo (Tracepoints): Describe tracepoints as a
	special case of breakpoints.
	(Enable and Disable Tracepoints): Mention deprecation.
	(Listing Tracepoints): Update description and example.

	testsuite/
	* gdb.trace/actions.exp: Update to match new info trace format.
	* gdb.trace/deltrace.exp: Ditto.
	* gdb.trace/infotrace.exp: Ditto.
	* gdb.trace/passcount.exp: Ditto.
	* gdb.trace/save-trace.exp: Ditto.
	* gdb.trace/while-stepping.exp: Ditto.
	* gdb.trace/tracecmd.exp: Ditto, plus don't allow pending option.

	gdbtk/
	* generic/gdbtk-bp.c (gdb_actions_command): Update to handle
	tracepoints as breakpoints.
	(gdb_get_tracepoint_info): Ditto, plus use get_tracepoint and
	breakpoint locations.
	(tracepoint_exists): Ditto, plus use all_tracepoints.
This commit is contained in:
Stan Shebs 2009-03-31 05:08:37 +00:00
parent adfd732835
commit 1042e4c058
15 changed files with 903 additions and 932 deletions

View File

@ -1,3 +1,78 @@
2009-03-30 Stan Shebs <stan@codesourcery.com>
Make tracepoints into a type of breakpoint.
* breakpoint.h (enum bptype): Add bp_tracepoint.
(struct breakpoint): Add fields step_count, pass_count, actions.
(get_tracepoint, get_tracepoint_by_number): Declare.
(all_tracepoints): Declare.
* breakpoint.c: Include tracepoint.h, readline.h.
(ALL_TRACEPOINTS): Move here from tracepoint.c.
(tracepoint_count): Ditto.
(should_be_inserted): GDB does not insert tracepoints itself.
(print_it_typical): Add tracepoint case.
(bpstat_what): Ditto.
(print_one_breakpoint_location): Ditto, and add printing for
pass count, step count, and action list.
(user_settable_breakpoint): Add tracepoint case.
(allocate_bp_location): Ditto.
(set_breakpoint_location_function): Ditto.
(disable_breakpoints_in_shlibs): Ditto.
(mention): Ditto.
(break_command_really): Add argument traceflag, use to choose
basic breakpoint type.
(break_command_1): Pass extra argument.
(set_breakpoint, handle_gnu_v3_exceptions): Ditto.
(breakpoint_re_set_one): Add tracepoint case.
(disable_command, enable_command): Ditto.
(set_tracepoint_count): Move here from tracepoint.c.
(trace_command): Move here from tracepoint.c and use
break_command_really.
(tracepoints_info): Move here from tracepoint.c and call
breakpoints_info.
(enable_trace_command): Move here from tracepoint.c and call
enable_command.
(disable_trace_command): Move here from tracepoint.c and call
disable_command.
(delete_trace_command): Move here from tracepoint.c and call
delete_breakpoint.
(trace_pass_command): Move here from tracepoint.c.
(get_tracepoint_by_number): Ditto.
(tracepoint_save_command): Ditto.
(get_tracepoint): New function.
(all_tracepoints): New function.
(_initialize_breakpoint): Move tracepoint init from tracepoint.c,
deprecate "enable trace" and "disable trace" commands.
* tracepoint.h (struct tracepoint): Remove.
(tracepoint_chain): Remove decl.
(deprecated_create_tracepoint_hook): Remove decl.
(deprecated_delete_tracepoint_hook): Remove decl.
(deprecated_modify_tracepoint_hook): Remove decl.
(ALL_TRACEPOINTS, ALL_TRACEPOINTS_SAFE): Remove.
(free_actions): Update signature.
(validate_actionline): Update signature.
(end_actions_pseudocommand): Declare.
(while_stepping_pseudocommand): Declare.
* tracepoint.c: Include breakpoint.h.
(tracepoint_chain, tracepoint_count): Remove.
(free_actions, make_cleanup_free_actions): Update signature.
(trace_command, set_raw_tracepoint): Remove.
(trace_mention): Remove.
(tracepoints_info): Remove.
(tracepoint_operation, map_args_over_tracepoints): Remove.
(get_tracepoint_by_number): Remove.
(enable_trace_command, disable_trace_command): Remove.
(delete_trace_command, trace_pass_command): Remove.
(trace_actions_command, read_actions): Update signature.
(validate_actionline): Update signature, use bp loc.
(encode_actions): Ditto.
(download_tracepoint): New function, body of trace_start_command.
(trace_start_command): Call it, use all_tracepoints.
(tracepoint_save_command): Remove.
(tracepoint_dump_command): Use get_tracepoint.
(end_actions_pseudocommand): Make globally visible.
(while_stepping_pseudocommand): Ditto.
(_initialize_tracepoint): Move command definitions to breakpoint.c.
2009-03-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
Expose frames to Python.

View File

@ -25,6 +25,7 @@
#include "symtab.h"
#include "frame.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "gdbtypes.h"
#include "expression.h"
#include "gdbcore.h"
@ -58,6 +59,13 @@
#include "wrapper.h"
#include "valprint.h"
/* readline include files */
#include "readline/readline.h"
#include "readline/history.h"
/* readline defines this. */
#undef savestring
#include "mi/mi-common.h"
/* Arguments to pass as context to some catch command handlers. */
@ -191,6 +199,16 @@ static int is_hardware_watchpoint (struct breakpoint *bpt);
static void insert_breakpoint_locations (void);
static void tracepoints_info (char *, int);
static void delete_trace_command (char *, int);
static void enable_trace_command (char *, int);
static void disable_trace_command (char *, int);
static void trace_pass_command (char *, int);
/* Flag indicating that a command has proceeded the inferior past the
current breakpoint. */
@ -314,6 +332,12 @@ static int overlay_events_enabled;
B ? (TMP=B->global_next, 1): 0; \
B = TMP)
/* Iterator for tracepoints only. */
#define ALL_TRACEPOINTS(B) \
for (B = breakpoint_chain; B; B = B->next) \
if ((B)->type == bp_tracepoint)
/* Chains of all breakpoints defined. */
struct breakpoint *breakpoint_chain;
@ -329,6 +353,10 @@ VEC(bp_location_p) *moribund_locations = NULL;
int breakpoint_count;
/* Number of last tracepoint made. */
int tracepoint_count;
/* Return whether a breakpoint is an active enabled breakpoint. */
static int
breakpoint_enabled (struct breakpoint *b)
@ -1029,6 +1057,11 @@ should_be_inserted (struct bp_location *bpt)
if (!bpt->enabled || bpt->shlib_disabled || bpt->duplicate)
return 0;
/* Tracepoints are inserted by the target at a time of its choosing,
not by us. */
if (bpt->owner->type == bp_tracepoint)
return 0;
return 1;
}
@ -2423,6 +2456,7 @@ print_it_typical (bpstat bs)
case bp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_tracepoint:
default:
result = PRINT_UNKNOWN;
break;
@ -3324,6 +3358,13 @@ bpstat_what (bpstat bs)
bs_class = bp_silent;
retval.call_dummy = 1;
break;
case bp_tracepoint:
/* Tracepoint hits should not be reported back to GDB, and
if one got through somehow, it should have been filtered
out already. */
internal_error (__FILE__, __LINE__,
_("bpstat_what: bp_tracepoint encountered"));
break;
}
current_action = table[(int) bs_class][(int) current_action];
}
@ -3423,6 +3464,7 @@ print_one_breakpoint_location (struct breakpoint *b,
{bp_thread_event, "thread events"},
{bp_overlay_event, "overlay events"},
{bp_catchpoint, "catchpoint"},
{bp_tracepoint, "tracepoint"},
};
static char bpenables[] = "nynny";
@ -3549,6 +3591,7 @@ print_one_breakpoint_location (struct breakpoint *b,
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_tracepoint:
if (opts.addressprint)
{
annotate_field (4);
@ -3593,7 +3636,10 @@ print_one_breakpoint_location (struct breakpoint *b,
because the condition is an internal implementation detail
that we do not want to expose to the user. */
annotate_field (7);
ui_out_text (uiout, "\tstop only if ");
if (b->type == bp_tracepoint)
ui_out_text (uiout, "\ttrace only if ");
else
ui_out_text (uiout, "\tstop only if ");
ui_out_field_string (uiout, "cond", b->cond_string);
ui_out_text (uiout, "\n");
}
@ -3645,6 +3691,34 @@ print_one_breakpoint_location (struct breakpoint *b,
do_cleanups (script_chain);
}
if (!part_of_multiple && b->pass_count)
{
annotate_field (10);
ui_out_text (uiout, "\tpass count ");
ui_out_field_int (uiout, "pass", b->pass_count);
ui_out_text (uiout, " \n");
}
if (!part_of_multiple && b->step_count)
{
annotate_field (11);
ui_out_text (uiout, "\tstep count ");
ui_out_field_int (uiout, "step", b->step_count);
ui_out_text (uiout, " \n");
}
if (!part_of_multiple && b->actions)
{
struct action_line *action;
annotate_field (12);
for (action = b->actions; action; action = action->next)
{
ui_out_text (uiout, " A\t");
ui_out_text (uiout, action->action);
ui_out_text (uiout, "\n");
}
}
if (ui_out_is_mi_like_p (uiout) && !part_of_multiple)
{
if (b->addr_string)
@ -3735,6 +3809,7 @@ user_settable_breakpoint (const struct breakpoint *b)
return (b->type == bp_breakpoint
|| b->type == bp_catchpoint
|| b->type == bp_hardware_breakpoint
|| b->type == bp_tracepoint
|| b->type == bp_watchpoint
|| b->type == bp_read_watchpoint
|| b->type == bp_access_watchpoint
@ -4113,6 +4188,7 @@ allocate_bp_location (struct breakpoint *bpt)
switch (bpt->type)
{
case bp_breakpoint:
case bp_tracepoint:
case bp_until:
case bp_finish:
case bp_longjmp:
@ -4202,7 +4278,8 @@ static void
set_breakpoint_location_function (struct bp_location *loc)
{
if (loc->owner->type == bp_breakpoint
|| loc->owner->type == bp_hardware_breakpoint)
|| loc->owner->type == bp_hardware_breakpoint
|| loc->owner->type == bp_tracepoint)
{
find_pc_partial_function (loc->address, &(loc->function_name),
NULL, NULL);
@ -4477,7 +4554,9 @@ disable_breakpoints_in_shlibs (void)
becomes enabled, or the duplicate is removed, gdb will try to insert
all breakpoints. If we don't set shlib_disabled here, we'll try
to insert those breakpoints and fail. */
if (((b->type == bp_breakpoint) || (b->type == bp_hardware_breakpoint))
if (((b->type == bp_breakpoint)
|| (b->type == bp_hardware_breakpoint)
|| (b->type == bp_tracepoint))
&& !loc->shlib_disabled
#ifdef PC_SOLIB
&& PC_SOLIB (loc->address)
@ -5007,6 +5086,16 @@ mention (struct breakpoint *b)
printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
say_where = 1;
break;
case bp_tracepoint:
if (ui_out_is_mi_like_p (uiout))
{
say_where = 0;
break;
}
printf_filtered (_("Tracepoint"));
printf_filtered (_(" %d"), b->number);
say_where = 1;
break;
case bp_until:
case bp_finish:
@ -5514,7 +5603,7 @@ find_condition_and_thread (char *tok, CORE_ADDR pc,
static void
break_command_really (char *arg, char *cond_string, int thread,
int parse_condition_and_thread,
int tempflag, int hardwareflag,
int tempflag, int hardwareflag, int traceflag,
int ignore_count,
enum auto_boolean pending_break_support,
struct breakpoint_ops *ops,
@ -5534,6 +5623,7 @@ break_command_really (char *arg, char *cond_string, int thread,
int i;
int pending = 0;
int not_found = 0;
enum bptype type_wanted;
sals.sals = NULL;
sals.nelts = 0;
@ -5622,6 +5712,10 @@ break_command_really (char *arg, char *cond_string, int thread,
if (!pending)
breakpoint_sals_to_pc (&sals, addr_start);
type_wanted = (traceflag
? bp_tracepoint
: (hardwareflag ? bp_hardware_breakpoint : bp_breakpoint));
/* Verify that condition can be parsed, before setting any
breakpoints. Allocate a separate condition expression for each
breakpoint. */
@ -5648,9 +5742,7 @@ break_command_really (char *arg, char *cond_string, int thread,
make_cleanup (xfree, cond_string);
}
}
create_breakpoints (sals, addr_string, cond_string,
hardwareflag ? bp_hardware_breakpoint
: bp_breakpoint,
create_breakpoints (sals, addr_string, cond_string, type_wanted,
tempflag ? disp_del : disp_donttouch,
thread, ignore_count, ops, from_tty, enabled);
}
@ -5661,9 +5753,7 @@ break_command_really (char *arg, char *cond_string, int thread,
make_cleanup (xfree, copy_arg);
b = set_raw_breakpoint_without_location (hardwareflag
? bp_hardware_breakpoint
: bp_breakpoint);
b = set_raw_breakpoint_without_location (type_wanted);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->thread = -1;
@ -5704,7 +5794,7 @@ break_command_1 (char *arg, int flag, int from_tty)
break_command_really (arg,
NULL, 0, 1 /* parse arg */,
tempflag, hardwareflag,
tempflag, hardwareflag, 0 /* traceflag */,
0 /* Ignore count */,
pending_break_support,
NULL /* breakpoint_ops */,
@ -5721,7 +5811,7 @@ set_breakpoint (char *address, char *condition,
{
break_command_really (address, condition, thread,
0 /* condition and thread are valid. */,
tempflag, hardwareflag,
tempflag, hardwareflag, 0 /* traceflag */,
ignore_count,
pending
? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
@ -6584,7 +6674,7 @@ handle_gnu_v3_exceptions (int tempflag, char *cond_string,
break_command_really (trigger_func_name, cond_string, -1,
0 /* condition and thread are valid. */,
tempflag, 0,
tempflag, 0, 0,
0,
AUTO_BOOLEAN_TRUE /* pending */,
&gnu_v3_exception_catchpoint_ops, from_tty,
@ -7444,6 +7534,7 @@ breakpoint_re_set_one (void *bint)
return 0;
case bp_breakpoint:
case bp_hardware_breakpoint:
case bp_tracepoint:
if (b->addr_string == NULL)
{
/* Anything without a string can't be re-set. */
@ -7809,6 +7900,7 @@ disable_command (char *args, int from_tty)
bpt->number);
continue;
case bp_breakpoint:
case bp_tracepoint:
case bp_catchpoint:
case bp_hardware_breakpoint:
case bp_watchpoint:
@ -7901,6 +7993,7 @@ enable_command (char *args, int from_tty)
bpt->number);
continue;
case bp_breakpoint:
case bp_tracepoint:
case bp_catchpoint:
case bp_hardware_breakpoint:
case bp_watchpoint:
@ -8084,6 +8177,324 @@ single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
return 0;
}
/* Tracepoint-specific operations. */
/* Set tracepoint count to NUM. */
static void
set_tracepoint_count (int num)
{
tracepoint_count = num;
set_internalvar (lookup_internalvar ("tpnum"),
value_from_longest (builtin_type_int32, (LONGEST) num));
}
void
trace_command (char *arg, int from_tty)
{
break_command_really (arg,
NULL, 0, 1 /* parse arg */,
0 /* tempflag */, 0 /* hardwareflag */,
1 /* traceflag */,
0 /* Ignore count */,
pending_break_support,
NULL,
from_tty,
1 /* enabled */);
set_tracepoint_count (breakpoint_count);
}
/* Print information on tracepoint number TPNUM_EXP, or all if
omitted. */
static void
tracepoints_info (char *tpnum_exp, int from_tty)
{
struct breakpoint *b;
int tps_to_list = 0;
/* In the no-arguments case, say "No tracepoints" if none found. */
if (tpnum_exp == 0)
{
ALL_TRACEPOINTS (b)
{
if (b->number >= 0)
{
tps_to_list = 1;
break;
}
}
if (!tps_to_list)
{
ui_out_message (uiout, 0, "No tracepoints.\n");
return;
}
}
/* Otherwise be the same as "info break". */
breakpoints_info (tpnum_exp, from_tty);
}
/* The 'enable trace' command enables tracepoints.
Not supported by all targets. */
static void
enable_trace_command (char *args, int from_tty)
{
enable_command (args, from_tty);
}
/* The 'disable trace' command disables tracepoints.
Not supported by all targets. */
static void
disable_trace_command (char *args, int from_tty)
{
disable_command (args, from_tty);
}
/* Remove a tracepoint (or all if no argument) */
static void
delete_trace_command (char *arg, int from_tty)
{
struct breakpoint *b, *temp;
dont_repeat ();
if (arg == 0)
{
int breaks_to_delete = 0;
/* Delete all breakpoints if no argument.
Do not delete internal or call-dummy breakpoints, these
have to be deleted with an explicit breakpoint number argument. */
ALL_TRACEPOINTS (b)
{
if (b->number >= 0)
{
breaks_to_delete = 1;
break;
}
}
/* Ask user only if there are some breakpoints to delete. */
if (!from_tty
|| (breaks_to_delete && query (_("Delete all tracepoints? "))))
{
ALL_BREAKPOINTS_SAFE (b, temp)
{
if (b->type == bp_tracepoint &&
b->number >= 0)
delete_breakpoint (b);
}
}
}
else
map_breakpoint_numbers (arg, delete_breakpoint);
}
/* Set passcount for tracepoint.
First command argument is passcount, second is tracepoint number.
If tracepoint number omitted, apply to most recently defined.
Also accepts special argument "all". */
static void
trace_pass_command (char *args, int from_tty)
{
struct breakpoint *t1 = (struct breakpoint *) -1, *t2;
unsigned int count;
int all = 0;
if (args == 0 || *args == 0)
error (_("passcount command requires an argument (count + optional TP num)"));
count = strtoul (args, &args, 10); /* Count comes first, then TP num. */
while (*args && isspace ((int) *args))
args++;
if (*args && strncasecmp (args, "all", 3) == 0)
{
args += 3; /* Skip special argument "all". */
all = 1;
if (*args)
error (_("Junk at end of arguments."));
}
else
t1 = get_tracepoint_by_number (&args, 1, 1);
do
{
if (t1)
{
ALL_TRACEPOINTS (t2)
if (t1 == (struct breakpoint *) -1 || t1 == t2)
{
t2->pass_count = count;
observer_notify_tracepoint_modified (t2->number);
if (from_tty)
printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
t2->number, count);
}
if (! all && *args)
t1 = get_tracepoint_by_number (&args, 1, 0);
}
}
while (*args);
}
struct breakpoint *
get_tracepoint (int num)
{
struct breakpoint *t;
ALL_TRACEPOINTS (t)
if (t->number == num)
return t;
return NULL;
}
/* Utility: parse a tracepoint number and look it up in the list.
If MULTI_P is true, there might be a range of tracepoints in ARG.
if OPTIONAL_P is true, then if the argument is missing, the most
recent tracepoint (tracepoint_count) is returned. */
struct breakpoint *
get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
{
extern int tracepoint_count;
struct breakpoint *t;
int tpnum;
char *instring = arg == NULL ? NULL : *arg;
if (arg == NULL || *arg == NULL || ! **arg)
{
if (optional_p)
tpnum = tracepoint_count;
else
error_no_arg (_("tracepoint number"));
}
else
tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
if (tpnum <= 0)
{
if (instring && *instring)
printf_filtered (_("bad tracepoint number at or near '%s'\n"),
instring);
else
printf_filtered (_("Tracepoint argument missing and no previous tracepoint\n"));
return NULL;
}
ALL_TRACEPOINTS (t)
if (t->number == tpnum)
{
return t;
}
/* FIXME: if we are in the middle of a range we don't want to give
a message. The current interface to get_number_or_range doesn't
allow us to discover this. */
printf_unfiltered ("No tracepoint number %d.\n", tpnum);
return NULL;
}
/* save-tracepoints command */
static void
tracepoint_save_command (char *args, int from_tty)
{
struct breakpoint *tp;
int any_tp = 0;
struct action_line *line;
FILE *fp;
char *i1 = " ", *i2 = " ";
char *indent, *actionline, *pathname;
char tmp[40];
struct cleanup *cleanup;
if (args == 0 || *args == 0)
error (_("Argument required (file name in which to save tracepoints)"));
/* See if we have anything to save. */
ALL_TRACEPOINTS (tp)
{
any_tp = 1;
break;
}
if (!any_tp)
{
warning (_("save-tracepoints: no tracepoints to save."));
return;
}
pathname = tilde_expand (args);
cleanup = make_cleanup (xfree, pathname);
if (!(fp = fopen (pathname, "w")))
error (_("Unable to open file '%s' for saving tracepoints (%s)"),
args, safe_strerror (errno));
make_cleanup_fclose (fp);
ALL_TRACEPOINTS (tp)
{
if (tp->addr_string)
fprintf (fp, "trace %s\n", tp->addr_string);
else
{
sprintf_vma (tmp, tp->loc->address);
fprintf (fp, "trace *0x%s\n", tmp);
}
if (tp->pass_count)
fprintf (fp, " passcount %d\n", tp->pass_count);
if (tp->actions)
{
fprintf (fp, " actions\n");
indent = i1;
for (line = tp->actions; line; line = line->next)
{
struct cmd_list_element *cmd;
QUIT; /* allow user to bail out with ^C */
actionline = line->action;
while (isspace ((int) *actionline))
actionline++;
fprintf (fp, "%s%s\n", indent, actionline);
if (*actionline != '#') /* skip for comment lines */
{
cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
if (cmd == 0)
error (_("Bad action list item: %s"), actionline);
if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
indent = i2;
else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
indent = i1;
}
}
}
}
do_cleanups (cleanup);
if (from_tty)
printf_filtered (_("Tracepoints saved to file '%s'.\n"), args);
return;
}
/* Create a vector of all tracepoints. */
VEC(breakpoint_p) *
all_tracepoints ()
{
VEC(breakpoint_p) *tp_vec = 0;
struct breakpoint *tp;
ALL_TRACEPOINTS (tp)
{
VEC_safe_push (breakpoint_p, tp_vec, tp);
}
return tp_vec;
}
/* This help string is used for the break, hbreak, tbreak and thbreak commands.
It is defined as a macro to prevent duplication.
@ -8146,6 +8557,8 @@ _initialize_breakpoint (void)
before a breakpoint is set. */
breakpoint_count = 0;
tracepoint_count = 0;
add_com ("ignore", class_breakpoint, ignore_command, _("\
Set ignore-count of breakpoint number N to COUNT.\n\
Usage is `ignore N COUNT'."));
@ -8475,6 +8888,58 @@ hardware.)"),
can_use_hw_watchpoints = 1;
/* Tracepoint manipulation commands. */
c = add_com ("trace", class_breakpoint, trace_command, _("\
Set a tracepoint at specified line or function.\n\
\n"
BREAK_ARGS_HELP ("trace") "\n\
Do \"help tracepoints\" for info on other tracepoint commands."));
set_cmd_completer (c, location_completer);
add_com_alias ("tp", "trace", class_alias, 0);
add_com_alias ("tr", "trace", class_alias, 1);
add_com_alias ("tra", "trace", class_alias, 1);
add_com_alias ("trac", "trace", class_alias, 1);
add_info ("tracepoints", tracepoints_info, _("\
Status of tracepoints, or tracepoint number NUMBER.\n\
Convenience variable \"$tpnum\" contains the number of the\n\
last tracepoint set."));
add_info_alias ("tp", "tracepoints", 1);
add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
Delete specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means delete all tracepoints."),
&deletelist);
c = add_cmd ("tracepoints", class_trace, disable_trace_command, _("\
Disable specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means disable all tracepoints."),
&disablelist);
deprecate_cmd (c, "disable");
c = add_cmd ("tracepoints", class_trace, enable_trace_command, _("\
Enable specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means enable all tracepoints."),
&enablelist);
deprecate_cmd (c, "enable");
add_com ("passcount", class_trace, trace_pass_command, _("\
Set the passcount for a tracepoint.\n\
The trace will end when the tracepoint has been passed 'count' times.\n\
Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
if TPNUM is omitted, passcount refers to the last tracepoint defined."));
c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
Save current tracepoint definitions as a script.\n\
Use the 'source' command in another debug session to restore them."));
set_cmd_completer (c, filename_completer);
add_prefix_cmd ("breakpoint", class_maintenance, set_breakpoint_cmd, _("\
Breakpoint specific settings\n\
Configure various breakpoint-specific variables such as\n\

View File

@ -111,6 +111,8 @@ enum bptype
bp_overlay_event,
bp_catchpoint,
bp_tracepoint,
};
/* States of enablement of breakpoint. */
@ -449,6 +451,17 @@ struct breakpoint
no location initially so had no context to parse
the condition in. */
int condition_not_parsed;
/* Number of times this tracepoint should single-step
and collect additional data. */
long step_count;
/* Number of times this tracepoint should be hit before
disabling/ending. */
int pass_count;
/* Chain of action lines to execute when this tracepoint is hit. */
struct action_line *actions;
};
typedef struct breakpoint *breakpoint_p;
@ -860,4 +873,15 @@ extern void breakpoint_retire_moribund (void);
/* Tell a breakpoint to be quiet. */
extern void make_breakpoint_silent (struct breakpoint *);
/* Return a tracepoint with the given number if found. */
extern struct breakpoint *get_tracepoint (int num);
/* Find a tracepoint by parsing a number in the supplied string. */
extern struct breakpoint *get_tracepoint_by_number (char **arg, int multi_p,
int optional_p);
/* Return a vector of all tracepoints currently defined. The vector
is newly allocated; the caller should free when done with it. */
extern VEC(breakpoint_p) *all_tracepoints (void);
#endif /* !defined (BREAKPOINT_H) */

View File

@ -1,3 +1,10 @@
2009-03-30 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Tracepoints): Describe tracepoints as a
special case of breakpoints.
(Enable and Disable Tracepoints): Mention deprecation.
(Listing Tracepoints): Update description and example.
2009-03-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.texinfo (Frames in Python): New node.

View File

@ -8555,12 +8555,12 @@ This chapter describes the tracepoint commands and features.
@section Commands to Set Tracepoints
Before running such a @dfn{trace experiment}, an arbitrary number of
tracepoints can be set. Like a breakpoint (@pxref{Set Breaks}), a
tracepoint has a number assigned to it by @value{GDBN}. Like with
breakpoints, tracepoint numbers are successive integers starting from
one. Many of the commands associated with tracepoints take the
tracepoint number as their argument, to identify which tracepoint to
work on.
tracepoints can be set. A tracepoint is actually a special type of
breakpoint (@pxref{Set Breaks}), so you can manipulate it using
standard breakpoint commands. For instance, as with breakpoints,
tracepoint numbers are successive integers starting from one, and many
of the commands associated with tracepoints take the tracepoint number
as their argument, to identify which tracepoint to work on.
For each tracepoint, you can specify, in advance, some arbitrary set
of data that you want the target to collect in the trace buffer when
@ -8569,6 +8569,11 @@ local variables, or global data. Later, you can use @value{GDBN}
commands to examine the values these data had at the time the
tracepoint was hit.
Tracepoints do not support every breakpoint feature. Conditional
expressions and ignore counts on tracepoints have no effect, and
tracepoints cannot run @value{GDBN} commands when they are
hit. Tracepoints may not be thread-specific either.
This section describes commands to set tracepoints and associated
conditions and actions.
@ -8587,16 +8592,16 @@ conditions and actions.
@table @code
@cindex set tracepoint
@kindex trace
@item trace
@item trace @var{location}
The @code{trace} command is very similar to the @code{break} command.
Its argument can be a source line, a function name, or an address in
the target program. @xref{Set Breaks}. The @code{trace} command
defines a tracepoint, which is a point in the target program where the
debugger will briefly stop, collect some data, and then allow the
program to continue. Setting a tracepoint or changing its commands
doesn't take effect until the next @code{tstart} command; thus, you
cannot change the tracepoint attributes once a trace experiment is
running.
Its argument @var{location} can be a source line, a function name, or
an address in the target program. @xref{Specify Location}. The
@code{trace} command defines a tracepoint, which is a point in the
target program where the debugger will briefly stop, collect some
data, and then allow the program to continue. Setting a tracepoint or
changing its actions doesn't take effect until the next @code{tstart}
command, and once a trace experiment is running, further changes will
not have any effect until the next trace experiment starts.
Here are some examples of using the @code{trace} command:
@ -8626,7 +8631,8 @@ of the most recently set tracepoint.
@cindex tracepoint deletion
@item delete tracepoint @r{[}@var{num}@r{]}
Permanently delete one or more tracepoints. With no argument, the
default is to delete all tracepoints.
default is to delete all tracepoints. Note that the regular
@code{delete} command can remove tracepoints also.
Examples:
@ -8643,6 +8649,8 @@ You can abbreviate this command as @code{del tr}.
@node Enable and Disable Tracepoints
@subsection Enable and Disable Tracepoints
These commands are deprecated; they are equivalent to plain @code{disable} and @code{enable}.
@table @code
@kindex disable tracepoint
@item disable tracepoint @r{[}@var{num}@r{]}
@ -8796,34 +8804,36 @@ You may abbreviate @code{while-stepping} as @code{ws} or
@kindex info tp
@cindex information about tracepoints
@item info tracepoints @r{[}@var{num}@r{]}
Display information about the tracepoint @var{num}. If you don't specify
a tracepoint number, displays information about all the tracepoints
defined so far. For each tracepoint, the following information is
shown:
Display information about the tracepoint @var{num}. If you don't
specify a tracepoint number, displays information about all the
tracepoints defined so far. The format is similar to that used for
@code{info breakpoints}; in fact, @code{info tracepoints} is the same
command, simply restricting itself to tracepoints.
A tracepoint's listing may include additional information specific to
tracing:
@itemize @bullet
@item
its number
@item
whether it is enabled or disabled
@item
its address
@item
its passcount as given by the @code{passcount @var{n}} command
@item
its step count as given by the @code{while-stepping @var{n}} command
@item
where in the source files is the tracepoint set
@item
its action list as given by the @code{actions} command
its action list as given by the @code{actions} command. The actions
are prefixed with an @samp{A} so as to distinguish them from commands.
@end itemize
@smallexample
(@value{GDBP}) @b{info trace}
Num Enb Address PassC StepC What
1 y 0x002117c4 0 0 <gdb_asm>
2 y 0x0020dc64 0 0 in g_test at g_test.c:1375
3 y 0x0020b1f4 0 0 in get_data at ../foo.c:41
Num Type Disp Enb Address What
1 tracepoint keep y 0x0804ab57 in foo() at main.cxx:7
pass count 1200
step count 20
A while-stepping 20
A collect globfoo, $regs
A end
A collect globfoo2
A end
(@value{GDBP})
@end smallexample

View File

@ -1,3 +1,13 @@
2009-03-30 Stan Shebs <stan@codesourcery.com>
* gdb.trace/actions.exp: Update to match new info trace format.
* gdb.trace/deltrace.exp: Ditto.
* gdb.trace/infotrace.exp: Ditto.
* gdb.trace/passcount.exp: Ditto.
* gdb.trace/save-trace.exp: Ditto.
* gdb.trace/while-stepping.exp: Ditto.
* gdb.trace/tracecmd.exp: Ditto, plus don't allow pending option.
2009-03-30 Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.python/python-frame.c: New file.

View File

@ -90,43 +90,46 @@ gdb_trace_setactions "5.1b: set actions for first tracepoint" \
"$trcpt1" \
"collect gdb_char_test" "^$"
send_gdb "info tracepoints\n"
gdb_expect {
-re "Actions for.* $trcpt1:.*collect gdb_char_test.*$gdb_prompt $" {
pass "5.1c: verify actions set for first tracepoint"
}
-re "$gdb_prompt $" {
fail "5.1c: verify actions set for first tracepoint"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_char_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"5.1c: verify actions set for first tracepoint"
gdb_trace_setactions "5.1d: set actions for second tracepoint" \
"$trcpt2" \
"collect gdb_short_test" "^$"
send_gdb "info tracepoints\n"
gdb_expect {
-re "Actions for.* $trcpt2:.*collect gdb_short_test.*$gdb_prompt $" {
pass "5.1e: verify actions set for second tracepoint"
}
-re "$gdb_prompt $" {
fail "5.1e: verify actions set for second tracepoint"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_char_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_short_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"5.1e: verify actions set for second tracepoint"
gdb_trace_setactions "5.2a: set actions for last (default) tracepoint" \
"" \
"collect gdb_long_test" "^$"
send_gdb "info tracepoints\n"
gdb_expect {
-re "Actions for.* $trcpt3:.*collect gdb_long_test.*$gdb_prompt $" {
pass "5.2b: verify actions set for last (default) tracepoint"
}
-re "$gdb_prompt $" {
fail "5.2b: verify actions set for last (default) tracepoint"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_char_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_short_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_long_test.
\[\t \]+A\[\t \]+end." \
"5.1e: verify actions set for second tracepoint"
# 5.3 replace actions set earlier
@ -134,15 +137,18 @@ gdb_trace_setactions "5.3a: reset actions for first tracepoint" \
"$trcpt1" \
"collect gdb_struct1_test" "^$"
send_gdb "info tracepoints\n"
gdb_expect {
-re "Actions for.* $trcpt1:.*collect gdb_struct1_test.*$gdb_prompt $" {
pass "5.3b: verify actions set for first tracepoint"
}
-re "$gdb_prompt $" {
fail "5.3b: verify actions set for first tracepoint"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_struct1_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_short_test.
\[\t \]+A\[\t \]+end.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+A\[\t \]+collect gdb_long_test.
\[\t \]+A\[\t \]+end." \
"5.3b: verify actions set for first tracepoint"
#
# test end command (all by itself)

View File

@ -67,7 +67,10 @@ gdb_test "trace gdb_asm_test" "Tracepoint \[0-9\]+ at .*" "set tracepoint 2"
gdb_test "trace $testline1" "Tracepoint \[0-9\]+ at .*" "set tracepoint 3"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*\[0-9\]+\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"3.1a: set three tracepoints"
send_gdb "delete tracepoints\n"
@ -98,7 +101,10 @@ if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
}
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in.*gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"3.2a: set three tracepoints"
#gdb_test "delete tracepoint $trcpt1" "" ""
@ -118,21 +124,11 @@ gdb_expect {
}
}
send_gdb "info tracepoints\n"
gdb_expect {
-re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" {
fail "3.2c: verify delete first tracepoint (argh)"
}
-re "$trcpt2\[\t \]+y.*gdb_asm_test.*\[\r\n\t ]+$trcpt3\[\t \]+y.* in gdb_recursion_test at .*$gdb_prompt $" {
pass "3.2c: verify delete first tracepoint"
}
-re ".*$gdb_prompt $" {
fail "3.2c: verify delete first tracepoint (mumble)"
}
timeout {
fail "3.2c: verify delete first tracepoint (timeout)"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"3.2c: verify delete first tracepoint"
#gdb_test "delete tracepoint $trcpt2" "" ""
send_gdb "delete tracepoint $trcpt2\n"
@ -151,24 +147,10 @@ gdb_expect {
}
}
send_gdb "info tracepoints\n"
gdb_expect {
-re "$trcpt1\[\t \]+y\[\t \]+0x.*in.*gdb_c_test.*$gdb_prompt $" {
fail "3.2e: verify delete second tracepoint"
}
-re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" {
fail "3.2e: verify delete second tracepoint"
}
-re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
pass "3.2e: verify delete second tracepoint"
}
-re "$gdb_prompt $" {
fail "3.2e: verify delete second tracepoint"
}
timeout {
fail "3.2e: verify delete second tracepoint (timeout)"
}
}
gdb_test "info tracepoints" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"3.2e: verify delete second tracepoint"
#gdb_test "delete tracepoint $trcpt3" "" ""
send_gdb "delete tracepoint $trcpt3\n"
@ -188,18 +170,9 @@ gdb_expect {
}
# send_gdb "ARF! \\n\n"
send_gdb "info tracepoints\n"
gdb_expect {
-re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
fail "3.2g: verify delete third tracepoint"
}
-re "$gdb_prompt $" {
pass "3.2g: verify delete third tracepoint"
}
timeout {
fail "3.2g: verify delete third tracepoint (timeout)"
}
}
gdb_test "info tracepoints" \
"No tracepoints." \
"3.2g: verify delete third tracepoint"
# 3.3 delete three tracepoints at once
gdb_delete_tracepoints
@ -212,7 +185,10 @@ if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
}
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"3.3a: set three tracepoints"
#gdb_test "delete tracepoint $trcpt1 $trcpt2 $trcpt3" "" ""
@ -232,32 +208,17 @@ gdb_expect {
}
}
send_gdb "info tracepoints\n"
gdb_expect {
-re "$trcpt1\[\t \]+y\[\t \]+0x.*in gdb_c_test.*$gdb_prompt $" {
fail "3.3c: verify delete three tracepoints (first one persists)"
}
-re "$trcpt2\[\t \]+y\[\t \]+0x.*in gdb_asm_test.*$gdb_prompt $" {
fail "3.3c: verify delete three tracepoints (second one persists)"
}
-re "$trcpt3\[\t \]+y\[\t \]+0x.*in gdb_recursion_test.*$gdb_prompt $" {
fail "3.3c: verify delete three tracepoints (third one persists)"
}
-re "$gdb_prompt $" {
pass "3.3c: verify delete three tracepoints"
}
timeout {
fail "3.3c: verify delete three tracepoints (timeout)"
}
}
gdb_test "info tracepoints" \
"No tracepoints." \
"3.3c: verify delete three tracepoints"
# 3.4 delete invalid tracepoint number
gdb_test "delete tracepoint [expr $trcpt2 + $trcpt3]" \
"No tracepoint number [expr $trcpt2 + $trcpt3]." \
"No breakpoint number [expr $trcpt2 + $trcpt3]." \
"3.4: delete invalid tracepoint number"
# 3.5 delete tracepoint number zero
gdb_test "delete tracepoint 0" "bad tracepoint number at or near '0'" \
gdb_test "delete tracepoint 0" "bad breakpoint number at or near '0'" \
"3.5: delete tracepoint number zero"
# 3.6 help delete tracepoints

View File

@ -61,21 +61,25 @@ if { $c_test_num <= 0 || $asm_test_num <= 0 } then {
# 2.1 info tracepoints (all)
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+." \
"2.1: info tracepoints (all)"
# 2.2 info tracepoint (specific)
gdb_test "info tracepoint $c_test_num" \
"$c_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*in gdb_c_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+." \
"2.2a: info tracepoint $c_test_num (gdb_c_test)"
gdb_test "info tracepoint $asm_test_num" \
"$asm_test_num\[\t \]+y\[\t \]+0x\[0-9a-fA-F\]+.*gdb_asm_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+." \
"2.2b: info tracepoint $asm_test_num (gdb_asm_test)"
# 2.3 info tracepoint (invalid tracepoint number)
gdb_test "info tracepoint [expr $c_test_num + $asm_test_num]" \
"No tracepoint number [expr $c_test_num + $asm_test_num]." \
"No breakpoint or watchpoint number [expr $c_test_num + $asm_test_num]." \
"2.3: info tracepoint (invalid tracepoint number)"
# 2.4 info tracepoints (list of numbers)

View File

@ -72,7 +72,10 @@ if { $trcpt1 <= 0 || $trcpt2 <= 0 || $trcpt3 <= 0 } then {
# 4.1 passcount of specified tracepoint
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"4.1a: set three tracepoints, passcounts all zero"
gdb_test "passcount 2 $trcpt1" \
@ -80,7 +83,11 @@ gdb_test "passcount 2 $trcpt1" \
"4.1b: set 1st tracepoint's passcount to two"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 2 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"4.1c: verify 1st tracepoint's passcount set to two"
gdb_test "passcount 4 $trcpt2" \
@ -88,7 +95,12 @@ gdb_test "passcount 4 $trcpt2" \
"4.1d: set 2nd tracepoint's passcount to four"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 2 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+" \
"4.1c: verify 2nd tracepoint's passcount set to four"
# 4.2 passcount of last (default) tracepoint
@ -98,7 +110,13 @@ gdb_test "passcount 6" \
"4.2b: set last (default) tp's passcount to six"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+6\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 2 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 6 .*" \
"4.2b: verify last (default) tp's passcount set to six"
# 4.3 run until stopped explicitly by user
@ -111,7 +129,13 @@ gdb_test "passcount 7" \
"4.4a: reset last (default) tp's passcount to seven"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 2 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 7 .*" \
"4.4a: verify reset last (default) tp's passcount to seven"
gdb_test "passcount 5 $trcpt2" \
@ -119,7 +143,13 @@ gdb_test "passcount 5 $trcpt2" \
"4.4b: reset second tracepoint's passcount to five"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+2\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+5\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+7\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 2 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 5 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 7 .*" \
"4.4c: verify reset second tracepoint's passcount to five"
# 4.20 <FIXME test number> passcount for "all"
@ -129,7 +159,13 @@ gdb_test "passcount 3 all" \
"4.20a: set all three passcounts to three"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+3\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 3 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 3 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 3 .*" \
"4.20a: set all three passcounts to three"
gdb_test "passcount 4 all" \
@ -137,7 +173,13 @@ gdb_test "passcount 4 all" \
"4.20a: reset all three passcounts to four"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*" \
"4.20b: reset all three passcounts to four"
# 4.5 Verify trace stops on first "satisfied" passcount
@ -150,7 +192,12 @@ gdb_test "passcount 0 $trcpt1" \
"4.6: set passcount to zero"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+0\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*" \
"4.6: set passcount to zero"
# 4.7 (test a very large passcount)
@ -160,7 +207,13 @@ gdb_test "passcount 32767 $trcpt1" \
"4.7: set passcount to large number (32767)"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1\[\t \]+y\[\t \]+$hex\[\t \]+32767\[\t \]+.*in gdb_c_test.*$trcpt2\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*gdb_asm_test.*$trcpt3\[\t \]+y\[\t \]+$hex\[\t \]+4\[\t \]+.*in gdb_recursion_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 32767 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_asm_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_recursion_test at .*$srcfile:\[0-9\]+.
\[\t \]+pass count 4 .*" \
"4.7: set passcount to large number (32767)"
# 4.8 set passcount for invalid tracepoint
@ -172,4 +225,3 @@ gdb_test "passcount 1 [expr $trcpt2 + $trcpt3]" \
# 4.9 help passcount
gdb_test "help passcount" "Set the passcount for a tracepoint.*" \
"4.9: help passcount"

View File

@ -96,13 +96,10 @@ proc gdb_verify_tracepoints { testname } {
set result "pass";
send_gdb "info tracepoints\n";
gdb_expect 10 {
-re "y\[\t \]+0x\[0-9a-fA-F\]+\[\t \]+(\[0-9\]+)\[\t \]+(\[0-9\]+)\[\t \]+in gdb_recursion_test\[^\r\n\]+" {
if { $expect_out(1,string) != $expect_out(2,string) } {
#set result "fail";
}
if { $expect_out(1,string) != $ourstate } {
set result "fail";
}
-re "\[0-9\]+\[\t \]+tracepoint\[\t \]+keep y\[\t \]+0x\[0-9a-fA-F\]+ in gdb_recursion_test\[^\r\n\]+" {
# if { $expect_out(1,string) != $ourstate } {
# set result "fail";
# }
incr ourstate;
exp_continue;
}

View File

@ -87,6 +87,7 @@ gdb_test "info trace" "No tracepoints.*" \
# 1.3 trace line in invalid source file
gdb_delete_tracepoints
gdb_test "set breakpoint pending off" ""
gdb_test "trace NoSuChFiLe.c:1" "No source file named NoSuChFiLe.c." \
"1.3a: trace invalid source file"
gdb_test "info trace" "No tracepoints.*" \
@ -145,7 +146,7 @@ gdb_test "info trace" "$c_test_addr.*in gdb_recursion_test.*:$baseline" \
# no address is invalid
# 1.9 trace no arguments
gdb_test "trace" "trace command requires an argument" \
gdb_test "trace" "No default breakpoint address now." \
"1.9: trace <no arguments>"
# 1.10 set large number of tracepoints

View File

@ -61,7 +61,8 @@ if { $trcpt1 <= 0 } then {
# 5.12 basic while-stepping command (collect regs)
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+0\[\t \]+.*in gdb_c_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+" \
"5.12: set a tracepoint, stepcount is zero"
set stepcount 12
@ -73,11 +74,13 @@ gdb_trace_setactions "5.12: set stepcount to $stepcount" \
"end" ""
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
\[\t \]+step count 12 .*" \
"5.12: confirm stepcount set to $stepcount"
gdb_test "info tracepoints" \
"Num Enb Address\[ \]+PassC StepC What.*
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
.*while-stepping $stepcount.*" \
"5.12: info trace shows \"while-stepping\""
@ -108,6 +111,10 @@ gdb_trace_setactions "5.16: step without collecting anything" \
"end" ""
gdb_test "info tracepoints" \
".*$trcpt1.*0x.*\[\t \]+\[0-9\]+\[\t \]+$stepcount\[\t \]+.*in gdb_c_test.*\[ \t\]+Actions for tracepoint $trcpt1:.*\[ \t\]+while-stepping $stepcount.*\[ \t\]+end.*\[ \t\]+end.*" \
"Num Type\[ \]+Disp Enb Address\[ \]+What.*
\[0-9\]+\[\t \]+tracepoint keep y.* in gdb_c_test at .*$srcfile:\[0-9\]+.
.*while-stepping $stepcount.*
.*end.*
.*end.*" \
"5.16: confirm actions, step without collecting anything"

View File

@ -29,6 +29,7 @@
#include "language.h"
#include "gdb_string.h"
#include "inferior.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "remote.h"
#include "linespec.h"
@ -102,12 +103,6 @@ extern void output_command (char *, int);
/* ======= Important global variables: ======= */
/* Chain of all tracepoints defined. */
struct tracepoint *tracepoint_chain;
/* Number of last tracepoint made. */
static int tracepoint_count;
/* Number of last traceframe collected. */
static int traceframe_number;
@ -124,12 +119,6 @@ static struct symtab_and_line traceframe_sal;
static struct cmd_list_element *tfindlist;
/* ======= Important command functions: ======= */
static void trace_command (char *, int);
static void tracepoints_info (char *, int);
static void delete_trace_command (char *, int);
static void enable_trace_command (char *, int);
static void disable_trace_command (char *, int);
static void trace_pass_command (char *, int);
static void trace_actions_command (char *, int);
static void trace_start_command (char *, int);
static void trace_stop_command (char *, int);
@ -144,14 +133,13 @@ static void tracepoint_save_command (char *, int);
static void trace_dump_command (char *, int);
/* support routines */
static void trace_mention (struct tracepoint *);
struct collection_list;
static void add_aexpr (struct collection_list *, struct agent_expr *);
static char *mem2hex (gdb_byte *, char *, int);
static void add_register (struct collection_list *collection,
unsigned int regno);
static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
static struct cleanup *make_cleanup_free_actions (struct breakpoint *t);
static void free_actions_list (char **actions_list);
static void free_actions_list_cleanup_wrapper (void *);
@ -214,15 +202,6 @@ remote_get_noisy_reply (char **buf_p,
while (1);
}
/* Set tracepoint count to NUM. */
static void
set_tracepoint_count (int num)
{
tracepoint_count = num;
set_internalvar (lookup_internalvar ("tpnum"),
value_from_longest (builtin_type_int32, (LONGEST) num));
}
/* Set traceframe number to NUM. */
static void
set_traceframe_num (int num)
@ -323,436 +302,10 @@ set_traceframe_context (CORE_ADDR trace_pc)
}
}
/* Low level routine to set a tracepoint.
Returns the tracepoint object so caller can set other things.
Does not set the tracepoint number!
Does not print anything.
==> This routine should not be called if there is a chance of later
error(); otherwise it leaves a bogus tracepoint on the chain.
Validate your arguments BEFORE calling this routine! */
static struct tracepoint *
set_raw_tracepoint (struct symtab_and_line sal)
{
struct tracepoint *t, *tc;
struct cleanup *old_chain;
t = (struct tracepoint *) xmalloc (sizeof (struct tracepoint));
old_chain = make_cleanup (xfree, t);
memset (t, 0, sizeof (*t));
t->address = sal.pc;
if (sal.symtab == NULL)
t->source_file = NULL;
else
t->source_file = savestring (sal.symtab->filename,
strlen (sal.symtab->filename));
t->section = sal.section;
t->language = current_language->la_language;
t->input_radix = input_radix;
t->line_number = sal.line;
t->enabled_p = 1;
t->next = 0;
t->step_count = 0;
t->pass_count = 0;
t->addr_string = NULL;
/* Add this tracepoint to the end of the chain
so that a list of tracepoints will come out in order
of increasing numbers. */
tc = tracepoint_chain;
if (tc == 0)
tracepoint_chain = t;
else
{
while (tc->next)
tc = tc->next;
tc->next = t;
}
discard_cleanups (old_chain);
return t;
}
/* Set a tracepoint according to ARG (function, linenum or *address). */
static void
trace_command (char *arg, int from_tty)
{
char **canonical = (char **) NULL;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
struct tracepoint *t;
char *addr_start = 0, *addr_end = 0;
int i;
if (!arg || !*arg)
error (_("trace command requires an argument"));
if (from_tty && info_verbose)
printf_filtered ("TRACE %s\n", arg);
addr_start = arg;
sals = decode_line_1 (&arg, 1, (struct symtab *) NULL,
0, &canonical, NULL);
addr_end = arg;
if (!sals.nelts)
return; /* ??? Presumably decode_line_1 has already warned? */
/* Resolve all line numbers to PC's */
for (i = 0; i < sals.nelts; i++)
resolve_sal_pc (&sals.sals[i]);
/* Now set all the tracepoints. */
for (i = 0; i < sals.nelts; i++)
{
sal = sals.sals[i];
t = set_raw_tracepoint (sal);
set_tracepoint_count (tracepoint_count + 1);
t->number = tracepoint_count;
/* If a canonical line spec is needed use that instead of the
command string. */
if (canonical != (char **) NULL && canonical[i] != NULL)
t->addr_string = canonical[i];
else if (addr_start)
t->addr_string = savestring (addr_start, addr_end - addr_start);
trace_mention (t);
}
if (sals.nelts > 1)
{
printf_filtered ("Multiple tracepoints were set.\n");
printf_filtered ("Use 'delete trace' to delete unwanted tracepoints.\n");
}
}
/* Tell the user we have just set a tracepoint TP. */
static void
trace_mention (struct tracepoint *tp)
{
struct value_print_options opts;
printf_filtered ("Tracepoint %d", tp->number);
get_user_print_options (&opts);
if (opts.addressprint || (tp->source_file == NULL))
{
printf_filtered (" at ");
printf_filtered ("%s", paddress (tp->address));
}
if (tp->source_file)
printf_filtered (": file %s, line %d.",
tp->source_file, tp->line_number);
printf_filtered ("\n");
}
/* Print information on tracepoint number TPNUM_EXP, or all if
omitted. */
static void
tracepoints_info (char *tpnum_exp, int from_tty)
{
struct tracepoint *t;
struct action_line *action;
int found_a_tracepoint = 0;
char wrap_indent[80];
struct symbol *sym;
int tpnum = -1;
if (tpnum_exp)
tpnum = parse_and_eval_long (tpnum_exp);
ALL_TRACEPOINTS (t)
if (tpnum == -1 || tpnum == t->number)
{
struct value_print_options opts;
get_user_print_options (&opts);
if (!found_a_tracepoint++)
{
printf_filtered ("Num Enb ");
if (opts.addressprint)
{
if (gdbarch_addr_bit (current_gdbarch) <= 32)
printf_filtered ("Address ");
else
printf_filtered ("Address ");
}
printf_filtered ("PassC StepC What\n");
}
strcpy (wrap_indent, " ");
if (opts.addressprint)
{
if (gdbarch_addr_bit (current_gdbarch) <= 32)
strcat (wrap_indent, " ");
else
strcat (wrap_indent, " ");
}
printf_filtered ("%-3d %-3s ", t->number,
t->enabled_p ? "y" : "n");
if (opts.addressprint)
{
char *tmp;
if (gdbarch_addr_bit (current_gdbarch) <= 32)
tmp = hex_string_custom (t->address & (CORE_ADDR) 0xffffffff,
8);
else
tmp = hex_string_custom (t->address, 16);
printf_filtered ("%s ", tmp);
}
printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count);
if (t->source_file)
{
sym = find_pc_sect_function (t->address, t->section);
if (sym)
{
fputs_filtered ("in ", gdb_stdout);
fputs_filtered (SYMBOL_PRINT_NAME (sym), gdb_stdout);
wrap_here (wrap_indent);
fputs_filtered (" at ", gdb_stdout);
}
fputs_filtered (t->source_file, gdb_stdout);
printf_filtered (":%d", t->line_number);
}
else
print_address_symbolic (t->address, gdb_stdout, demangle, " ");
printf_filtered ("\n");
if (t->actions)
{
printf_filtered (" Actions for tracepoint %d: \n", t->number);
for (action = t->actions; action; action = action->next)
{
printf_filtered ("\t%s\n", action->action);
}
}
}
if (!found_a_tracepoint)
{
if (tpnum == -1)
printf_filtered ("No tracepoints.\n");
else
printf_filtered ("No tracepoint number %d.\n", tpnum);
}
}
/* Optimization: the code to parse an enable, disable, or delete TP
command is virtually identical except for whether it performs an
enable, disable, or delete. Therefore I've combined them into one
function with an opcode. */
enum tracepoint_opcode
{
enable_op,
disable_op,
delete_op
};
/* This function implements enable, disable and delete commands. */
static void
tracepoint_operation (struct tracepoint *t, int from_tty,
enum tracepoint_opcode opcode)
{
struct tracepoint *t2;
if (t == NULL) /* no tracepoint operand */
return;
switch (opcode)
{
case enable_op:
t->enabled_p = 1;
observer_notify_tracepoint_modified (t->number);
break;
case disable_op:
t->enabled_p = 0;
observer_notify_tracepoint_modified (t->number);
break;
case delete_op:
if (tracepoint_chain == t)
tracepoint_chain = t->next;
ALL_TRACEPOINTS (t2)
if (t2->next == t)
{
t2->next = t->next;
break;
}
observer_notify_tracepoint_deleted (t->number);
if (t->addr_string)
xfree (t->addr_string);
if (t->source_file)
xfree (t->source_file);
if (t->actions)
free_actions (t);
xfree (t);
break;
}
}
/* Utility: parse a tracepoint number and look it up in the list.
If MULTI_P is true, there might be a range of tracepoints in ARG.
if OPTIONAL_P is true, then if the argument is missing, the most
recent tracepoint (tracepoint_count) is returned. */
struct tracepoint *
get_tracepoint_by_number (char **arg, int multi_p, int optional_p)
{
struct tracepoint *t;
int tpnum;
char *instring = arg == NULL ? NULL : *arg;
if (arg == NULL || *arg == NULL || ! **arg)
{
if (optional_p)
tpnum = tracepoint_count;
else
error_no_arg (_("tracepoint number"));
}
else
tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
if (tpnum <= 0)
{
if (instring && *instring)
printf_filtered ("bad tracepoint number at or near '%s'\n",
instring);
else
printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
return NULL;
}
ALL_TRACEPOINTS (t)
if (t->number == tpnum)
{
return t;
}
/* FIXME: if we are in the middle of a range we don't want to give
a message. The current interface to get_number_or_range doesn't
allow us to discover this. */
printf_unfiltered ("No tracepoint number %d.\n", tpnum);
return NULL;
}
/* Utility:
parse a list of tracepoint numbers, and call a func for each. */
static void
map_args_over_tracepoints (char *args, int from_tty,
enum tracepoint_opcode opcode)
{
struct tracepoint *t, *tmp;
if (args == 0 || *args == 0) /* do them all */
ALL_TRACEPOINTS_SAFE (t, tmp)
tracepoint_operation (t, from_tty, opcode);
else
while (*args)
{
QUIT; /* Give user option to bail out with ^C. */
t = get_tracepoint_by_number (&args, 1, 0);
tracepoint_operation (t, from_tty, opcode);
while (*args == ' ' || *args == '\t')
args++;
}
}
/* The 'enable trace' command enables tracepoints.
Not supported by all targets. */
static void
enable_trace_command (char *args, int from_tty)
{
dont_repeat ();
map_args_over_tracepoints (args, from_tty, enable_op);
}
/* The 'disable trace' command disables tracepoints.
Not supported by all targets. */
static void
disable_trace_command (char *args, int from_tty)
{
dont_repeat ();
map_args_over_tracepoints (args, from_tty, disable_op);
}
/* Remove a tracepoint (or all if no argument) */
static void
delete_trace_command (char *args, int from_tty)
{
dont_repeat ();
if (!args || !*args) /* No args implies all tracepoints; */
if (from_tty) /* confirm only if from_tty... */
if (tracepoint_chain) /* and if there are tracepoints to
delete! */
if (!query (_("Delete all tracepoints? ")))
return;
map_args_over_tracepoints (args, from_tty, delete_op);
}
/* Set passcount for tracepoint.
First command argument is passcount, second is tracepoint number.
If tracepoint number omitted, apply to most recently defined.
Also accepts special argument "all". */
static void
trace_pass_command (char *args, int from_tty)
{
struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
unsigned int count;
int all = 0;
if (args == 0 || *args == 0)
error (_("passcount command requires an argument (count + optional TP num)"));
count = strtoul (args, &args, 10); /* Count comes first, then TP num. */
while (*args && isspace ((int) *args))
args++;
if (*args && strncasecmp (args, "all", 3) == 0)
{
args += 3; /* Skip special argument "all". */
all = 1;
if (*args)
error (_("Junk at end of arguments."));
}
else
t1 = get_tracepoint_by_number (&args, 1, 1);
do
{
if (t1)
{
ALL_TRACEPOINTS (t2)
if (t1 == (struct tracepoint *) -1 || t1 == t2)
{
t2->pass_count = count;
observer_notify_tracepoint_modified (t2->number);
if (from_tty)
printf_filtered ("Setting tracepoint %d's passcount to %d\n",
t2->number, count);
}
if (! all && *args)
t1 = get_tracepoint_by_number (&args, 1, 0);
}
}
while (*args);
}
/* ACTIONS functions: */
/* Prototypes for action-parsing utility commands */
static void read_actions (struct tracepoint *);
static void read_actions (struct breakpoint *);
/* The three functions:
collect_pseudocommand,
@ -763,13 +316,13 @@ static void read_actions (struct tracepoint *);
it means that somebody issued the "command" at the top level,
which is always an error. */
static void
void
end_actions_pseudocommand (char *args, int from_tty)
{
error (_("This command cannot be used at the top level."));
}
static void
void
while_stepping_pseudocommand (char *args, int from_tty)
{
error (_("This command can only be used in a tracepoint actions list."));
@ -785,7 +338,7 @@ collect_pseudocommand (char *args, int from_tty)
static void
trace_actions_command (char *args, int from_tty)
{
struct tracepoint *t;
struct breakpoint *t;
char tmpbuf[128];
char *end_msg = "End with a line saying just \"end\".";
@ -816,7 +369,7 @@ trace_actions_command (char *args, int from_tty)
/* worker function */
static void
read_actions (struct tracepoint *t)
read_actions (struct breakpoint *t)
{
char *line;
char *prompt1 = "> ", *prompt2 = " > ";
@ -920,7 +473,7 @@ read_actions (struct tracepoint *t)
/* worker function */
enum actionline_type
validate_actionline (char **line, struct tracepoint *t)
validate_actionline (char **line, struct breakpoint *t)
{
struct cmd_list_element *c;
struct expression *exp = NULL;
@ -971,7 +524,7 @@ validate_actionline (char **line, struct tracepoint *t)
}
/* else fall thru, treat p as an expression and parse it! */
}
exp = parse_exp_1 (&p, block_for_pc (t->address), 1);
exp = parse_exp_1 (&p, block_for_pc (t->loc->address), 1);
old_chain = make_cleanup (free_current_contents, &exp);
if (exp->elts[0].opcode == OP_VAR_VALUE)
@ -994,7 +547,7 @@ validate_actionline (char **line, struct tracepoint *t)
/* We have something to collect, make sure that the expr to
bytecode translator can handle it and that it's not too
long. */
aexpr = gen_trace_for_expr (t->address, exp);
aexpr = gen_trace_for_expr (t->loc->address, exp);
make_cleanup_free_agent_expr (aexpr);
if (aexpr->len > MAX_AGENT_EXPR_LEN)
@ -1044,7 +597,7 @@ validate_actionline (char **line, struct tracepoint *t)
/* worker function */
void
free_actions (struct tracepoint *t)
free_actions (struct breakpoint *t)
{
struct action_line *line, *next;
@ -1065,7 +618,7 @@ do_free_actions_cleanup (void *t)
}
static struct cleanup *
make_cleanup_free_actions (struct tracepoint *t)
make_cleanup_free_actions (struct breakpoint *t)
{
return make_cleanup (do_free_actions_cleanup, t);
}
@ -1483,7 +1036,7 @@ free_actions_list (char **actions_list)
/* Render all actions into gdb protocol. */
static void
encode_actions (struct tracepoint *t, char ***tdp_actions,
encode_actions (struct breakpoint *t, char ***tdp_actions,
char ***stepping_actions)
{
static char tdp_buff[2048], step_buff[2048];
@ -1507,7 +1060,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
*stepping_actions = NULL;
gdbarch_virtual_frame_pointer (current_gdbarch,
t->address, &frame_reg, &frame_offset);
t->loc->address, &frame_reg, &frame_offset);
for (action = t->actions; action; action = action->next)
{
@ -1540,7 +1093,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
else if (0 == strncasecmp ("$arg", action_exp, 4))
{
add_local_symbols (collect,
t->address,
t->loc->address,
frame_reg,
frame_offset,
'A');
@ -1549,7 +1102,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
else if (0 == strncasecmp ("$loc", action_exp, 4))
{
add_local_symbols (collect,
t->address,
t->loc->address,
frame_reg,
frame_offset,
'L');
@ -1563,7 +1116,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
struct agent_reqs areqs;
exp = parse_exp_1 (&action_exp,
block_for_pc (t->address), 1);
block_for_pc (t->loc->address), 1);
old_chain = make_cleanup (free_current_contents, &exp);
switch (exp->elts[0].opcode)
@ -1600,7 +1153,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
break;
default: /* full-fledged expression */
aexpr = gen_trace_for_expr (t->address, exp);
aexpr = gen_trace_for_expr (t->loc->address, exp);
old_chain1 = make_cleanup_free_agent_expr (aexpr);
@ -1732,15 +1285,14 @@ remote_set_transparent_ranges (void)
to the target. If no errors,
Tell target to start a new trace experiment. */
void download_tracepoint (struct breakpoint *t);
static void
trace_start_command (char *args, int from_tty)
{
struct tracepoint *t;
char buf[2048];
char **tdp_actions;
char **stepping_actions;
int ndx;
struct cleanup *old_chain = NULL;
VEC(breakpoint_p) *tp_vec = NULL;
int ix;
struct breakpoint *t;
dont_repeat (); /* Like "run", dangerous to repeat accidentally. */
@ -1751,70 +1303,13 @@ trace_start_command (char *args, int from_tty)
if (strcmp (target_buf, "OK"))
error (_("Target does not support this command."));
ALL_TRACEPOINTS (t)
{
char tmp[40];
tp_vec = all_tracepoints ();
for (ix = 0; VEC_iterate (breakpoint_p, tp_vec, ix, t); ix++)
{
download_tracepoint (t);
}
VEC_free (breakpoint_p, tp_vec);
sprintf_vma (tmp, t->address);
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
tmp, /* address */
t->enabled_p ? 'E' : 'D',
t->step_count, t->pass_count);
if (t->actions)
strcat (buf, "-");
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support tracepoints."));
if (t->actions)
{
encode_actions (t, &tdp_actions, &stepping_actions);
old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
tdp_actions);
(void) make_cleanup (free_actions_list_cleanup_wrapper,
stepping_actions);
/* do_single_steps (t); */
if (tdp_actions)
{
for (ndx = 0; tdp_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%c",
t->number, tmp, /* address */
tdp_actions[ndx],
((tdp_actions[ndx + 1] || stepping_actions)
? '-' : 0));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
if (stepping_actions)
{
for (ndx = 0; stepping_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%s%s",
t->number, tmp, /* address */
((ndx == 0) ? "S" : ""),
stepping_actions[ndx],
(stepping_actions[ndx + 1] ? "-" : ""));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
do_cleanups (old_chain);
}
}
/* Tell target to treat text-like sections as transparent. */
remote_set_transparent_ranges ();
/* Now insert traps and begin collecting data. */
@ -1834,6 +1329,77 @@ trace_start_command (char *args, int from_tty)
error (_("Trace can only be run on remote targets."));
}
/* Send the definition of a single tracepoint to the target. */
void
download_tracepoint (struct breakpoint *t)
{
char tmp[40];
char buf[2048];
char **tdp_actions;
char **stepping_actions;
int ndx;
struct cleanup *old_chain = NULL;
sprintf_vma (tmp, (t->loc ? t->loc->address : 0));
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
tmp, /* address */
(t->enable_state == bp_enabled ? 'E' : 'D'),
t->step_count, t->pass_count);
if (t->actions)
strcat (buf, "-");
putpkt (buf);
remote_get_noisy_reply (&target_buf, &target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Target does not support tracepoints."));
if (!t->actions)
return;
encode_actions (t, &tdp_actions, &stepping_actions);
old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
tdp_actions);
(void) make_cleanup (free_actions_list_cleanup_wrapper, stepping_actions);
/* do_single_steps (t); */
if (tdp_actions)
{
for (ndx = 0; tdp_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%c",
t->number, tmp, /* address */
tdp_actions[ndx],
((tdp_actions[ndx + 1] || stepping_actions)
? '-' : 0));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
if (stepping_actions)
{
for (ndx = 0; stepping_actions[ndx]; ndx++)
{
QUIT; /* allow user to bail out with ^C */
sprintf (buf, "QTDP:-%x:%s:%s%s%s",
t->number, tmp, /* address */
((ndx == 0) ? "S" : ""),
stepping_actions[ndx],
(stepping_actions[ndx + 1] ? "-" : ""));
putpkt (buf);
remote_get_noisy_reply (&target_buf,
&target_buf_size);
if (strcmp (target_buf, "OK"))
error (_("Error on target while setting tracepoints."));
}
}
do_cleanups (old_chain);
}
/* tstop command */
static void
trace_stop_command (char *args, int from_tty)
@ -2284,80 +1850,6 @@ trace_find_outside_command (char *args, int from_tty)
error (_("Trace can only be run on remote targets."));
}
/* save-tracepoints command */
static void
tracepoint_save_command (char *args, int from_tty)
{
struct tracepoint *tp;
struct action_line *line;
FILE *fp;
char *i1 = " ", *i2 = " ";
char *indent, *actionline, *pathname;
char tmp[40];
struct cleanup *cleanup;
if (args == 0 || *args == 0)
error (_("Argument required (file name in which to save tracepoints)"));
if (tracepoint_chain == 0)
{
warning (_("save-tracepoints: no tracepoints to save."));
return;
}
pathname = tilde_expand (args);
cleanup = make_cleanup (xfree, pathname);
if (!(fp = fopen (pathname, "w")))
error (_("Unable to open file '%s' for saving tracepoints (%s)"),
args, safe_strerror (errno));
make_cleanup_fclose (fp);
ALL_TRACEPOINTS (tp)
{
if (tp->addr_string)
fprintf (fp, "trace %s\n", tp->addr_string);
else
{
sprintf_vma (tmp, tp->address);
fprintf (fp, "trace *0x%s\n", tmp);
}
if (tp->pass_count)
fprintf (fp, " passcount %d\n", tp->pass_count);
if (tp->actions)
{
fprintf (fp, " actions\n");
indent = i1;
for (line = tp->actions; line; line = line->next)
{
struct cmd_list_element *cmd;
QUIT; /* allow user to bail out with ^C */
actionline = line->action;
while (isspace ((int) *actionline))
actionline++;
fprintf (fp, "%s%s\n", indent, actionline);
if (*actionline != '#') /* skip for comment lines */
{
cmd = lookup_cmd (&actionline, cmdlist, "", -1, 1);
if (cmd == 0)
error (_("Bad action list item: %s"), actionline);
if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
indent = i2;
else if (cmd_cfunc_eq (cmd, end_actions_pseudocommand))
indent = i1;
}
}
}
}
do_cleanups (cleanup);
if (from_tty)
printf_filtered ("Tracepoints saved to file '%s'.\n", args);
return;
}
/* info scope command: list the locals for a scope. */
static void
scope_info (char *args, int from_tty)
@ -2503,7 +1995,7 @@ trace_dump_command (char *args, int from_tty)
{
struct regcache *regcache;
struct gdbarch *gdbarch;
struct tracepoint *t;
struct breakpoint *t;
struct action_line *action;
char *action_exp, *next_comma;
struct cleanup *old_cleanups;
@ -2522,9 +2014,7 @@ trace_dump_command (char *args, int from_tty)
return;
}
ALL_TRACEPOINTS (t)
if (t->number == tracepoint_number)
break;
t = get_tracepoint (tracepoint_number);
if (t == NULL)
error (_("No known tracepoint matches 'current' tracepoint #%d."),
@ -2542,7 +2032,7 @@ trace_dump_command (char *args, int from_tty)
regcache = get_current_regcache ();
gdbarch = get_regcache_arch (regcache);
stepping_frame = (t->address != (regcache_read_pc (regcache)
stepping_frame = (t->loc->address != (regcache_read_pc (regcache)
- gdbarch_decr_pc_after_break (gdbarch)));
for (action = t->actions; action; action = action->next)
@ -2654,8 +2144,6 @@ _initialize_tracepoint (void)
{
struct cmd_list_element *c;
tracepoint_chain = 0;
tracepoint_count = 0;
traceframe_number = -1;
tracepoint_number = -1;
@ -2693,18 +2181,6 @@ _initialize_tracepoint (void)
_("Tracing of program execution without stopping the program."),
&cmdlist);
add_info ("tracepoints", tracepoints_info, _("\
Status of tracepoints, or tracepoint number NUMBER.\n\
Convenience variable \"$tpnum\" contains the number of the\n\
last tracepoint set."));
add_info_alias ("tp", "tracepoints", 1);
c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
Save current tracepoint definitions as a script.\n\
Use the 'source' command in another debug session to restore them."));
set_cmd_completer (c, filename_completer);
add_com ("tdump", class_trace, trace_dump_command,
_("Print everything collected at the current tracepoint."));
@ -2762,12 +2238,6 @@ De-select any trace frame and resume 'live' debugging."),
add_com ("tstart", class_trace, trace_start_command,
_("Start trace data collection."));
add_com ("passcount", class_trace, trace_pass_command, _("\
Set the passcount for a tracepoint.\n\
The trace will end when the tracepoint has been passed 'count' times.\n\
Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
if TPNUM is omitted, passcount refers to the last tracepoint defined."));
add_com ("end", class_trace, end_actions_pseudocommand, _("\
Ends a list of commands or actions.\n\
Several GDB commands allow you to enter a list of commands or actions.\n\
@ -2802,37 +2272,6 @@ Tracepoint actions may include collecting of specified data, \n\
single-stepping, or enabling/disabling other tracepoints, \n\
depending on target's capabilities."));
add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
Delete specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means delete all tracepoints."),
&deletelist);
add_cmd ("tracepoints", class_trace, disable_trace_command, _("\
Disable specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means disable all tracepoints."),
&disablelist);
add_cmd ("tracepoints", class_trace, enable_trace_command, _("\
Enable specified tracepoints.\n\
Arguments are tracepoint numbers, separated by spaces.\n\
No argument means enable all tracepoints."),
&enablelist);
c = add_com ("trace", class_trace, trace_command, _("\
Set a tracepoint at a specified line or function or address.\n\
Argument may be a line number, function name, or '*' plus an address.\n\
For a line number or function, trace at the start of its code.\n\
If an address is specified, trace at that exact address.\n\n\
Do \"help tracepoints\" for info on other tracepoint commands."));
set_cmd_completer (c, location_completer);
add_com_alias ("tp", "trace", class_alias, 0);
add_com_alias ("tr", "trace", class_alias, 1);
add_com_alias ("tra", "trace", class_alias, 1);
add_com_alias ("trac", "trace", class_alias, 1);
target_buf_size = 2048;
target_buf = xmalloc (target_buf_size);
}

View File

@ -27,76 +27,6 @@ struct action_line
char *action;
};
/* The data structure for a tracepoint: */
struct tracepoint
{
struct tracepoint *next;
int enabled_p;
#if 0
/* Type of tracepoint. (MVS FIXME: needed?) */
enum tptype type;
/* What to do with this tracepoint after we hit it
MVS FIXME: needed?). */
enum tpdisp disposition;
#endif
/* Number assigned to distinguish tracepoints. */
int number;
/* Address to trace at, or NULL if not an instruction tracepoint.
(MVS ?) */
CORE_ADDR address;
/* Line number of this address.
Only matters if address is non-NULL. */
int line_number;
/* Source file name of this address.
Only matters if address is non-NULL. */
char *source_file;
/* Number of times this tracepoint should single-step
and collect additional data. */
long step_count;
/* Number of times this tracepoint should be hit before
disabling/ending. */
int pass_count;
/* Chain of action lines to execute when this tracepoint is hit. */
struct action_line *actions;
/* Conditional (MVS ?). */
struct expression *cond;
/* String we used to set the tracepoint (malloc'd).
Only matters if address is non-NULL. */
char *addr_string;
/* Language we used to set the tracepoint. */
enum language language;
/* Input radix we used to set the tracepoint. */
int input_radix;
/* Count of the number of times this tracepoint was taken, dumped
with the info, but not used for anything else. Useful for
seeing how many times you hit a tracepoint prior to the program
aborting, so you can back up to just before the abort. */
int hit_count;
/* Thread number for thread-specific tracepoint,
or -1 if don't care. */
int thread;
/* BFD section, in case of overlays: no, I don't know if
tracepoints are really gonna work with overlays. */
struct obj_section *section;
};
enum actionline_type
{
BADLINE = -1,
@ -105,35 +35,18 @@ enum actionline_type
STEPPING = 2
};
/* The tracepoint chain of all tracepoints. */
extern struct tracepoint *tracepoint_chain;
extern unsigned long trace_running_p;
/* A hook used to notify the UI of tracepoint operations. */
void (*deprecated_create_tracepoint_hook) (struct tracepoint *);
void (*deprecated_delete_tracepoint_hook) (struct tracepoint *);
void (*deprecated_modify_tracepoint_hook) (struct tracepoint *);
void (*deprecated_trace_find_hook) (char *arg, int from_tty);
void (*deprecated_trace_start_stop_hook) (int start, int from_tty);
struct tracepoint *get_tracepoint_by_number (char **, int, int);
int get_traceframe_number (void);
void free_actions (struct tracepoint *);
enum actionline_type validate_actionline (char **, struct tracepoint *);
void free_actions (struct breakpoint *);
enum actionline_type validate_actionline (char **, struct breakpoint *);
extern void end_actions_pseudocommand (char *args, int from_tty);
extern void while_stepping_pseudocommand (char *args, int from_tty);
/* Walk the following statement or block through all tracepoints.
ALL_TRACEPOINTS_SAFE does so even if the statment deletes the
current breakpoint. */
#define ALL_TRACEPOINTS(t) for (t = tracepoint_chain; t; t = t->next)
#define ALL_TRACEPOINTS_SAFE(t,tmp) \
for (t = tracepoint_chain; \
t ? (tmp = t->next, 1) : 0;\
t = tmp)
#endif /* TRACEPOINT_H */