static void free_bp_location (struct bp_location *loc);
-static struct bp_location *
-allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type);
+static struct bp_location *allocate_bp_location (struct breakpoint *bpt);
static void update_global_location_list (int);
int breakpoint_count;
-/* This function returns a pointer to the string representation of the
- pathname of the dynamically-linked library that has just been
- loaded.
-
- This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE,
- or undefined results are guaranteed.
-
- This string's contents are only valid immediately after the
- inferior has stopped in the dynamic linker hook, and becomes
- invalid as soon as the inferior is continued. Clients should make
- a copy of this string if they wish to continue the inferior and
- then access the string. */
-
-#ifndef SOLIB_LOADED_LIBRARY_PATHNAME
-#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) ""
-#endif
-
-/* This function returns a pointer to the string representation of the
- pathname of the dynamically-linked library that has just been
- unloaded.
-
- This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is
- TRUE, or undefined results are guaranteed.
-
- This string's contents are only valid immediately after the
- inferior has stopped in the dynamic linker hook, and becomes
- invalid as soon as the inferior is continued. Clients should make
- a copy of this string if they wish to continue the inferior and
- then access the string. */
-
-#ifndef SOLIB_UNLOADED_LIBRARY_PATHNAME
-#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) ""
-#endif
-
-/* This function is called by the "catch load" command. It allows the
- debugger to be notified by the dynamic linker when a specified
- library file (or any library file, if filename is NULL) is loaded. */
-
-#ifndef SOLIB_CREATE_CATCH_LOAD_HOOK
-#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag,filename,cond_string) \
- error (_("catch of library loads not yet implemented on this platform"))
-#endif
-
-/* This function is called by the "catch unload" command. It allows
- the debugger to be notified by the dynamic linker when a specified
- library file (or any library file, if filename is NULL) is
- unloaded. */
-
-#ifndef SOLIB_CREATE_CATCH_UNLOAD_HOOK
-#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid, tempflag, filename, cond_string) \
- error (_("catch of library unloads not yet implemented on this platform"))
-#endif
-
/* Return whether a breakpoint is an active enabled breakpoint. */
static int
breakpoint_enabled (struct breakpoint *b)
}
}
-/* Assuming that B is a hardware watchpoint:
- - Reparse watchpoint expression, is REPARSE is non-zero
+/* Assuming that B is a watchpoint:
+ - Reparse watchpoint expression, if REPARSE is non-zero
- Evaluate expression and store the result in B->val
+ - Evaluate the condition if there is one, and store the result
+ in b->loc->cond.
- Update the list of values that must be watched in B->loc.
If the watchpoint is disabled, do nothing. If this is
struct bp_location *loc;
bpstat bs;
- /* We don't free locations. They are stored in
- bp_location_chain and update_global_locations will
- eventually delete them and remove breakpoints if
- needed. */
+ /* We don't free locations. They are stored in bp_location_chain and
+ update_global_locations will eventually delete them and remove
+ breakpoints if needed. */
b->loc = NULL;
if (b->disposition == disp_del_at_next_stop)
b->val_valid = 1;
}
+ /* Change the type of breakpoint between hardware assisted or an
+ ordinary watchpoint depending on the hardware support and free
+ hardware slots. REPARSE is set when the inferior is started. */
+ if ((b->type == bp_watchpoint || b->type == bp_hardware_watchpoint)
+ && reparse)
+ {
+ int i, mem_cnt, target_resources_ok, other_type_used;
+
+ i = hw_watchpoint_used_count (bp_hardware_watchpoint,
+ &other_type_used);
+ mem_cnt = can_use_hardware_watchpoint (val_chain);
+
+ if (mem_cnt)
+ target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT
+ (bp_hardware_watchpoint, i + mem_cnt, other_type_used);
+ if (!mem_cnt || target_resources_ok <= 0)
+ b->type = bp_watchpoint;
+ else
+ b->type = bp_hardware_watchpoint;
+ }
+
/* Look at each value on the value chain. */
for (v = val_chain; v; v = next)
{
else if (b->type == bp_access_watchpoint)
type = hw_access;
- loc = allocate_bp_location (b, bp_hardware_watchpoint);
+ loc = allocate_bp_location (b);
for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
else if (!within_current_scope)
{
printf_filtered (_("\
-Hardware watchpoint %d deleted because the program has left the block \n\
+Watchpoint %d deleted because the program has left the block \n\
in which its expression is valid.\n"),
b->number);
if (b->related_breakpoint)
update_global_location_list (1);
- if (!breakpoints_always_inserted_mode () && target_has_execution)
+ if (!breakpoints_always_inserted_mode ()
+ && (target_has_execution
+ || (gdbarch_has_global_solist (target_gdbarch)
+ && target_supports_multi_process ())))
/* update_global_location_list does not insert breakpoints
when always_inserted_mode is not enabled. Explicitly
insert them now. */
struct bp_location *bpt;
int ix;
+ /* If breakpoint locations are shared across processes, then there's
+ nothing to do. */
+ if (gdbarch_has_global_solist (target_gdbarch))
+ return;
+
ALL_BP_LOCATIONS (bpt)
if (bpt->owner->enable_state != bp_permanent)
bpt->inserted = 0;
int
ep_is_catchpoint (struct breakpoint *ep)
{
- return (ep->type == bp_catchpoint)
- || (ep->type == bp_catch_load)
- || (ep->type == bp_catch_unload);
-
- /* ??rehrauer: Add more kinds here, as are implemented... */
-}
-
-int
-ep_is_shlib_catchpoint (struct breakpoint *ep)
-{
- return
- (ep->type == bp_catch_load)
- || (ep->type == bp_catch_unload);
+ return (ep->type == bp_catchpoint);
}
void
return PRINT_NOTHING;
break;
- case bp_catch_load:
- annotate_catchpoint (b->number);
- printf_filtered (_("\nCatchpoint %d (loaded %s), "),
- b->number,
- b->triggered_dll_pathname);
- return PRINT_SRC_AND_LOC;
- break;
-
- case bp_catch_unload:
- annotate_catchpoint (b->number);
- printf_filtered (_("\nCatchpoint %d (unloaded %s), "),
- b->number,
- b->triggered_dll_pathname);
- return PRINT_SRC_AND_LOC;
- break;
-
case bp_watchpoint:
case bp_hardware_watchpoint:
annotate_watchpoint (b->number);
return 0;
}
- /* Is this a catchpoint of a load or unload? If so, did we
- get a load or unload of the specified library? If not,
- ignore it. */
- if ((b->type == bp_catch_load)
-#if defined(SOLIB_HAVE_LOAD_EVENT)
- && (!SOLIB_HAVE_LOAD_EVENT (PIDGET (inferior_ptid))
- || ((b->dll_pathname != NULL)
- && (strcmp (b->dll_pathname,
- SOLIB_LOADED_LIBRARY_PATHNAME (
- PIDGET (inferior_ptid)))
- != 0)))
-#endif
- )
- return 0;
-
- if ((b->type == bp_catch_unload)
-#if defined(SOLIB_HAVE_UNLOAD_EVENT)
- && (!SOLIB_HAVE_UNLOAD_EVENT (PIDGET (inferior_ptid))
- || ((b->dll_pathname != NULL)
- && (strcmp (b->dll_pathname,
- SOLIB_UNLOADED_LIBRARY_PATHNAME (
- PIDGET (inferior_ptid)))
- != 0)))
-#endif
- )
- return 0;
-
if (b->type == bp_catchpoint)
{
gdb_assert (b->ops != NULL && b->ops->breakpoint_hit != NULL);
/* We hit the shared library event breakpoint. */
shlib_event,
- /* We caught a shared library event. */
- catch_shlib_event,
-
/* This is just used to count how many enums there are. */
class_last
};
#define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
#define sr BPSTAT_WHAT_STEP_RESUME
#define shl BPSTAT_WHAT_CHECK_SHLIBS
-#define shlr BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK
/* "Can't happen." Might want to print an error message.
abort() is not out of the question, but chances are GDB is just
back and decide something of a lower priority is better. The
ordering is:
- kc < clr sgl shl shlr slr sn sr ss
- sgl < shl shlr slr sn sr ss
- slr < err shl shlr sn sr ss
- clr < err shl shlr sn sr ss
- ss < shl shlr sn sr
- sn < shl shlr sr
- shl < shlr sr
- shlr < sr
+ kc < clr sgl shl slr sn sr ss
+ sgl < shl slr sn sr ss
+ slr < err shl sn sr ss
+ clr < err shl sn sr ss
+ ss < shl sn sr
+ sn < shl sr
+ shl < sr
sr <
What I think this means is that we don't need a damned table
table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
{
/* old action */
- /* kc ss sn sgl slr clr sr shl shlr
+ /* kc ss sn sgl slr clr sr shl
*/
/*no_effect */
- {kc, ss, sn, sgl, slr, clr, sr, shl, shlr},
+ {kc, ss, sn, sgl, slr, clr, sr, shl},
/*wp_silent */
- {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
+ {ss, ss, sn, ss, ss, ss, sr, shl},
/*wp_noisy */
- {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+ {sn, sn, sn, sn, sn, sn, sr, shl},
/*bp_nostop */
- {sgl, ss, sn, sgl, slr, slr, sr, shl, shlr},
+ {sgl, ss, sn, sgl, slr, slr, sr, shl},
/*bp_silent */
- {ss, ss, sn, ss, ss, ss, sr, shl, shlr},
+ {ss, ss, sn, ss, ss, ss, sr, shl},
/*bp_noisy */
- {sn, sn, sn, sn, sn, sn, sr, shl, shlr},
+ {sn, sn, sn, sn, sn, sn, sr, shl},
/*long_jump */
- {slr, ss, sn, slr, slr, err, sr, shl, shlr},
+ {slr, ss, sn, slr, slr, err, sr, shl},
/*long_resume */
- {clr, ss, sn, err, err, err, sr, shl, shlr},
+ {clr, ss, sn, err, err, err, sr, shl},
/*step_resume */
- {sr, sr, sr, sr, sr, sr, sr, sr, sr},
+ {sr, sr, sr, sr, sr, sr, sr, sr},
/*shlib */
- {shl, shl, shl, shl, shl, shl, sr, shl, shlr},
-/*catch_shlib */
- {shlr, shlr, shlr, shlr, shlr, shlr, sr, shlr, shlr}
+ {shl, shl, shl, shl, shl, shl, sr, shl}
};
#undef kc
#undef sr
#undef ts
#undef shl
-#undef shlr
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
struct bpstat_what retval;
case bp_overlay_event:
bs_class = bp_nostop;
break;
- case bp_catch_load:
- case bp_catch_unload:
- /* Only if this catchpoint triggered should we cause the
- step-out-of-dld behaviour. Otherwise, we ignore this
- catchpoint. */
- if (bs->stop)
- bs_class = catch_shlib_event;
- else
- bs_class = no_effect;
- break;
case bp_catchpoint:
if (bs->stop)
{
\f
-/* Given a bpstat that records zero or more triggered eventpoints, this
- function returns another bpstat which contains only the catchpoints
- on that first list, if any. */
-void
-bpstat_get_triggered_catchpoints (bpstat ep_list, bpstat *cp_list)
-{
- struct bpstats root_bs[1];
- bpstat bs = root_bs;
- struct breakpoint *ep;
- char *dll_pathname;
-
- bpstat_clear (cp_list);
- root_bs->next = NULL;
-
- for (; ep_list != NULL; ep_list = ep_list->next)
- {
- /* Is this eventpoint a catchpoint? If not, ignore it. */
- ep = ep_list->breakpoint_at->owner;
- if (ep == NULL)
- break;
- if ((ep->type != bp_catch_load) &&
- (ep->type != bp_catch_unload))
- /* pai: (temp) ADD fork/vfork here!! */
- continue;
-
- /* Yes; add it to the list. */
- bs = bpstat_alloc (ep_list->breakpoint_at, bs);
- *bs = *ep_list;
- bs->next = NULL;
- bs = root_bs->next;
-
-#if defined(SOLIB_ADD)
- /* Also, for each triggered catchpoint, tag it with the name of
- the library that caused this trigger. (We copy the name now,
- because it's only guaranteed to be available NOW, when the
- catchpoint triggers. Clients who may wish to know the name
- later must get it from the catchpoint itself.) */
- if (ep->triggered_dll_pathname != NULL)
- xfree (ep->triggered_dll_pathname);
- if (ep->type == bp_catch_load)
- dll_pathname = SOLIB_LOADED_LIBRARY_PATHNAME (
- PIDGET (inferior_ptid));
- else
- dll_pathname = SOLIB_UNLOADED_LIBRARY_PATHNAME (
- PIDGET (inferior_ptid));
-#else
- dll_pathname = NULL;
-#endif
- if (dll_pathname)
- {
- ep->triggered_dll_pathname = (char *)
- xmalloc (strlen (dll_pathname) + 1);
- strcpy (ep->triggered_dll_pathname, dll_pathname);
- }
- else
- ep->triggered_dll_pathname = NULL;
- }
-
- *cp_list = bs;
-}
-
static void print_breakpoint_location (struct breakpoint *b,
struct bp_location *loc,
char *wrap_indent,
{bp_thread_event, "thread events"},
{bp_overlay_event, "overlay events"},
{bp_catchpoint, "catchpoint"},
- {bp_catch_load, "catch load"},
- {bp_catch_unload, "catch unload"}
};
static char bpenables[] = "nynny";
ui_out_field_stream (uiout, "what", stb);
break;
- case bp_catch_load:
- case bp_catch_unload:
- /* Field 4, the address, is omitted (which makes the columns
- not line up too nicely with the headers, but the effect
- is relatively readable). */
- if (opts.addressprint)
- ui_out_field_skip (uiout, "addr");
- annotate_field (5);
- if (b->dll_pathname == NULL)
- {
- ui_out_field_string (uiout, "what", "<any library>");
- ui_out_spaces (uiout, 1);
- }
- else
- {
- ui_out_text (uiout, "library \"");
- ui_out_field_string (uiout, "what", b->dll_pathname);
- ui_out_text (uiout, "\" ");
- }
- break;
-
case bp_breakpoint:
case bp_hardware_breakpoint:
case bp_until:
{
return (b->type == bp_breakpoint
|| b->type == bp_catchpoint
- || b->type == bp_catch_load
- || b->type == bp_catch_unload
|| b->type == bp_hardware_breakpoint
|| b->type == bp_watchpoint
|| b->type == bp_read_watchpoint
/* Allocate a struct bp_location. */
static struct bp_location *
-allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type)
+allocate_bp_location (struct breakpoint *bpt)
{
struct bp_location *loc, *loc_p;
loc->shlib_disabled = 0;
loc->enabled = 1;
- switch (bp_type)
+ switch (bpt->type)
{
case bp_breakpoint:
case bp_until:
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
- case bp_catch_load:
- case bp_catch_unload:
loc->loc_type = bp_loc_software_breakpoint;
break;
case bp_hardware_breakpoint:
b->ignore_count = 0;
b->commands = NULL;
b->frame_id = null_frame_id;
- b->dll_pathname = NULL;
- b->triggered_dll_pathname = NULL;
b->forked_inferior_pid = null_ptid;
b->exec_pathname = NULL;
b->ops = NULL;
breakpoint may cause target_read_memory() 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);
+ adjusted_address = adjust_breakpoint_address (sal.pc, b->type);
- b->loc = allocate_bp_location (b, bptype);
+ b->loc = allocate_bp_location (b);
b->loc->requested_address = sal.pc;
b->loc->address = adjusted_address;
printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
say_where = 1;
break;
- case bp_catch_load:
- case bp_catch_unload:
- printf_filtered (_("Catchpoint %d (%s %s)"),
- b->number,
- (b->type == bp_catch_load) ? "load" : "unload",
- (b->dll_pathname != NULL) ?
- b->dll_pathname : "<any library>");
- break;
case bp_until:
case bp_finish:
\f
static struct bp_location *
-add_location_to_breakpoint (struct breakpoint *b, enum bptype bptype,
+add_location_to_breakpoint (struct breakpoint *b,
const struct symtab_and_line *sal)
{
struct bp_location *loc, **tmp;
- loc = allocate_bp_location (b, bptype);
+ loc = allocate_bp_location (b);
for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
;
*tmp = loc;
loc->requested_address = sal->pc;
- loc->address = adjust_breakpoint_address (loc->requested_address,
- bptype);
+ loc->address = adjust_breakpoint_address (loc->requested_address, b->type);
loc->section = sal->section;
set_breakpoint_location_function (loc);
CORE_ADDR addr;
const gdb_byte *brk;
gdb_byte *target_mem;
+ struct cleanup *cleanup;
+ int retval = 0;
gdb_assert (loc != NULL);
addr = loc->address;
brk = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &len);
+ /* Software breakpoints unsupported? */
+ if (brk == NULL)
+ return 0;
+
target_mem = alloca (len);
+ /* Enable the automatic memory restoration from breakpoints while
+ we read the memory. Otherwise we could say about our temporary
+ breakpoints they are permanent. */
+ cleanup = make_show_memory_breakpoints_cleanup (0);
+
if (target_read_memory (loc->address, target_mem, len) == 0
&& memcmp (target_mem, brk, len) == 0)
- return 1;
+ retval = 1;
- return 0;
+ do_cleanups (cleanup);
+
+ return retval;
}
}
else
{
- loc = add_location_to_breakpoint (b, type, &sal);
+ loc = add_location_to_breakpoint (b, &sal);
}
if (bp_loc_is_permanent (loc))
create_catchpoint (tempflag, cond_string, &catch_exec_breakpoint_ops);
}
-static void
-catch_load_command_1 (char *arg, int from_tty, struct cmd_list_element *command)
-{
- int tempflag;
- char *dll_pathname = NULL;
- char *cond_string = NULL;
-
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
- if (!arg)
- arg = "";
- ep_skip_leading_whitespace (&arg);
-
- /* The allowed syntax is:
- catch load
- catch load if <cond>
- catch load <filename>
- catch load <filename> if <cond>
-
- The user is not allowed to specify the <filename> after an
- if clause.
-
- We'll ignore the pathological case of a file named "if".
-
- First, check if there's an if clause. If so, then there
- cannot be a filename. */
- cond_string = ep_parse_optional_if_clause (&arg);
-
- /* If there was an if clause, then there cannot be a filename.
- Else, there might be a filename and an if clause. */
- if (cond_string == NULL)
- {
- dll_pathname = ep_parse_optional_filename (&arg);
- ep_skip_leading_whitespace (&arg);
- cond_string = ep_parse_optional_if_clause (&arg);
- }
-
- if ((*arg != '\0') && !isspace (*arg))
- error (_("Junk at end of arguments."));
-
- /* Create a load breakpoint that only triggers when a load of
- the specified dll (or any dll, if no pathname was specified)
- occurs. */
- SOLIB_CREATE_CATCH_LOAD_HOOK (PIDGET (inferior_ptid), tempflag,
- dll_pathname, cond_string);
-}
-
-static void
-catch_unload_command_1 (char *arg, int from_tty,
- struct cmd_list_element *command)
-{
- int tempflag;
- char *dll_pathname = NULL;
- char *cond_string = NULL;
-
- tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
-
- if (!arg)
- arg = "";
- ep_skip_leading_whitespace (&arg);
-
- /* The allowed syntax is:
- catch unload
- catch unload if <cond>
- catch unload <filename>
- catch unload <filename> if <cond>
-
- The user is not allowed to specify the <filename> after an
- if clause.
-
- We'll ignore the pathological case of a file named "if".
-
- First, check if there's an if clause. If so, then there
- cannot be a filename. */
- cond_string = ep_parse_optional_if_clause (&arg);
-
- /* If there was an if clause, then there cannot be a filename.
- Else, there might be a filename and an if clause. */
- if (cond_string == NULL)
- {
- dll_pathname = ep_parse_optional_filename (&arg);
- ep_skip_leading_whitespace (&arg);
- cond_string = ep_parse_optional_if_clause (&arg);
- }
-
- if ((*arg != '\0') && !isspace (*arg))
- error (_("Junk at end of arguments."));
-
- /* Create an unload breakpoint that only triggers when an unload of
- the specified dll (or any dll, if no pathname was specified)
- occurs. */
- SOLIB_CREATE_CATCH_UNLOAD_HOOK (PIDGET (inferior_ptid), tempflag,
- dll_pathname, cond_string);
-}
-
static enum print_stop_action
print_exception_catchpoint (struct breakpoint *b)
{
}
}
-/* If SHOULD_INSERT is true, do not insert any breakpoint locations
+/* If SHOULD_INSERT is false, do not insert any breakpoint locations
into the inferior, only remove already-inserted locations that no
longer should be inserted. Functions that delete a breakpoint or
breakpoints should pass false, so that deleting a breakpoint
check_duplicates (b);
}
- if (breakpoints_always_inserted_mode ()
- && should_insert
- && target_has_execution)
+ if (breakpoints_always_inserted_mode () && should_insert
+ && (target_has_execution
+ || (gdbarch_has_global_solist (target_gdbarch)
+ && target_supports_multi_process ())))
insert_breakpoint_locations ();
}
value_free (bpt->val);
if (bpt->source_file != NULL)
xfree (bpt->source_file);
- if (bpt->dll_pathname != NULL)
- xfree (bpt->dll_pathname);
- if (bpt->triggered_dll_pathname != NULL)
- xfree (bpt->triggered_dll_pathname);
if (bpt->exec_pathname != NULL)
xfree (bpt->exec_pathname);
for (i = 0; i < sals.nelts; ++i)
{
struct bp_location *new_loc =
- add_location_to_breakpoint (b, b->type, &(sals.sals[i]));
+ add_location_to_breakpoint (b, &(sals.sals[i]));
/* Reparse conditions, they might contain references to the
old symtab. */
return 0;
case bp_breakpoint:
case bp_hardware_breakpoint:
- case bp_catch_load:
- case bp_catch_unload:
if (b->addr_string == NULL)
{
/* Anything without a string can't be re-set. */
continue;
case bp_breakpoint:
case bp_catchpoint:
- case bp_catch_load:
- case bp_catch_unload:
case bp_hardware_breakpoint:
case bp_watchpoint:
case bp_hardware_watchpoint:
continue;
case bp_breakpoint:
case bp_catchpoint:
- case bp_catch_load:
- case bp_catch_unload:
case bp_hardware_breakpoint:
case bp_watchpoint:
case bp_hardware_watchpoint:
catch_exec_command_1,
CATCH_PERMANENT,
CATCH_TEMPORARY);
- add_catch_command ("load", _("\
-Catch library loads.\n\
-With an argument, catch only loads of that library."),
- catch_load_command_1,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
- add_catch_command ("unload", _("\
-Catch library unloads.\n\
-With an argument, catch only unloads of that library."),
- catch_unload_command_1,
- CATCH_PERMANENT,
- CATCH_TEMPORARY);
add_catch_command ("exception", _("\
Catch Ada exceptions, when raised.\n\
With an argument, catch only exceptions with the given name."),