* breakpoint.c (do_restore_lang_radix_cleanup): Remove.

(resolve_pending_breakpoint): Remove.
	(re_enable_breakpoints_in_shlibs): Remove.
	(unlink_locations_from_global_list): New.
	(update_breakpoint_locations): New.
	(breakpoint_re_set_one): Don't bail out on pending breakpoints.
	Use parse_condition and update_breakpoint_location to
	reset breakpoint.  Ignore 'symbol not found' error from
	decode_line_1.
	(breakpoint_re_set): Don't emit newline before the
	reason why breakpoint is not reset.
	(do_enable_breakpoint): Don't specially process pending
	breakpoints.
	(free_bp_location): New.
	(break_command_1): For pending breakpoints, initialize
	all fields of a sal with zeroes.
	* breakpoint.h (re_enable_breakpoints_in_shlibs): Remove.
	* infcmd.c (post_create_inferior): Don't call
	re_enable_breakpoints_in_shlibs.
	* infrun.c (handle_inferior_event): Likewise.
	* solib-irix.c (irix_solib_create_inferior_hook): Likewise.
	* solib-osf.c (osf_solib_create_inferior_hook): Likewise.
	* win32-nat.c (get_win32_debug_event): Likewise.
This commit is contained in:
Vladimir Prus 2007-09-22 19:33:32 +00:00
parent 018d34a46b
commit fe3f5fa8f9
11 changed files with 242 additions and 284 deletions

View file

@ -1,3 +1,29 @@
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
* breakpoint.c (do_restore_lang_radix_cleanup): Remove.
(resolve_pending_breakpoint): Remove.
(re_enable_breakpoints_in_shlibs): Remove.
(unlink_locations_from_global_list): New.
(update_breakpoint_locations): New.
(breakpoint_re_set_one): Don't bail out on pending breakpoints.
Use parse_condition and update_breakpoint_location to
reset breakpoint. Ignore 'symbol not found' error from
decode_line_1.
(breakpoint_re_set): Don't emit newline before the
reason why breakpoint is not reset.
(do_enable_breakpoint): Don't specially process pending
breakpoints.
(free_bp_location): New.
(break_command_1): For pending breakpoints, initialize
all fields of a sal with zeroes.
* breakpoint.h (re_enable_breakpoints_in_shlibs): Remove.
* infcmd.c (post_create_inferior): Don't call
re_enable_breakpoints_in_shlibs.
* infrun.c (handle_inferior_event): Likewise.
* solib-irix.c (irix_solib_create_inferior_hook): Likewise.
* solib-osf.c (osf_solib_create_inferior_hook): Likewise.
* win32-nat.c (get_win32_debug_event): Likewise.
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
* breakpoint.c (create_breakpoint): Split from

View file

