2011-10-06 Justin Lebar <justin.lebar@gmail.com>

* Makefile.in: (SFILES): Add skip.c.
	(HFILES_NO_SRCDIR): Add skip.h.
	(COMMON_OBS): Add skip.o.
	* skip.h, skip.c: New.
	* breakpoint.h (set_default_breakpoint): Remove.
	(get_sal_arch): Declare.
	* breakpoint.c: Remove default_breakpoint_valid,
	default_breakpoint_address, default_breakpoint_symtab,
	default_breakpoint_line, default_breakpoint_pspace variables.
	(get_sal_arch): Make public.
	(set_default_breakpoint): Remove.
	(parse_breakpoint_sals, create_breakpoint, clear_command,
	decode_line_spec_1): Remove uses of default_breakpoint variables;
	replaced with function calls into stack.c.
	* cli/cli-cmds.h: Add cmd_list_element *skiplist.
	* cli/cli-cmds.c: Add skiplist.
	(init_cmd_lists): Initialize skiplist.
	(init_cli_cmds): Fix comment (classes of commands appear in
	alphabetical order).
	* infrun.c (handle_inferior_event): Add check that we don't step into
	a function whose pc is marked for skip.
	* stack.c: Declare last_displayed_sal_valid, last_displayed_pspace,
	last_displayed_addr, last_displayed_symtab, last_displayed_line
	variables.
	(set_last_displayed_sal): New static function.
	(print_frame_info): Switch call to set_default_breakpoint to call to
	set_last_displayed_sal.
	(clear_last_displayed_sal, last_displayed_sal_is_valid,
	get_last_displayed_pspace, get_last_displayed_addr,
	get_last_displayed_symtab, get_last_displayed_line,
	get_last_displayed_sal): New public functions.
	* stack.h (clear_last_displayed_sal, last_displayed_sal_is_valid,
	get_last_displayed_pspace, get_last_displayed_addr,
	get_last_displayed_symtab, get_last_displayed_line,
	get_last_displayed_sal): Declare.

2011-10-06  Justin Lebar <justin.lebar@gmail.com>

	Add tests for skip command.
	* testsuite/gdb.base/skip-solib-lib.c: New
	* testsuite/gdb.base/skip-solib-main.c: New
	* testsuite/gdb.base/skip-solib.exp: New
	* testsuite/gdb.base/skip.c: New
	* testsuite/gdb.base/skip.exp: New
	* testsuite/gdb.base/skip1.c: New
	* testsuite/gdb.base/Makefile.in: Adding new files.
This commit is contained in:
Justin Lebar 2011-11-01 14:51:25 +00:00
parent b60e158872
commit 1bfeeb0f75
23 changed files with 1324 additions and 67 deletions

View File

@ -1,3 +1,41 @@
2011-10-06 Justin Lebar <justin.lebar@gmail.com>
* Makefile.in: (SFILES): Add skip.c.
(HFILES_NO_SRCDIR): Add skip.h.
(COMMON_OBS): Add skip.o.
* skip.h, skip.c: New.
* breakpoint.h (set_default_breakpoint): Remove.
(get_sal_arch): Declare.
* breakpoint.c: Remove default_breakpoint_valid,
default_breakpoint_address, default_breakpoint_symtab,
default_breakpoint_line, default_breakpoint_pspace variables.
(get_sal_arch): Make public.
(set_default_breakpoint): Remove.
(parse_breakpoint_sals, create_breakpoint, clear_command,
decode_line_spec_1): Remove uses of default_breakpoint variables;
replaced with function calls into stack.c.
* cli/cli-cmds.h: Add cmd_list_element *skiplist.
* cli/cli-cmds.c: Add skiplist.
(init_cmd_lists): Initialize skiplist.
(init_cli_cmds): Fix comment (classes of commands appear in
alphabetical order).
* infrun.c (handle_inferior_event): Add check that we don't step into
a function whose pc is marked for skip.
* stack.c: Declare last_displayed_sal_valid, last_displayed_pspace,
last_displayed_addr, last_displayed_symtab, last_displayed_line
variables.
(set_last_displayed_sal): New static function.
(print_frame_info): Switch call to set_default_breakpoint to call to
set_last_displayed_sal.
(clear_last_displayed_sal, last_displayed_sal_is_valid,
get_last_displayed_pspace, get_last_displayed_addr,
get_last_displayed_symtab, get_last_displayed_line,
get_last_displayed_sal): New public functions.
* stack.h (clear_last_displayed_sal, last_displayed_sal_is_valid,
get_last_displayed_pspace, get_last_displayed_addr,
get_last_displayed_symtab, get_last_displayed_line,
get_last_displayed_sal): Declare.
2011-11-01 Justin Lebar <justin.lebar@gmail.com>
* MAINTAINERS (Write After Approval): Add myself to the list.

View File

@ -727,7 +727,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
prologue-value.c psymtab.c \
regcache.c reggroups.c remote.c remote-fileio.c reverse.c \
sentinel-frame.c \
serial.c ser-base.c ser-unix.c \
serial.c ser-base.c ser-unix.c skip.c \
solib.c solib-target.c source.c \
stabsread.c stack.c std-regs.c symfile.c symfile-mem.c symmisc.c \
symtab.c \
@ -827,7 +827,7 @@ osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
python/python-internal.h python/python.h ravenscar-thread.h record.h \
solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
gnulib/extra/arg-nonnull.h gnulib/extra/c++defs.h gnulib/extra/warn-on-use.h \
gnulib/stddef.in.h inline-frame.h \
gnulib/stddef.in.h inline-frame.h skip.h \
common/common-utils.h common/xml-utils.h common/buffer.h common/ptid.h \
common/linux-osdata.h
@ -915,7 +915,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
xml-support.o xml-syscall.o xml-utils.o \
target-descriptions.o target-memory.o xml-tdesc.o xml-builtin.o \
inferior.o osdata.o gdb_usleep.o record.o gcore.o \
jit.o progspace.o \
jit.o progspace.o skip.o \
common-utils.o buffer.o ptid.o
TSOBS = inflow.o

View File

@ -3,6 +3,9 @@
*** Changes since GDB 7.3.1
* GDB now allows you to skip uninteresting functions and files when
stepping with the "skip function" and "skip file" commands.
* GDB has two new commands: "set remote hardware-watchpoint-length-limit"
and "show remote hardware-watchpoint-length-limit". These allows to
set or show the maximum length limit (in bytes) of a remote

View File

