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 2 of the License, or
+ 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,
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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include <ctype.h>
#include "exceptions.h"
#include "memattr.h"
#include "ada-lang.h"
+#include "top.h"
#include "gdb-events.h"
#include "mi/mi-common.h"
static void ep_skip_leading_whitespace (char **s);
+static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
+
/* Prototypes for exported functions. */
/* If FALSE, gdb will not use hardware support for watchpoints, even
/* Pointer to current exception event record */
static struct exception_event_record *current_exception_event;
-/* Indicator of whether exception catchpoints should be nuked between
- runs of a program. */
-int deprecated_exception_catchpoints_are_fragile = 0;
-
-/* Indicator of when exception catchpoints set-up should be
- reinitialized -- e.g. when program is re-run. */
-int deprecated_exception_support_initialized = 0;
-
/* This function returns a pointer to the string representation of the
pathname of the dynamically-linked library that has just been
loaded.
CORE_ADDR bp_addr = 0;
int bp_size = 0;
- if (BREAKPOINT_FROM_PC (&bp_addr, &bp_size) == NULL)
+ if (gdbarch_breakpoint_from_pc (current_gdbarch, &bp_addr, &bp_size) == NULL)
/* No breakpoints on this machine. */
return target_read_memory (memaddr, myaddr, len);
if (val)
{
/* Can't set the breakpoint. */
- if (
-#if defined (DISABLE_UNSETTABLE_BREAK)
- DISABLE_UNSETTABLE_BREAK (bpt->address)
-#else
- solib_address (bpt->address)
-#endif
- )
+ if (solib_address (bpt->address))
{
/* See also: disable_breakpoints_in_shlibs. */
val = 0;
struct bp_location *b;
int val;
struct cleanup *old_chain = save_inferior_ptid ();
+ struct ui_file *tmp_error_stream = mem_fileopen ();
+ int dummy1 = 0, dummy2 = 0, dummy3 = 0;
+
+ make_cleanup_ui_file_delete (tmp_error_stream);
- /* Set inferior_ptid; remove_breakpoint uses this global. */
inferior_ptid = pid_to_ptid (pid);
ALL_BP_LOCATIONS (b)
{
if (b->inserted)
{
- remove_breakpoint (b, mark_inserted);
- /* Note: since we insert a breakpoint right after removing,
- any decisions about automatically using hardware breakpoints
- made in insert_bp_location are preserved. */
- if (b->loc_type == bp_loc_hardware_breakpoint)
- val = target_insert_hw_breakpoint (&b->target_info);
- else
- val = target_insert_breakpoint (&b->target_info);
- /* FIXME drow/2003-10-07: This doesn't handle any other kinds of
- breakpoints. It's wrong for watchpoints, for example. */
+ b->inserted = 0;
+ val = insert_bp_location (b, tmp_error_stream,
+ &dummy1, &dummy2, &dummy3);
if (val != 0)
{
do_cleanups (old_chain);
on this target, we may not be able to stop when the vfork is
seen, but only when the subsequent exec is seen. (And because
deleting fork catchpoints here but not vfork catchpoints will
- seem mysterious to users, keep those too.)
-
- ??rehrauer: Let's hope that merely clearing out this catchpoint's
- target address field, if any, is sufficient to have it be reset
- automagically. Certainly on HP-UX that's true.
-
- Jim Blandy <jimb@redhat.com>: Actually, zero is a perfectly
- valid code address on some platforms (like the mn10300
- simulators). We shouldn't assign any special interpretation to
- a breakpoint with a zero address. And in fact, GDB doesn't ---
- I can't see what that comment above is talking about. As far
- as I can tell, setting the address of a
- bp_catch_exec/bp_catch_vfork/bp_catch_fork breakpoint to zero
- is meaningless, since those are implemented with HP-UX kernel
- hackery, not by storing breakpoint instructions somewhere. */
+ seem mysterious to users, keep those too.) */
if ((b->type == bp_catch_exec) ||
(b->type == bp_catch_vfork) ||
(b->type == bp_catch_fork))
{
- b->loc->address = (CORE_ADDR) 0;
continue;
}
delete_breakpoint (b);
continue;
}
-
- /* If this breakpoint has survived the above battery of checks, then
- it must have a symbolic address. Be sure that it gets reevaluated
- to a target address, rather than reusing the old evaluation.
-
- Jim Blandy <jimb@redhat.com>: As explained above in the comment
- for bp_catch_exec and friends, I'm pretty sure this is entirely
- unnecessary. A call to breakpoint_re_set_one always recomputes
- the breakpoint's address from scratch, or deletes it if it can't.
- So I think this assignment could be deleted without effect. */
- b->loc->address = (CORE_ADDR) 0;
}
/* FIXME what about longjmp breakpoints? Re-create them here? */
create_overlay_event_breakpoint ("_ovly_debug_event");
don't know what the overlay manager might do. */
if (b->loc_type == bp_loc_hardware_breakpoint)
val = target_remove_hw_breakpoint (&b->target_info);
- else
+
+ /* However, we should remove *software* breakpoints only
+ if the section is still mapped, or else we overwrite
+ wrong code with the saved shadow contents. */
+ else if (section_is_mapped (b->section))
val = target_remove_breakpoint (&b->target_info);
+ else
+ val = 0;
}
else
{
{
struct breakpoint *b, *temp;
struct bp_location *bpt;
- static int warning_needed = 0;
ALL_BP_LOCATIONS (bpt)
bpt->inserted = 0;
/* Likewise for watchpoints on local expressions. */
if (b->exp_valid_block != NULL)
delete_breakpoint (b);
- if (context == inf_starting)
+ else if (context == inf_starting)
{
/* Reset val field to force reread of starting value
in insert_breakpoints. */
}
break;
default:
- /* Likewise for exception catchpoints in dynamic-linked
- executables where required */
- if (ep_is_exception_catchpoint (b)
- && deprecated_exception_catchpoints_are_fragile)
- {
- warning_needed = 1;
- delete_breakpoint (b);
- }
break;
}
}
-
- if (deprecated_exception_catchpoints_are_fragile)
- deprecated_exception_support_initialized = 0;
-
- /* Don't issue the warning unless it's really needed... */
- if (warning_needed && (context != inf_exited))
- {
- warning (_("Exception catchpoints from last run were deleted.\n"
- "You must reinsert them explicitly."));
- warning_needed = 0;
- }
}
/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
}
}
+ /* Also check for software single-step breakpoints. */
+ if (single_step_breakpoint_inserted_here_p (pc))
+ return 1;
+
return 0;
}
}
}
+ /* Also check for software single-step breakpoints. */
+ if (single_step_breakpoint_inserted_here_p (pc))
+ return 1;
+
return 0;
}
|| (ep->type == bp_catch_throw);
}
+void
+bpstat_free (bpstat bs)
+{
+ if (bs->old_val != NULL)
+ value_free (bs->old_val);
+ free_command_lines (&bs->commands);
+ xfree (bs);
+}
+
/* Clear a bpstat so that it says we are not at any breakpoint.
Also free any storage that is part of a bpstat. */
while (p != NULL)
{
q = p->next;
- if (p->old_val != NULL)
- value_free (p->old_val);
- free_command_lines (&p->commands);
- xfree (p);
+ bpstat_free (p);
p = q;
}
*bsp = NULL;
/* 2 */
annotate_field (1);
- if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
+ if (((int) b->type >= (sizeof (bptypes) / sizeof (bptypes[0])))
|| ((int) b->type != bptypes[(int) b->type].type))
internal_error (__FILE__, __LINE__,
_("bptypes table does not describe type #%d."),
strcpy (wrap_indent, " ");
if (addressprint)
{
- if (TARGET_ADDR_BIT <= 32)
+ if (gdbarch_addr_bit (current_gdbarch) <= 32)
strcat (wrap_indent, " ");
else
strcat (wrap_indent, " ");
{
if (nr_printable_breakpoints > 0)
annotate_field (4);
- if (TARGET_ADDR_BIT <= 32)
+ if (gdbarch_addr_bit (current_gdbarch) <= 32)
ui_out_table_header (uiout, 10, ui_left, "addr", "Address");/* 5 */
else
ui_out_table_header (uiout, 18, ui_left, "addr", "Address");/* 5 */
{
/* Compare against (CORE_ADDR)-1 in case some compiler decides
that a comparison of an unsigned with -1 is always false. */
- if (last_addr != (CORE_ADDR) -1)
+ if (last_addr != (CORE_ADDR) -1 && !server_command)
set_next_address (last_addr);
}
set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
{
struct breakpoint *b, *b1;
+ CORE_ADDR adjusted_address;
b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
memset (b, 0, sizeof (*b));
+
+ /* Adjust the breakpoint's address prior to allocating a location.
+ Once we call allocate_bp_location(), that mostly uninitialized
+ location will be placed on the location chain. Adjustment of the
+ breakpoint may cause read_memory_nobpt() to be called and we do
+ not want its scan of the location chain to find a breakpoint and
+ location that's only been partially initialized. */
+ adjusted_address = adjust_breakpoint_address (sal.pc, bptype);
+
b->loc = allocate_bp_location (b, bptype);
b->loc->requested_address = sal.pc;
- b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
- bptype);
+ b->loc->address = adjusted_address;
+
if (sal.symtab == NULL)
b->source_file = NULL;
else
apply to enabled breakpoints, disabled ones can just stay disabled. */
void
-disable_breakpoints_in_shlibs (int silent)
+disable_breakpoints_in_shlibs (void)
{
struct breakpoint *b;
int disabled_shlib_breaks = 0;
- /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
ALL_BREAKPOINTS (b)
{
if (((b->type == bp_breakpoint) || (b->type == bp_hardware_breakpoint))
&& solib_address (b->loc->address)
#endif
)
- {
b->enable_state = bp_shlib_disabled;
- if (!silent)
- {
- if (!disabled_shlib_breaks)
- {
- target_terminal_ours_for_output ();
- warning (_("Temporarily disabling shared library breakpoints:"));
- }
- disabled_shlib_breaks = 1;
- warning (_("breakpoint #%d "), b->number);
- }
- }
}
}
struct breakpoint *b;
int disabled_shlib_breaks = 0;
- /* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
ALL_BREAKPOINTS (b)
{
if ((b->loc->loc_type == bp_loc_hardware_breakpoint
error (_("Target can only support one kind of HW watchpoint at a time."));
}
-#if defined(HPUXHPPA)
- /* On HP-UX if you set a h/w
- watchpoint before the "run" command, the inferior dies with a e.g.,
- SIGILL once you start it. I initially believed this was due to a
- bad interaction between page protection traps and the initial
- startup sequence by the dynamic linker.
-
- However, I tried avoiding that by having HP-UX's implementation of
- TARGET_CAN_USE_HW_WATCHPOINT return FALSE if there was no inferior_ptid
- yet, which forced slow watches before a "run" or "attach", and it
- still fails somewhere in the startup code.
-
- Until I figure out what's happening, I'm disallowing watches altogether
- before the "run" or "attach" command. We'll tell the user they must
- set watches after getting the program started. */
- if (!target_has_execution)
- {
- warning (_("can't do that without a running program; try \"break main\"), \"run\" first");
- return;
- }
-#endif /* HPUXHPPA */
-
/* Change the type of breakpoint to an ordinary watchpoint if a hardware
watchpoint could not be set. */
if (!mem_cnt || target_resources_ok <= 0)
/* Be sure no bpstat's are pointing at it after it's been freed. */
/* FIXME, how can we find all bpstat's?
- We just check stop_bpstat for now. */
+ We just check stop_bpstat for now. Note that we cannot just
+ remove bpstats pointing at bpt from the stop_bpstat list
+ entirely, as breakpoint commands are associated with the bpstat;
+ if we remove it here, then the later call to
+ bpstat_do_actions (&stop_bpstat);
+ in event-top.c won't do anything, and temporary breakpoints
+ with commands won't work. */
for (bs = stop_bpstat; bs; bs = bs->next)
if (bs->breakpoint_at == bpt)
{
set_language (save_language);
input_radix = save_input_radix;
- if (GET_LONGJMP_TARGET_P ())
+ if (gdbarch_get_longjmp_target_p (current_gdbarch))
{
create_longjmp_breakpoint ("longjmp");
create_longjmp_breakpoint ("_longjmp");
}
}
+/* Check whether a software single-step breakpoint is inserted at PC. */
+
+static int
+single_step_breakpoint_inserted_here_p (CORE_ADDR pc)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ {
+ struct bp_target_info *bp_tgt = single_step_breakpoints[i];
+ if (bp_tgt && bp_tgt->placed_address == pc)
+ return 1;
+ }
+
+ return 0;
+}
+
\f
/* This help string is used for the break, hbreak, tbreak and thbreak commands.
It is defined as a macro to prevent duplication.
address and file/line number respectively.\n\
\n\
Convenience variable \"$_\" and default examine address for \"x\"\n\
-are set to the address of the last breakpoint listed.\n\n\
+are set to the address of the last breakpoint listed unless the command\n\
+is prefixed with \"server \".\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set."));
}
address and file/line number respectively.\n\
\n\
Convenience variable \"$_\" and default examine address for \"x\"\n\
-are set to the address of the last breakpoint listed.\n\n\
+are set to the address of the last breakpoint listed unless the command\n\
+is prefixed with \"server \".\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set."));
address and file/line number respectively.\n\
\n\
Convenience variable \"$_\" and default examine address for \"x\"\n\
-are set to the address of the last breakpoint listed.\n\n\
+are set to the address of the last breakpoint listed unless the command\n\
+is prefixed with \"server \".\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set."));
address and file/line number respectively.\n\
\n\
Convenience variable \"$_\" and default examine address for \"x\"\n\
-are set to the address of the last breakpoint listed.\n\
-\n\
+are set to the address of the last breakpoint listed unless the command\n\
+is prefixed with \"server \".\n\n\
Convenience variable \"$bpnum\" contains the number of the last\n\
breakpoint set."),
&maintenanceinfolist);