@ -203,6 +203,8 @@ static void ep_skip_leading_whitespace (char **s);
static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
static void free_bp_location (struct bp_location *loc);
/* Prototypes for exported functions. */
/* If FALSE, gdb will not use hardware support for watchpoints, even
@ -4140,6 +4142,13 @@ allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
return loc;
}
static void free_bp_location (struct bp_location *loc)
{
if (loc->cond)
xfree (loc->cond);
xfree (loc);
}
/* set_raw_breakpoint() is a low level routine for allocating and
partially initializing a breakpoint of type BPTYPE. The newly
created breakpoint's address, section, source file name, and line
@ -4396,51 +4405,6 @@ struct lang_and_radix
int radix;
};
/* Cleanup helper routine to restore the current language and
input radix. */
static void
do_restore_lang_radix_cleanup (void *old)
{
struct lang_and_radix *p = old;
set_language (p->lang);
input_radix = p->radix;
}
/* Try and resolve a pending breakpoint. */
static int
resolve_pending_breakpoint (struct breakpoint *b)
{
/* Try and reparse the breakpoint in case the shared library
is now loaded. */
struct symtabs_and_lines sals;
struct symtab_and_line pending_sal;
char **cond_string = (char **) NULL;
char *copy_arg = b->addr_string;
char **addr_string;
char *errmsg;
int rc;
int not_found = 0;
struct ui_file *old_gdb_stderr;
struct lang_and_radix old_lr;
struct cleanup *old_chain;
/* Set language, input-radix, then reissue breakpoint command.
Ensure the language and input-radix are restored afterwards. */
old_lr.lang = current_language->la_language;
old_lr.radix = input_radix;
old_chain = make_cleanup (do_restore_lang_radix_cleanup, &old_lr);
set_language (b->language);
input_radix = b->input_radix;
rc = break_command_1 (b->addr_string, b->flag, b->from_tty, b);
if (rc == GDB_RC_OK)
/* Pending breakpoint has been resolved. */
printf_filtered (_("Pending breakpoint \"%s\" resolved\n"), b->addr_string);
do_cleanups (old_chain);
return rc;
}
void
remove_solib_event_breakpoints (void)
@ -4523,37 +4487,6 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
}
}
/* Try to reenable any breakpoints in shared libraries. */
void
re_enable_breakpoints_in_shlibs (void)
{
struct breakpoint *b, *tmp;
ALL_BREAKPOINTS_SAFE (b, tmp)
{
if (b->enable_state == bp_shlib_disabled)
{
gdb_byte buf[1];
char *lib;
/* Do not reenable the breakpoint if the shared library is
still not mapped in. */
#ifdef PC_SOLIB
lib = PC_SOLIB (b->loc->address);
#else
lib = solib_address (b->loc->address);
#endif
if (lib != NULL && target_read_memory (b->loc->address, buf, 1) == 0)
b->enable_state = bp_enabled;
}
else if (b->pending && (b->enable_state == bp_enabled))
{
if (resolve_pending_breakpoint (b) == GDB_RC_OK)
delete_breakpoint (b);
}
}
}
static void
solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
char *cond_string, enum bptype bp_kind)
@ -5422,12 +5355,9 @@ break_command_1 (char *arg, int flag, int from_tty, struct breakpoint *pending_b
}
else
{
struct symtab_and_line sal;
struct symtab_and_line sal = {0};
struct breakpoint *b;
sal.symtab = NULL;
sal.pc = 0;
make_cleanup (xfree, copy_arg);
b = set_raw_breakpoint (sal, hardwareflag ? bp_hardware_breakpoint
@ -7153,6 +7083,97 @@ delete_command (char *arg, int from_tty)
map_breakpoint_numbers (arg, delete_breakpoint);
}
static void
unlink_locations_from_global_list (struct breakpoint *bpt)
/* Remove locations of this breakpoint from the list of
all breakpoint locations. */
{
struct bp_location **tmp = &bp_location_chain;
struct bp_location *here = bpt->loc;
if (here == NULL)
return;
for (; *tmp && *tmp != here; tmp = &((*tmp)->next));
gdb_assert (*tmp);
*tmp = here->next;
}
static void
update_breakpoint_location (struct breakpoint *b,
struct symtabs_and_lines sals)
{
int i;
char *s;
/* FIXME: memleak. */
struct bp_location *existing = b->loc;
struct bp_location *loc;
struct symtab_and_line sal;
if (b->enable_state == bp_shlib_disabled && sals.nelts == 0)
return;
unlink_locations_from_global_list (b);
b->loc = NULL;
gdb_assert (sals.nelts == 0 || sals.nelts == 1);
if (sals.nelts == 0)
return;
sal = sals.sals[0];
loc = allocate_bp_location (b, b->type);
loc->requested_address = sal.pc;
loc->address = adjust_breakpoint_address (loc->requested_address,
b->type);
loc->section = sal.section;
b->loc = loc;
/* Reparse conditions, they might contain references to the
old symtab. */
if (b->cond_string != NULL)
{
struct gdb_exception e;
s = b->cond_string;
TRY_CATCH (e, RETURN_MASK_ERROR)
{
loc->cond = parse_exp_1 (&s, block_for_pc (sal.pc),
0);
}
if (e.reason < 0)
{
warning (_("failed to reevaluate condition for breakpoint %d: %s"),
b->number, e.message);
b->enable_state = bp_disabled;
}
}
if (b->source_file != NULL)
xfree (b->source_file);
if (sal.symtab == NULL)
b->source_file = NULL;
else
b->source_file =
savestring (sal.symtab->filename,
strlen (sal.symtab->filename));
if (b->line_number == 0)
b->line_number = sal.line;
if (b->enable_state == bp_shlib_disabled)
b->enable_state = bp_enabled;
b->pending = 0;
check_duplicates (b);
if (existing)
free_bp_location (existing);
}
/* Reset a breakpoint given it's struct breakpoint * BINT.
The value we return ends up being the return value from catch_errors.
Unused in this case. */
@ -7164,11 +7185,13 @@ breakpoint_re_set_one (void *bint)
struct breakpoint *b = (struct breakpoint *) bint;
struct value *mark;
int i;
int not_found;
int *not_found_ptr = NULL;
struct symtabs_and_lines sals;
int not_found = 0;
int *not_found_ptr = &not_found;
struct symtabs_and_lines sals = {};
char *s;
enum enable_state save_enable;
struct gdb_exception e;
switch (b->type)
{
@ -7186,115 +7209,59 @@ breakpoint_re_set_one (void *bint)
delete_breakpoint (b);
return 0;
}
/* HACK: cagney/2001-11-11: kettenis/2001-11-11: MarkK wrote:
``And a hack it is, although Apple's Darwin version of GDB
contains an almost identical hack to implement a "future
break" command. It seems to work in many real world cases,
but it is easy to come up with a test case where the patch
doesn't help at all.''
``It seems that the way GDB implements breakpoints - in -
shared - libraries was designed for a.out shared library
systems (SunOS 4) where shared libraries were loaded at a
fixed address in memory. Since ELF shared libraries can (and
will) be loaded at any address in memory, things break.
Fixing this is not trivial. Therefore, I'm not sure whether
we should add this hack to the branch only. I cannot
guarantee that things will be fixed on the trunk in the near
future.''
In case we have a problem, disable this breakpoint. We'll
restore its status if we succeed. Don't disable a
shlib_disabled breakpoint though. There's a fair chance we
can't re-set it if the shared library it's in hasn't been
loaded yet. */
if (b->pending)
break;
save_enable = b->enable_state;
if (b->enable_state != bp_shlib_disabled)
b->enable_state = bp_disabled;
else
/* If resetting a shlib-disabled breakpoint, we don't want to
see an error message if it is not found since we will expect
this to occur until the shared library is finally reloaded.
We accomplish this by giving decode_line_1 a pointer to use
for silent notification that the symbol is not found. */
not_found_ptr = &not_found;
set_language (b->language);
input_radix = b->input_radix;
s = b->addr_string;
TRY_CATCH (e, RETURN_MASK_ERROR)
{
sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) NULL,
not_found_ptr);
for (i = 0; i < sals.nelts; i++)
{
resolve_sal_pc (&sals.sals[i]);
/* Reparse conditions, they might contain references to the
old symtab. */
if (b->cond_string != NULL)
{
s = b->cond_string;
if (b->loc->cond)
{
xfree (b->loc->cond);
/* Avoid re-freeing b->exp if an error during the call
to parse_exp_1. */
b->loc->cond = NULL;
}
b->loc->cond = parse_exp_1 (&s, block_for_pc (sals.sals[i].pc), 0);
if (e.reason < 0)
{
int not_found_and_ok = 0;
/* For pending breakpoints, it's expected that parsing
will fail until the right shared library is loaded.
User has already told to create pending breakpoints and
don't need extra messages. If breakpoint is in bp_shlib_disabled
state, then user already saw the message about that breakpoint
being disabled, and don't want to see more errors. */
if (not_found && (b->pending || b->enable_state == bp_shlib_disabled
|| b->enable_state == bp_disabled))
not_found_and_ok = 1;
if (!not_found_and_ok)
{
/* We surely don't want to warn about the same breakpoint
10 times. One solution, implemented here, is disable
the breakpoint on error. Another solution would be to
have separate 'warning emitted' flag. Since this
happens only when a binary has changed, I don't know
which approach is better. */
b->enable_state = bp_disabled;
throw_exception (e);
}
}
/* We need to re-set the breakpoint if the address changes... */
if (b->loc->address != sals.sals[i].pc
/* ...or new and old breakpoints both have source files, and
the source file name or the line number changes... */
|| (b->source_file != NULL
&& sals.sals[i].symtab != NULL
&& (strcmp (b->source_file, sals.sals[i].symtab->filename) != 0
|| b->line_number != sals.sals[i].line)
)
/* ...or we switch between having a source file and not having
one. */
|| ((b->source_file == NULL) != (sals.sals[i].symtab == NULL))
)
if (not_found)
break;
gdb_assert (sals.nelts == 1);
resolve_sal_pc (&sals.sals[0]);
if (b->pending && s && s[0])
{
if (b->source_file != NULL)
xfree (b->source_file);
if (sals.sals[i].symtab == NULL)
b->source_file = NULL;
else
b->source_file =
savestring (sals.sals[i].symtab->filename,
strlen (sals.sals[i].symtab->filename));
b->line_number = sals.sals[i].line;
b->loc->requested_address = sals.sals[i].pc;
b->loc->address
= adjust_breakpoint_address (b->loc->requested_address,
b->type);
/* Used to check for duplicates here, but that can
cause trouble, as it doesn't check for disabled
breakpoints. */
mention (b);
/* Might be better to do this just once per breakpoint_re_set,
rather than once for every breakpoint. */
breakpoints_changed ();
char *cond_string = 0;
int thread = -1;
find_condition_and_thread (s, sals.sals[0].pc,
&cond_string, &thread);
if (cond_string)
b->cond_string = cond_string;
b->thread = thread;
}
b->loc->section = sals.sals[i].section;
b->enable_state = save_enable; /* Restore it, this worked. */
update_breakpoint_location (b, sals);
/* Now that this is re-enabled, check_duplicates
can be used. */
check_duplicates (b);
}
xfree (sals.sals);
break;
@ -7408,7 +7375,7 @@ breakpoint_re_set (void)
ALL_BREAKPOINTS_SAFE (b, temp)
{
/* Format possible error msg */
char *message = xstrprintf ("Error in re-setting breakpoint %d:\n",
char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
b->number);
struct cleanup *cleanups = make_cleanup (xfree, message);
catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
@ -7635,25 +7602,6 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
error (_("Hardware breakpoints used exceeds limit."));
}
if (bpt->pending)
{
if (bpt->enable_state != bp_enabled)
{
/* When enabling a pending breakpoint, we need to check if the breakpoint
is resolvable since shared libraries could have been loaded
after the breakpoint was disabled. */
breakpoints_changed ();
if (resolve_pending_breakpoint (bpt) == GDB_RC_OK)
{
delete_breakpoint (bpt);
return;
}
bpt->enable_state = bp_enabled;
bpt->disposition = disposition;
}
}
else /* Not a pending breakpoint. */
{
if (bpt->enable_state != bp_permanent)
bpt->enable_state = bp_enabled;
bpt->disposition = disposition;
@ -7717,13 +7665,13 @@ have been allocated for other watchpoints.\n"), bpt->number);
select_frame (frame_find_by_id (saved_frame_id));
value_free_to_mark (mark);
}
}
if (deprecated_modify_breakpoint_hook)
deprecated_modify_breakpoint_hook (bpt);
breakpoint_modify_event (bpt->number);
}
void
enable_breakpoint (struct breakpoint *bpt)
{

View file

@ -799,8 +799,6 @@ extern void remove_thread_event_breakpoints (void);
extern void disable_breakpoints_in_shlibs (void);
extern void re_enable_breakpoints_in_shlibs (void);
extern void create_solib_load_event_breakpoint (char *, int, char *, char *);
extern void create_solib_unload_event_breakpoint (char *, int,

View file

@ -433,10 +433,6 @@ post_create_inferior (struct target_ops *target, int from_tty)
#else
solib_create_inferior_hook ();
#endif
/* Enable any breakpoints which were disabled when the
underlying shared library was deleted. */
re_enable_breakpoints_in_shlibs ();
}
observer_notify_inferior_created (target, from_tty);

View file

@ -1337,10 +1337,6 @@ handle_inferior_event (struct execution_control_state *ecs)
#endif
target_terminal_inferior ();
/* Try to reenable shared library breakpoints, additional
code segments in shared libraries might be mapped in now. */
re_enable_breakpoints_in_shlibs ();
/* If requested, stop when the dynamic linker notifies
gdb of events. This allows the user to get control
and place breakpoints in initializer routines for
@ -2276,10 +2272,6 @@ process_event_stop_test:
#endif
target_terminal_inferior ();
/* Try to reenable shared library breakpoints, additional
code segments in shared libraries might be mapped in now. */
re_enable_breakpoints_in_shlibs ();
/* If requested, stop when the dynamic linker notifies
gdb of events. This allows the user to get control
and place breakpoints in initializer routines for

View file

@ -457,7 +457,6 @@ irix_solib_create_inferior_hook (void)
suppresses the warning. */
solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
stop_soon = NO_STOP_QUIETLY;
re_enable_breakpoints_in_shlibs ();
}
/* LOCAL FUNCTION

View file

@ -336,9 +336,6 @@ osf_solib_create_inferior_hook (void)
suppresses the warning. */
solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
stop_soon = NO_STOP_QUIETLY;
/* Enable breakpoints disabled (unnecessarily) by clear_solib(). */
re_enable_breakpoints_in_shlibs ();
}
/* target_so_ops callback. Do additional symbol handling, lookup, etc. after

View file

@ -1,3 +1,10 @@
2007-09-22 Vladimir Prus <vladimir@codesourcery.com>
* gdb.base/pending.exp: No longer expect "Pending breakpoint resolved"
messages.
* gdb.base/chng-syms.exp: Likewise.
* gdb.base/unload.exp: Likewise.
2007-09-21 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.base/sepdebug.exp (test_different_dir): Append to pf_prefix.

View file

@ -105,10 +105,10 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
gdb_run_cmd
gdb_expect {
-re "Error in re-setting .*No symbol .var1..*Program exited normally.*$gdb_prompt $" {
-re ".*No symbol .var1..*Program exited normally.*$gdb_prompt $" {
pass "running with invalidated bpt condition after executable changes"
}
-re "Error in re-setting .*No symbol .var1..*Breakpoint .*,( 0x.* in)? (\[^ \]*)exit .*$gdb_prompt $" {
-re "No symbol .var1..*Breakpoint .*,( 0x.* in)? (\[^ \]*)exit .*$gdb_prompt $" {
pass "running with invalidated bpt condition after executable changes"
}
-re "$gdb_prompt $" {

View file

@ -194,9 +194,7 @@ gdb_test "info break" \
gdb_run_cmd
gdb_test "" \
"Breakpoint.*at.*
Pending breakpoint \"pendshr.c:$bp2_loc if x > 3\" resolved.*
Breakpoint.*, main.*$mainline.*" \
".*Breakpoint.*, main.*$mainline.*" \
"running to main"
#
@ -204,8 +202,7 @@ Breakpoint.*, main.*$mainline.*" \
#
gdb_test "enable 1" \
"Breakpoint.*at.*
Pending breakpoint \"pendfunc1.* resolved.*" \
"" \
"re-enabling pending breakpoint that can resolve instantly"
#

View file

@ -89,9 +89,7 @@ set unloadshr_line [gdb_get_line_number "unloadshr break" ${libsrcfile}]
gdb_run_cmd
gdb_test "" \
"Breakpoint.*at.*
Pending breakpoint \"shrfunc1\" resolved.*
Breakpoint.*, shrfunc1 \\\(x=3\\\).*unloadshr.c:$unloadshr_line.*" \
".*Breakpoint.*, shrfunc1 \\\(x=3\\\).*unloadshr.c:$unloadshr_line.*" \
"running program"
gdb_test "continue" \