@ -65,6 +65,8 @@
#include "parser-defs.h"
#include "cli/cli-utils.h"
#include "continuations.h"
#include "stack.h"
#include "skip.h"
/* readline include files */
#include "readline/readline.h"
@ -572,19 +574,6 @@ make_cleanup_decref_counted_command_line (struct counted_command_line **cmdp)
return make_cleanup (do_cleanup_counted_command_line, cmdp);
}
/* Default address, symtab and line to put a breakpoint at
for "break" command with no arg.
If default_breakpoint_valid is zero, the other three are
not valid, and "break" with no arg is an error.
This set by print_stack_frame, which calls set_default_breakpoint. */
int default_breakpoint_valid;
CORE_ADDR default_breakpoint_address;
struct symtab *default_breakpoint_symtab;
int default_breakpoint_line;
struct program_space *default_breakpoint_pspace;
/* Return the breakpoint with the specified number, or NULL
if the number does not refer to an existing breakpoint. */
@ -5339,20 +5328,6 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
}
}
/* Set the default place to put a breakpoint
for the `break' command with no arguments. */
void
set_default_breakpoint (int valid, struct program_space *pspace,
CORE_ADDR addr, struct symtab *symtab,
int line)
{
default_breakpoint_valid = valid;
default_breakpoint_pspace = pspace;
default_breakpoint_address = addr;
default_breakpoint_symtab = symtab;
default_breakpoint_line = line;
}
/* Return true iff it is meaningful to use the address member of
BPT. For some breakpoint types, the address member is irrelevant
@ -5764,7 +5739,7 @@ set_breakpoint_location_function (struct bp_location *loc, int explicit_loc)
}
/* Attempt to determine architecture of location identified by SAL. */
static struct gdbarch *
struct gdbarch *
get_sal_arch (struct symtab_and_line sal)
{
if (sal.section)
@ -7543,24 +7518,26 @@ parse_breakpoint_sals (char **address,
if ((*address) == NULL
|| (strncmp ((*address), "if", 2) == 0 && isspace ((*address)[2])))
{
if (default_breakpoint_valid)
/* The last displayed codepoint, if it's valid, is our default breakpoint
address. */
if (last_displayed_sal_is_valid ())
{
struct symtab_and_line sal;
init_sal (&sal); /* Initialize to zeroes. */
sals->sals = (struct symtab_and_line *)
xmalloc (sizeof (struct symtab_and_line));
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
sal.pspace = default_breakpoint_pspace;
sal.section = find_pc_overlay (sal.pc);
/* Set sal's pspace, pc, symtab, and line to the values
corresponding to the last call to print_frame_info. */
get_last_displayed_sal (&sal);
sal.section = find_pc_overlay (sal.pc);
/* "break" without arguments is equivalent to "break *PC"
where PC is the default_breakpoint_address. So make sure
to set sal.explicit_pc to prevent GDB from trying to
expand the list of sals to include all other instances
with the same symtab and line. */
where PC is the last displayed codepoint's address. So
make sure to set sal.explicit_pc to prevent GDB from
trying to expand the list of sals to include all other
instances with the same symtab and line. */
sal.explicit_pc = 1;
sals->sals[0] = sal;
@ -7574,19 +7551,22 @@ parse_breakpoint_sals (char **address,
/* Force almost all breakpoints to be in terms of the
current_source_symtab (which is decode_line_1's default).
This should produce the results we want almost all of the
time while leaving default_breakpoint_* alone.
time while leaving the last displayed codepoint pointers
alone.
ObjC: However, don't match an Objective-C method name which
may have a '+' or '-' succeeded by a '[' */
struct symtab_and_line cursal = get_current_source_symtab_and_line ();
if (default_breakpoint_valid
if (last_displayed_sal_is_valid ()
&& (!cursal.symtab
|| ((strchr ("+-", (*address)[0]) != NULL)
&& ((*address)[1] != '['))))
*sals = decode_line_1 (address, 1, default_breakpoint_symtab,
default_breakpoint_line, canonical);
*sals = decode_line_1 (address, 1,
get_last_displayed_symtab (),
get_last_displayed_line (),
canonical);
else
*sals = decode_line_1 (address, 1, (struct symtab *) NULL, 0,
canonical);
@ -9611,9 +9591,11 @@ until_break_command (char *arg, int from_tty, int anywhere)
/* Set a breakpoint where the user wants it and at return from
this function. */
if (default_breakpoint_valid)
sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,
default_breakpoint_line, NULL);
if (last_displayed_sal_is_valid ())
sals = decode_line_1 (&arg, 1,
get_last_displayed_symtab (),
get_last_displayed_line (),
NULL);
else
sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, NULL);
@ -10135,10 +10117,11 @@ clear_command (char *arg, int from_tty)
xmalloc (sizeof (struct symtab_and_line));
make_cleanup (xfree, sals.sals);
init_sal (&sal); /* Initialize to zeroes. */
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
sal.pc = default_breakpoint_address;
sal.pspace = default_breakpoint_pspace;
/* Set sal's line, symtab, pc, and pspace to the values
corresponding to the last call to print_frame_info. If the
codepoint is not valid, this will set all the fields to 0. */
get_last_displayed_sal (&sal);
if (sal.symtab == 0)
error (_("No source file specified."));
@ -11986,6 +11969,9 @@ breakpoint_re_set (void)
create_longjmp_master_breakpoint ();
create_std_terminate_master_breakpoint ();
create_exception_master_breakpoint ();
/* While we're at it, reset the skip list too. */
skip_re_set ();
}
/* Reset the thread number of this breakpoint:
@ -12435,7 +12421,8 @@ invalidate_bp_value_on_memory_change (CORE_ADDR addr, int len,
}
}
/* Use default_breakpoint_'s, or nothing if they aren't valid. */
/* Use the last displayed codepoint's values, or nothing
if they aren't valid. */
struct symtabs_and_lines
decode_line_spec_1 (char *string, int funfirstline)
@ -12444,10 +12431,10 @@ decode_line_spec_1 (char *string, int funfirstline)
if (string == 0)
error (_("Empty line specification."));
if (default_breakpoint_valid)
if (last_displayed_sal_is_valid ())
sals = decode_line_1 (&string, funfirstline,
default_breakpoint_symtab,
default_breakpoint_line,
get_last_displayed_symtab (),
get_last_displayed_line (),
NULL);
else
sals = decode_line_1 (&string, funfirstline,

View File

@ -1033,9 +1033,6 @@ extern struct breakpoint *clone_momentary_breakpoint (struct breakpoint *bpkt);
extern void set_ignore_count (int, int, int);
extern void set_default_breakpoint (int, struct program_space *,
CORE_ADDR, struct symtab *, int);
extern void breakpoint_init_inferior (enum inf_context);
extern struct cleanup *make_cleanup_delete_breakpoint (struct breakpoint *);
@ -1365,4 +1362,7 @@ extern int pc_at_non_inline_function (struct address_space *aspace,
extern int user_breakpoint_p (struct breakpoint *);
/* Attempt to determine architecture of location identified by SAL. */
extern struct gdbarch *get_sal_arch (struct symtab_and_line sal);
#endif /* !defined (BREAKPOINT_H) */

View File

@ -186,6 +186,8 @@ struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
struct cmd_list_element *skiplist;
/* Command tracing state. */
int source_verbose = 0;
@ -1511,6 +1513,7 @@ init_cmd_lists (void)
showprintlist = NULL;
setchecklist = NULL;
showchecklist = NULL;
skiplist = NULL;
}
static void
@ -1576,7 +1579,7 @@ init_cli_cmds (void)
char *source_help_text;
/* Define the classes of commands.
They will appear in the help list in the reverse of this order. */
They will appear in the help list in alphabetical order. */
add_cmd ("internals", class_maintenance, NULL, _("\
Maintenance commands.\n\

View File

@ -106,6 +106,8 @@ extern struct cmd_list_element *setchecklist;
extern struct cmd_list_element *showchecklist;
extern struct cmd_list_element *skiplist;
/* Exported to gdb/top.c */
void init_cmd_lists (void);

View File

@ -4854,6 +4854,111 @@ proceed until the function returns.
An argument is a repeat count, as in @code{next}.
@end table
@node Skipping Over Functions and Files
@subsection Skipping Over Functions and Files
@cindex skipping over functions and files
The program you are debugging may contain some functions which are
uninteresting to debug. The @code{skip} comand lets you tell @value{GDBN} to
skip a function or all functions in a file when stepping.
For example, consider the following C function:
@smallexample
101 int func()
102 @{
103 foo(boring());
104 bar(boring());
105 @}
@end smallexample
@noindent
Suppose you wish to step into the functions @code{foo} and @code{bar}, but you
are not interested in stepping through @code{boring}. If you run @code{step}
at line 103, you'll enter @code{boring()}, but if you run @code{next}, you'll
step over both @code{foo} and @code{boring}!
One solution is to @code{step} into @code{boring} and use the @code{finish}
command to immediately exit it. But this can become tedious if @code{boring}
is called from many places.
A more flexible solution is to execute @kbd{skip boring}. This instructs
@value{GDBN} never to step into @code{boring}. Now when you execute
@code{step} at line 103, you'll step over @code{boring} and directly into
@code{foo}.
You can also instruct @value{GDBN} to skip all functions in a file, with, for
example, @code{skip file boring.c}.
@table @code
@kindex skip function
@item skip @r{[}@var{linespec}@r{]}
@itemx skip function @r{[}@var{linespec}@r{]}
After running this command, the function named by @var{linespec} or the
function containing the line named by @var{linespec} will be skipped over when
stepping. @xref{Specify Location}
If you do not specify @var{linespec}, the function you're currently debugging
will be skipped.
(If you have a function called @code{file} that you want to skip, use
@kbd{skip function file}.)
@kindex skip file
@item skip file @r{[}@var{filename}@r{]}
After running this command, any function whose source lives in @var{filename}
will be skipped over when stepping.
If you do not specify @var{filename}, functions whose source lives in the file
you're currently debugging will be skipped.
@end table
Skips can be listed, deleted, disabled, and enabled, much like breakpoints.
These are the commands for managing your list of skips:
@table @code
@kindex info skip
@item info skip @r{[}@var{range}@r{]}
Print details about the specified skip(s). If @var{range} is not specified,
print a table with details about all functions and files marked for skipping.
@code{info skip} prints the following information about each skip:
@table @emph
@item Identifier
A number identifying this skip.
@item Type
The type of this skip, either @samp{function} or @samp{file}.
@item Enabled or Disabled
Enabled skips are marked with @samp{y}. Disabled skips are marked with @samp{n}.
@item Address
For function skips, this column indicates the address in memory of the function
being skipped. If you've set a function skip on a function which has not yet
been loaded, this field will contain @samp{<PENDING>}. Once a shared library
which has the function is loaded, @code{info skip} will show the function's
address here.
@item What
For file skips, this field contains the filename being skipped. For functions
skips, this field contains the function name and its line number in the file
where it is defined.
@end table
@kindex skip delete
@item skip delete @r{[}@var{range}@r{]}
Delete the specified skip(s). If @var{range} is not specified, delete all
skips.
@kindex skip enable
@item skip enable @r{[}@var{range}@r{]}
Enable the specified skip(s). If @var{range} is not specified, enable all
skips.
@kindex skip disable
@item skip disable @r{[}@var{range}@r{]}
Disable the specified skip(s). If @var{range} is not specified, disable all
skips.
@end table
@node Signals
@section Signals
@cindex signals

View File

@ -124,6 +124,8 @@ extern struct cmd_list_element *setchecklist;
extern struct cmd_list_element *showchecklist;
extern struct cmd_list_element *skiplist;
/* Chain containing all defined "save" subcommands. */
extern struct cmd_list_element *save_cmdlist;

View File

@ -56,6 +56,7 @@
#include "tracepoint.h"
#include "continuations.h"
#include "interps.h"
#include "skip.h"
/* Prototypes for local functions */
@ -4917,7 +4918,8 @@ process_event_stop_test:
}
/* If we have line number information for the function we are
thinking of stepping into, step into it.
thinking of stepping into and the function isn't on the skip
list, step into it.
If there are several symtabs at that PC (e.g. with include
files), just want to know whether *any* of them have line
@ -4926,7 +4928,8 @@ process_event_stop_test:
struct symtab_and_line tmp_sal;
tmp_sal = find_pc_line (ecs->stop_func_start, 0);
if (tmp_sal.line != 0)
if (tmp_sal.line != 0 &&
!function_pc_is_marked_for_skip (ecs->stop_func_start))
{
if (execution_direction == EXEC_REVERSE)
handle_step_into_function_backward (gdbarch, ecs);

602
gdb/skip.c Normal file
View File

@ -0,0 +1,602 @@
/* Skipping uninteresting files and functions while stepping.
Copyright (C) 2011 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "skip.h"
#include "value.h"
#include "valprint.h"
#include "ui-out.h"
#include "gdb_string.h"
#include "symtab.h"
#include "gdbcmd.h"
#include "command.h"
#include "completer.h"
#include "stack.h"
#include "cli/cli-utils.h"
#include "arch-utils.h"
#include "linespec.h"
#include "objfiles.h"
#include "exceptions.h"
#include "breakpoint.h" /* for get_sal_arch () */
struct skiplist_entry
{
int number;
/* NULL if this isn't a skiplist entry for an entire file.
The skiplist entry owns this pointer. */
char *filename;
/* The name of the marked-for-skip function, if this is a skiplist
entry for a function. Note that this might be non-null even if
the pc is 0 if the entry is pending a shared library load.
The skiplist entry owns this pointer. */
char *function_name;
/* 0 if this is a skiplist entry for an entire file, or if this
entry will be on a function, pending a shared library load. */
CORE_ADDR pc;
/* Architecture we used to create the skiplist entry. May be null
if the entry is pending a shared library load. */
struct gdbarch *gdbarch;
int enabled;
int pending;
struct skiplist_entry *next;
};
static void skip_function_command (char *arg, int from_tty);
static void skip_file_command (char *arg, int from_tty);
static void skip_info (char *arg, int from_tty);
static void add_skiplist_entry (struct skiplist_entry *e);
static void skip_function_pc (CORE_ADDR pc, char *name,
struct gdbarch *arch,
int pending);
static struct skiplist_entry *skiplist_entry_chain;
static int skiplist_entry_count;
#define ALL_SKIPLIST_ENTRIES(E) \
for (E = skiplist_entry_chain; E; E = E->next)
#define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \
for (E = skiplist_entry_chain; \
E ? (TMP = E->next, 1) : 0; \
E = TMP)
static void
skip_file_command (char *arg, int from_tty)
{
struct skiplist_entry *e;
struct symtab *symtab;
int pending = 0;
char *filename = 0;
/* If no argument was given, try to default to the last
displayed codepoint. */
if (arg == 0)
{
symtab = get_last_displayed_symtab ();
if (symtab == 0)
error (_("No default file now."));
else
filename = symtab->filename;
}
else
{
symtab = lookup_symtab (arg);
if (symtab == 0)
{
fprintf_filtered (gdb_stderr, _("No source file named %s.\n"), arg);
if (!nquery (_("\
Ignore file pending future shared library load? ")))
return;
pending = 1;
filename = arg;
}
else
filename = symtab->filename;
}
e = XZALLOC (struct skiplist_entry);
e->filename = xstrdup (filename);
e->enabled = 1;
e->pending = pending;
if (symtab != 0)
e->gdbarch = get_objfile_arch (symtab->objfile);
add_skiplist_entry (e);
printf_filtered (_("File %s will be skipped when stepping.\n"), filename);
}
static void
skip_function_command (char *arg, int from_tty)
{
CORE_ADDR func_pc;
char *name = NULL;
/* Default to the current function if no argument is given. */
if (arg == 0)
{
CORE_ADDR pc;
if (!last_displayed_sal_is_valid ())
error (_("No default function now."));
pc = get_last_displayed_addr ();
if (!find_pc_partial_function (pc, &name, &func_pc, 0))
{
error (_("No function found containing current program point %s."),
paddress (get_current_arch (), pc));
}
skip_function_pc (func_pc, name, get_current_arch (), 0);
}
else
{
/* Decode arg. We set funfirstline=1 so decode_line_1 will give us the
first line of the function specified, if it can, and so that we'll
reject variable names and the like. */
int i;
int pending = 0;
char *orig_arg = arg; /* decode_line_1 modifies the arg pointer. */
volatile struct gdb_exception decode_exception;
struct symtabs_and_lines sals;
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
{
sals = decode_line_1 (&arg, 1, 0, 0, 0);
}
if (decode_exception.reason < 0)
{
if (decode_exception.error != NOT_FOUND_ERROR)
throw_exception (decode_exception);
fprintf_filtered (gdb_stderr,
_("No function found named %s.\n"), orig_arg);
if (nquery (_("\
Ignore function pending future shared library load? ")))
{
/* Add the pending skiplist entry. */
skip_function_pc (0, orig_arg, 0, 1);
}
return;
}
if (sals.nelts > 1)
error (_("Specify just one function at a time."));
if (strlen (arg) != 0)
error (_("Junk at end of arguments."));
/* The pc decode_line_1 gives us is the first line of the function,
but we actually want the line before that. The call to
find_pc_partial_function gets us the value we actually want. */
{
struct symtab_and_line sal = sals.sals[0];
CORE_ADDR pc = sal.pc;
CORE_ADDR func_start = 0;
struct gdbarch *arch = get_sal_arch (sal);
if (!find_pc_partial_function (pc, &name, &func_start, 0))
{
error (_("No function found containing program point %s."),
paddress (arch, pc));
}
skip_function_pc (func_start, name, arch, 0);
}
}
}
static void
skip_info (char *arg, int from_tty)
{
struct skiplist_entry *e;
int num_printable_entries = 0;
int address_width = 10;
struct value_print_options opts;
struct cleanup *tbl_chain;
get_user_print_options (&opts);
/* Count the number of rows in the table and see if we need space for a
64-bit address anywhere. */
ALL_SKIPLIST_ENTRIES (e)
if (arg == 0 || number_is_in_list (arg, e->number))
{
num_printable_entries++;
if (e->gdbarch && gdbarch_addr_bit (e->gdbarch) > 32)
address_width = 18;
}
if (num_printable_entries == 0)
{
if (arg == 0)
ui_out_message (current_uiout, 0, _("\
Not skipping any files or functions.\n"));
else
ui_out_message (current_uiout, 0,
_("No skiplist entries found with number %s.\n"), arg);
return;
}
if (opts.addressprint)
tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 5,
num_printable_entries,
"SkiplistTable");
else
tbl_chain
= make_cleanup_ui_out_table_begin_end (current_uiout, 4,
num_printable_entries,
"SkiplistTable");
ui_out_table_header (current_uiout, 7, ui_left, "number", "Num"); /* 1 */
ui_out_table_header (current_uiout, 14, ui_left, "type", "Type"); /* 2 */
ui_out_table_header (current_uiout, 3, ui_left, "enabled", "Enb"); /* 3 */
if (opts.addressprint)
{
ui_out_table_header (current_uiout, address_width, ui_left,
"addr", "Address"); /* 4 */
}
ui_out_table_header (current_uiout, 40, ui_noalign, "what", "What"); /* 5 */
ui_out_table_body (current_uiout);
ALL_SKIPLIST_ENTRIES (e)
{
struct cleanup *entry_chain;
QUIT;
if (arg != 0 && !number_is_in_list (arg, e->number))
continue;
entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
"blklst-entry");
ui_out_field_int (current_uiout, "number", e->number); /* 1 */
if (e->function_name != 0)
ui_out_field_string (current_uiout, "type", "function"); /* 2 */
else if (e->filename != 0)
ui_out_field_string (current_uiout, "type", "file"); /* 2 */
else
internal_error (__FILE__, __LINE__, _("\
Skiplist entry should have either a filename or a function name."));
if (e->enabled)
ui_out_field_string (current_uiout, "enabled", "y"); /* 3 */
else
ui_out_field_string (current_uiout, "enabled", "n"); /* 3 */
if (opts.addressprint)
{
if (e->pc != 0)
ui_out_field_core_addr (current_uiout, "addr",
e->gdbarch, e->pc); /* 4 */
else
ui_out_field_string (current_uiout, "addr", ""); /* 4 */
}
if (!e->pending && e->function_name != 0)
{
struct symbol *sym;
gdb_assert (e->pc != 0);
sym = find_pc_function (e->pc);
if (sym)
ui_out_field_fmt (current_uiout, "what", "%s at %s:%d",
sym->ginfo.name,
sym->symtab->filename,
sym->line);
else
ui_out_field_string (current_uiout, "what", "?");
}
else if (e->pending && e->function_name != 0)
{
ui_out_field_fmt (current_uiout, "what", "%s (PENDING)",
e->function_name);
}
else if (!e->pending && e->filename != 0)
ui_out_field_string (current_uiout, "what", e->filename);
else if (e->pending && e->filename != 0)
ui_out_field_fmt (current_uiout, "what", "%s (PENDING)",
e->filename);
ui_out_text (current_uiout, "\n");
do_cleanups (entry_chain);
}
do_cleanups (tbl_chain);
}
static void
skip_enable_command (char *arg, int from_tty)
{
struct skiplist_entry *e;
int found = 0;
ALL_SKIPLIST_ENTRIES (e)
if (arg == 0 || number_is_in_list (arg, e->number))
{
e->enabled = 1;
found = 1;
}
if (!found)
error (_("No skiplist entries found with number %s."), arg);
}
static void
skip_disable_command (char *arg, int from_tty)
{
struct skiplist_entry *e;
int found = 0;
ALL_SKIPLIST_ENTRIES (e)
if (arg == 0 || number_is_in_list (arg, e->number))
{
e->enabled = 0;
found = 1;
}
if (!found)
error (_("No skiplist entries found with number %s."), arg);
}
static void
skip_delete_command (char *arg, int from_tty)
{
struct skiplist_entry *e, *temp, *b_prev;
int found = 0;
b_prev = 0;
ALL_SKIPLIST_ENTRIES_SAFE (e, temp)
if (arg == 0 || number_is_in_list (arg, e->number))
{
if (b_prev != 0)
b_prev->next = e->next;
else
skiplist_entry_chain = e->next;
xfree (e->function_name);
xfree (e->filename);
xfree (e);
found = 1;
}
else
{
b_prev = e;
}
if (!found)
error (_("No skiplist entries found with number %s."), arg);
}
/* Create a skiplist entry for the given pc corresponding to the given
function name and add it to the list. */
static void
skip_function_pc (CORE_ADDR pc, char *name, struct gdbarch *arch,
int pending)
{
struct skiplist_entry *e = XZALLOC (struct skiplist_entry);
e->pc = pc;
e->gdbarch = arch;
e->enabled = 1;
e->pending = pending;
e->function_name = xstrdup (name);
add_skiplist_entry (e);
if (!pending)
printf_filtered (_("Function %s at %s will be skipped when stepping.\n"),
name, paddress (get_current_arch (), pc));
else
printf_filtered (_("Function %s will be skipped when stepping, "
"pending shared library load.\n"),
name);
}
/* Add the given skiplist entry to our list, and set the entry's number. */
static void
add_skiplist_entry (struct skiplist_entry *e)
{
struct skiplist_entry *e1;
e->number = ++skiplist_entry_count;
/* Add to the end of the chain so that the list of
skiplist entries will be in numerical order. */
e1 = skiplist_entry_chain;
if (e1 == 0)
skiplist_entry_chain = e;
else
{
while (e1->next)
e1 = e1->next;
e1->next = e;
}
}
/* Does the given pc correspond to the beginning of a skipped function? */
int
function_pc_is_marked_for_skip (CORE_ADDR pc)
{
int searched_for_sal = 0;
struct symtab_and_line sal;
char *filename = NULL;
struct skiplist_entry *e;
ALL_SKIPLIST_ENTRIES (e)
{
if (!e->enabled || e->pending)
continue;
/* Does the pc we're stepping into match e's stored pc? */
if (e->pc != 0 && pc == e->pc)
return 1;
if (e->filename != 0)
{
/* Get the filename corresponding to this pc, if we haven't
* yet. */
if (!searched_for_sal)
{
sal = find_pc_line (pc, 0);
if (sal.symtab != 0)
filename = sal.symtab->filename;
searched_for_sal = 1;
}
if (filename != 0 && strcmp (filename, e->filename) == 0)
return 1;
}
}
return 0;
}
/* Re-set the skip list after symbols have been re-loaded. */
void
skip_re_set (void)
{
struct skiplist_entry *e;
ALL_SKIPLIST_ENTRIES (e)
{
if (e->filename != 0)
{
/* If it's an entry telling us to skip a file, but the entry is
currently pending a solib load, let's see if we now know
about the file. */
struct symtab *symtab = lookup_symtab (e->filename);
if (symtab != 0)
{
xfree (e->filename);
e->filename = xstrdup (symtab->filename);
e->gdbarch = get_objfile_arch (symtab->objfile);
e->pending = 0;
}
else
{
e->pending = 1;
}
}
else if (e->function_name != 0)
{
char *func_name = e->function_name;
struct symtabs_and_lines sals;
volatile struct gdb_exception decode_exception;
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
{
sals = decode_line_1 (&func_name, 1, 0, 0, 0);
}
if (decode_exception.reason >= 0
&& sals.nelts == 1 && strlen (func_name) == 0)
{
struct symtab_and_line sal = sals.sals[0];
CORE_ADDR pc = sal.pc;
CORE_ADDR func_start = 0;
struct gdbarch *arch = get_sal_arch (sal);
char *func_name;
if (find_pc_partial_function (pc, &func_name, &func_start, 0))
{
e->pending = 0;
e->function_name = xstrdup (func_name);
e->pc = func_start;
e->gdbarch = arch;
}
}
else
{
e->pending = 1;
}
}
}
}
void
_initialize_step_skip (void)
{
struct cmd_list_element *c;
skiplist_entry_chain = 0;
skiplist_entry_count = 0;
add_prefix_cmd ("skip", class_breakpoint, skip_function_command, _("\
Ignore a function while stepping.\n\
Usage: skip [FUNCTION NAME]\n\
If no function name is given, ignore the current function."),
&skiplist, "skip ", 1, &cmdlist);
c = add_cmd ("file", class_breakpoint, skip_file_command, _("\
Ignore a file while stepping.\n\
Usage: skip file [FILENAME]\n\
If no filename is given, ignore the current file."),
&skiplist);
set_cmd_completer (c, filename_completer);
c = add_cmd ("function", class_breakpoint, skip_function_command, _("\
Ignore a function while stepping.\n\
Usage: skip function [FUNCTION NAME]\n\
If no function name is given, skip the current function."),
&skiplist);
set_cmd_completer (c, location_completer);
add_cmd ("enable", class_breakpoint, skip_enable_command, _("\
Enable skip entries. You can specify numbers (e.g. \"skip enable 1 3\"), \
ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
Usage: skip enable [NUMBERS AND/OR RANGES]"),
&skiplist);
add_cmd ("disable", class_breakpoint, skip_disable_command, _("\
Disable skip entries. You can specify numbers (e.g. \"skip disable 1 3\"), \
ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
Usage: skip disable [NUMBERS AND/OR RANGES]"),
&skiplist);
add_cmd ("delete", class_breakpoint, skip_delete_command, _("\
Delete skip entries. You can specify numbers (e.g. \"skip delete 1 3\"), \
ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
Usage: skip delete [NUMBERS AND/OR RANGES]"),
&skiplist);
add_info ("skip", skip_info, _("\
Display the status of skips. You can specify numbers (e.g. \"skip info 1 3\"), \
ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
If you don't specify any numbers or ranges, we'll show all skips.\n\n\
Usage: skip info [NUMBERS AND/OR RANGES]\n\
The \"Type\" column indicates one of:\n\
\tfile - ignored file\n\
\tfunction - ignored function"));
}

28
gdb/skip.h Normal file
View File

@ -0,0 +1,28 @@
/* Header for skipping over uninteresting files and functions when debugging.
Copyright (C) 2011 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#if !defined (SKIP_H)
#define SKIP_H
/* Returns 1 if the given pc is marked for skip and shouldn't be
stepped into. Otherwise, returns 0. */
int function_pc_is_marked_for_skip (CORE_ADDR pc);
/* Re-set the skip list after symbols have been reloaded. */
void skip_re_set (void);
#endif /* !defined (SKIP_H) */

View File

@ -96,6 +96,12 @@ static void print_frame (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args,
struct symtab_and_line sal);
static void set_last_displayed_sal (int valid,
struct program_space *pspace,
CORE_ADDR addr,
struct symtab *symtab,
int line);
/* Zero means do things normally; we are interacting directly with the
user. One means print the full filename and linenumber when a
frame is printed, and do so in a format emacs18/emacs19.22 can
@ -103,6 +109,14 @@ static void print_frame (struct frame_info *frame, int print_level,
cases and in a slightly different syntax. */
int annotation_level = 0;
/* These variables hold the last symtab and line we displayed to the user.
* This is where we insert a breakpoint or a skiplist entry by default. */
static int last_displayed_sal_valid = 0;
static struct program_space *last_displayed_pspace = 0;
static CORE_ADDR last_displayed_addr = 0;
static struct symtab *last_displayed_symtab = 0;
static int last_displayed_line = 0;
/* Return 1 if we should display the address in addition to the location,
@ -872,9 +886,9 @@ print_frame_info (struct frame_info *frame, int print_level,
CORE_ADDR pc;
if (get_frame_pc_if_available (frame, &pc))
set_default_breakpoint (1, sal.pspace, pc, sal.symtab, sal.line);
set_last_displayed_sal (1, sal.pspace, pc, sal.symtab, sal.line);
else
set_default_breakpoint (0, 0, 0, 0, 0);
set_last_displayed_sal (0, 0, 0, 0, 0);
}
annotate_frame_end ();
@ -882,6 +896,106 @@ print_frame_info (struct frame_info *frame, int print_level,
gdb_flush (gdb_stdout);
}
/* Remember the last symtab and line we displayed, which we use e.g.
* as the place to put a breakpoint when the `break' command is
* invoked with no arguments. */
static void
set_last_displayed_sal (int valid, struct program_space *pspace,
CORE_ADDR addr, struct symtab *symtab,
int line)
{
last_displayed_sal_valid = valid;
last_displayed_pspace = pspace;
last_displayed_addr = addr;
last_displayed_symtab = symtab;
last_displayed_line = line;
}
/* Forget the last sal we displayed. */
void
clear_last_displayed_sal (void)
{
last_displayed_sal_valid = 0;
last_displayed_pspace = 0;
last_displayed_addr = 0;
last_displayed_symtab = 0;
last_displayed_line = 0;
}
/* Is our record of the last sal we displayed valid? If not,
* the get_last_displayed_* functions will return NULL or 0, as
* appropriate. */
int
last_displayed_sal_is_valid (void)
{
return last_displayed_sal_valid;
}
/* Get the pspace of the last sal we displayed, if it's valid. */
struct program_space *
get_last_displayed_pspace (void)
{
if (last_displayed_sal_valid)
return last_displayed_pspace;
return 0;
}
/* Get the address of the last sal we displayed, if it's valid. */
CORE_ADDR
get_last_displayed_addr (void)
{
if (last_displayed_sal_valid)
return last_displayed_addr;
return 0;
}
/* Get the symtab of the last sal we displayed, if it's valid. */
struct symtab*
get_last_displayed_symtab (void)
{
if (last_displayed_sal_valid)
return last_displayed_symtab;
return 0;
}
/* Get the line of the last sal we displayed, if it's valid. */
int
get_last_displayed_line (void)
{
if (last_displayed_sal_valid)
return last_displayed_line;
return 0;
}
/* Get the last sal we displayed, if it's valid. */
void
get_last_displayed_sal (struct symtab_and_line *sal)
{
if (last_displayed_sal_valid)
{
sal->pspace = last_displayed_pspace;
sal->pc = last_displayed_addr;
sal->symtab = last_displayed_symtab;
sal->line = last_displayed_line;
}
else
{
sal->pspace = 0;
sal->pc = 0;
sal->symtab = 0;
sal->line = 0;
}
}
/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
corresponding to FRAME. */

View File

@ -38,4 +38,14 @@ void iterate_over_block_local_vars (struct block *block,
iterate_over_block_arg_local_vars_cb cb,
void *cb_data);
/* Get or set the last displayed symtab and line, which is, e.g. where we set a
* breakpoint when `break' is supplied with no arguments. */
void clear_last_displayed_sal (void);
int last_displayed_sal_is_valid (void);
struct program_space* get_last_displayed_pspace (void);
CORE_ADDR get_last_displayed_addr (void);
struct symtab* get_last_displayed_symtab (void);
int get_last_displayed_line (void);
void get_last_displayed_sal (struct symtab_and_line *sal);
#endif /* #ifndef STACK_H */

View File

@ -56,6 +56,7 @@
#include "elf-bfd.h"
#include "solib.h"
#include "remote.h"
#include "stack.h"
#include <sys/types.h>
#include <fcntl.h>
@ -2839,7 +2840,7 @@ clear_symtab_users (int add_flags)
clear_displays ();
if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
breakpoint_re_set ();
set_default_breakpoint (0, NULL, 0, 0, 0);
clear_last_displayed_sal ();
clear_pc_function_cache ();
observer_notify_new_objfile (NULL);

View File

@ -1,3 +1,14 @@
2011-10-06 Justin Lebar <justin.lebar@gmail.com>
Add tests for skip command.
* testsuite/gdb.base/skip-solib-lib.c: New
* testsuite/gdb.base/skip-solib-main.c: New
* testsuite/gdb.base/skip-solib.exp: New
* testsuite/gdb.base/skip.c: New
* testsuite/gdb.base/skip.exp: New
* testsuite/gdb.base/skip1.c: New
* testsuite/gdb.base/Makefile.in: Adding new files.
2011-10-31 Yao Qi <yao@codesourcery.com>
Pedro Alves <pedro@codesourcery.com>

View File

@ -30,8 +30,8 @@ EXECUTABLES = a2-run advance all-types annota1 annota1-watch_thread_num \
sepsymtab.debug sepsymtab.stripped setshow setvar shmain shreloc \
sigall sigaltstack sigbpt sigchld siginfo siginfo-addr \
siginfo-infcall siginfo-obj signals signull sigrepeat sigstep \
sizeof solib solib-corrupted solib-display-main solib-nodir \
solib-overlap-main-0x40000000 solib-symbol-main solib-weak \
sizeof skip skip-solib solib solib-corrupted solib-display-main
solib-nodir solib-overlap-main-0x40000000 solib-symbol-main solib-weak \
solib-weak-lib2 solib_sl so-impl-ld so-indr-cl \
stack-checking start step-break step-bt step-line step-resume-infcall \
step-test store structs-t* structs2 structs3 \

View File

@ -0,0 +1,11 @@
/* Simple shared library */
int square(int num)
{
return multiply(num, num);
}
int multiply(int a, int b)
{
return a * b;
}

View File

@ -0,0 +1,6 @@
int square(int num);
int main()
{
return square(0);
}

View File

@ -0,0 +1,130 @@
# Copyright 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file was written by Justin Lebar. (justin.lebar@gmail.com)
#
# Tests skipping shared libraries.
#
# This only works on GNU/Linux.
if { ![isnative] || [is_remote host] || ![istarget *-linux*] || [skip_shlib_tests]} {
continue
}
set test "skip-solib"
set srcfile_main "${test}-main.c"
set binfile_main "${test}-test"
set srcfile_lib "${test}-lib.c"
set libname "lib${test}"
set binfile_lib ${objdir}/${subdir}/${libname}.so
#
# Compile our program under test. The main program references a shared library
# libskip-solib.so, which contains two functions, square(), which is
# referenced by the main program, and multiply(), which is not referenced by
# the main program.
#
if {[gdb_compile_shlib ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} [list debug additional_flags=-fPIC -Wl,-soname,${libname}.so]] != ""} {
return -1
}
if {[gdb_compile "${srcdir}/${subdir}/${srcfile_main}" "${binfile_main}.o" object debug] != ""} {
return -1
}
if {[gdb_compile "${binfile_main}.o" "${binfile_main}" executable \
[list debug "additional_flags=-L${objdir}/${subdir} -l${test} \
-Wl,-rpath=${objdir}/${subdir}"]] != ""} {
return -1
}
gdb_start
clean_restart ${binfile_main}
#
# At this point, if we try to skip the file ${srcfile_lib} or the function
# multiply(), we should get a prompt asking us if we want to enable the
# skip entry pending a shared library load.
#
gdb_test "skip file ${srcfile_lib}" \
"File ${srcfile_lib} will be skipped when stepping." \
"ignoring file in solib" \
"No source file named ${srcfile_lib}.*
Ignore file pending future shared library load.*" \
"y"
#
# Does info skip list this entry as pending?
#
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
1\\s+file\\s+y\\s+\\s+${srcfile_lib} \\(PENDING\\)\\s*" \
"info skip with pending file"
if ![runto_main] { fail "skip tests suppressed" }
#
# We shouldn't step into square(), since we skipped skip-solib-lib.c.
#
gdb_test "step" ""
gdb_test "bt" "#0\\s+main.*" "step after ignoring solib file."
#
# Our entry should no longer be pending. Note that we unfortunately need to do
# at least one step before the entry will be unmarked as pending.
#
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
1\\s+file\\s+y\\s+\\s+.*${srcfile_lib}\\s*" \
"info skip with pending file"
#
# Now restart gdb and testing ignoring of a function inside a solib.
#
gdb_exit
gdb_start
clean_restart ${binfile_main}
gdb_test "skip function multiply" \
"Function multiply will be skipped when stepping, pending shared library load." \
"ignoring function in solib" \
"No function found named multiply..*
Ignore function pending future shared library load.*" \
"y"
if ![runto_main] { fail "skip tests suppressed" }
#
# Our first step should take us into square.
#
gdb_test "step" "square.*"
#
# Now our entry should no longer be pending.
#
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
1\\s+function\\s+y\\s+0x\[0-9a-f\]+\\s+multiply at .*${srcfile_lib}:.*\\s*" \
"skip should no longer be pending."
#
# This step shouldn't go into multiply -- we should skip it and go on to the
# last line of square.
#
gdb_test "step" ""
gdb_test "bt" "#0\\s+square.*"

View File

@ -0,0 +1,13 @@
int foo();
int bar();
int baz(int, int);
int main()
{
return baz(foo(), bar());
}
int foo()
{
return 0;
}

View File

@ -0,0 +1,179 @@
# Copyright 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file was written by Justin Lebar. (justin.lebar@gmail.com)
if { [prepare_for_testing skip.exp "skip" \
{skip.c skip1.c } \
{debug nowarnings}] } {
return -1
}
set srcfile skip.c
set srcfile1 skip1.c
#
# Right after we start gdb, there's no default file or function to skip.
#
gdb_test "skip file" "No default file now."
gdb_test "skip function" "No default function now."
gdb_test "skip" "No default function now."
if ![runto_main] { fail "skip tests suppressed" }
#
# Test |info skip| with an empty skiplist.
#
gdb_test "info skip" "Not skipping any files or functions\." "info skip empty"
#
# Create a skiplist entry for the current file and function.
#
gdb_test "skip file" "File .*$srcfile will be skipped when stepping\."
gdb_test "skip" "Function main at .* will be skipped when stepping\."
#
# Create a skiplist entry for a specified file and function.
#
gdb_test "skip file skip1.c" "File .*$srcfile1 will be skipped when stepping\."
gdb_test "skip function baz" "Function baz at .* will be skipped when stepping\."
#
# Test bad skiplist entry modification commands
#
gdb_test "skip enable 999" "No skiplist entries found with number 999."
gdb_test "skip disable 999" "No skiplist entries found with number 999."
gdb_test "skip delete 999" "No skiplist entries found with number 999."
gdb_test "skip enable a" "Args must be numbers or '\\$' variables."
gdb_test "skip disable a" "Args must be numbers or '\\$' variables."
gdb_test "skip delete a" "Args must be numbers or '\\$' variables."
#
# Ask for info on a skiplist entry which doesn't exist.
#
gdb_test "info skip 999" "No skiplist entries found with number 999."
#
# Does |info skip| look right?
#
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
1\\s+file\\s+y\\s+.*$srcfile\\s*
2\\s+function\\s+y\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+y\\s+.*$srcfile1\\s*
4\\s+function\\s+y\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*"
#
# Right now, we have an outstanding skiplist entry on both source
# files, so when we step into the first line in main(), we should step
# right over it and go to the second line of main().
#
if ![runto_main] { fail "skip tests suppressed" }
gdb_test "step"
gdb_test "bt" "\\s*\\#0\\s+main.*" "step after all ignored"
#
# Now remove skip.c from the skiplist. Our first step should take us
# into foo(), and our second step should take us to the next line in
# main().
#
gdb_test "skip delete 1"
# Check that entry 1 is missing from |info skip|
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+y\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+y\\s+.*$srcfile1\\s*
4\\s+function\\s+y\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*"
if ![runto_main] { fail "skip tests suppressed" }
gdb_test "step" "foo \\(\\) at.*" "step after deleting 1 (1)"
gdb_test "step"; # Return from foo()
gdb_test "step" "main \\(\\) at.*" "step after deleting 1 (2)"
#
# Now disable the skiplist entry for skip1.c. We should now
# step into foo(), then into bar(), but not into baz().
#
gdb_test "skip disable 3"
# Is entry 3 disabled in |info skip|?
gdb_test "info skip 3" ".*\\n3\\s+file\\s+n.*" \
"info skip shows entry as disabled"
if ![runto_main] { fail "skip tests suppressed" }
gdb_test "step" "bar \\(\\) at.*" "step after disabling 3 (1)"
gdb_test "step"; # Return from foo()
gdb_test "step" "foo \\(\\) at.*" "step after disabling 3 (2)"
gdb_test "step"; # Return from bar()
gdb_test "step" "main \\(\\) at.*" "step after disabling 3 (3)"
#
# Enable skiplist entry 3 and make sure we step over it like before.
#
gdb_test "skip enable 3"
# Is entry 3 enabled in |info skip|?
gdb_test "info skip 3" ".*\\n3\\s+file\\s+y.*" \
"info skip shows entry as enabled"
if ![runto_main] { fail "skip tests suppressed" }
gdb_test "step" "foo \\(\\) at.*" "step after deleting 1 (1)"
gdb_test "step"; # Return from foo()
gdb_test "step" "main \\(\\) at.*" "step after deleting 1 (2)"
gdb_test "skip disable"
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+n\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+n\\s+.*$srcfile1\\s*
4\\s+function\\s+n\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*" \
"info skip after disabling all"
gdb_test "skip enable"
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+y\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+y\\s+.*$srcfile1\\s*
4\\s+function\\s+y\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*" \
"info skip after enabling all"
gdb_test "skip disable 4 2-3"
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+n\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+n\\s+.*$srcfile1\\s*
4\\s+function\\s+n\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*" \
"info skip after disabling 4 2-3"
gdb_test "skip enable 2-3"
gdb_test "info skip" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+y\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+y\\s+.*$srcfile1\\s*
4\\s+function\\s+n\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*" \
"info skip after enabling 2-3"
gdb_test "info skip 2-3" \
"Num\\s+Type\\s+Enb\\s+Address\\s+What\\s*
2\\s+function\\s+y\\s+0x\[0-9a-f\]+ main at .*$srcfile:\[0-9\]+\\s*
3\\s+file\\s+y\\s+.*$srcfile1\\s*" \
"info skip 2-3"
gdb_test "skip delete 2 3"
gdb_test "info skip" \
"4\\s+function\\s+n\\s+0x\[0-9a-f\]+ baz at .*$srcfile1:\[0-9\]+\\s*" \
"info skip after deleting 2 3"
gdb_test "skip delete"
gdb_test "info skip" "Not skipping any files or functions\." \
"info skip after deleting all"

View File

@ -0,0 +1,9 @@
int bar()
{
return 1;
}
int baz(int a, int b)
{
return a + b;
}