}
}
-static void
-create_longjmp_master_breakpoint (void)
+/* Install a master longjmp breakpoint for OBJFILE using a probe. Return
+ true if a breakpoint was installed. */
+
+static bool
+create_longjmp_master_breakpoint_probe (objfile *objfile)
{
- scoped_restore_current_program_space restore_pspace;
+ struct gdbarch *gdbarch = objfile->arch ();
+ struct breakpoint_objfile_data *bp_objfile_data
+ = get_breakpoint_objfile_data (objfile);
- for (struct program_space *pspace : program_spaces)
+ if (!bp_objfile_data->longjmp_searched)
{
- set_current_program_space (pspace);
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libc", "longjmp");
- for (objfile *objfile : current_program_space->objfiles ())
+ if (!ret.empty ())
{
- int i;
- struct gdbarch *gdbarch;
- struct breakpoint_objfile_data *bp_objfile_data;
+ /* We are only interested in checking one element. */
+ probe *p = ret[0];
- gdbarch = objfile->arch ();
+ if (!p->can_evaluate_arguments ())
+ {
+ /* We cannot use the probe interface here,
+ because it does not know how to evaluate
+ arguments. */
+ ret.clear ();
+ }
+ }
+ bp_objfile_data->longjmp_probes = ret;
+ bp_objfile_data->longjmp_searched = 1;
+ }
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ if (bp_objfile_data->longjmp_probes.empty ())
+ return false;
- if (!bp_objfile_data->longjmp_searched)
- {
- std::vector<probe *> ret
- = find_probes_in_objfile (objfile, "libc", "longjmp");
+ for (probe *p : bp_objfile_data->longjmp_probes)
+ {
+ struct breakpoint *b;
- if (!ret.empty ())
- {
- /* We are only interested in checking one element. */
- probe *p = ret[0];
+ b = create_internal_breakpoint (gdbarch,
+ p->get_relocated_address (objfile),
+ bp_longjmp_master,
+ &internal_breakpoint_ops);
+ b->location = new_probe_location ("-probe-stap libc:longjmp");
+ b->enable_state = bp_disabled;
+ }
- if (!p->can_evaluate_arguments ())
- {
- /* We cannot use the probe interface here,
- because it does not know how to evaluate
- arguments. */
- ret.clear ();
- }
- }
- bp_objfile_data->longjmp_probes = ret;
- bp_objfile_data->longjmp_searched = 1;
- }
+ return true;
+}
- if (!bp_objfile_data->longjmp_probes.empty ())
- {
- for (probe *p : bp_objfile_data->longjmp_probes)
- {
- struct breakpoint *b;
-
- b = create_internal_breakpoint (gdbarch,
- p->get_relocated_address (objfile),
- bp_longjmp_master,
- &internal_breakpoint_ops);
- b->location = new_probe_location ("-probe-stap libc:longjmp");
- b->enable_state = bp_disabled;
- }
+/* Install master longjmp breakpoints for OBJFILE using longjmp_names.
+ Return true if at least one breakpoint was installed. */
+
+static bool
+create_longjmp_master_breakpoint_names (objfile *objfile)
+{
+ struct gdbarch *gdbarch = objfile->arch ();
+ if (!gdbarch_get_longjmp_target_p (gdbarch))
+ return false;
+ struct breakpoint_objfile_data *bp_objfile_data
+ = get_breakpoint_objfile_data (objfile);
+ unsigned int installed_bp = 0;
+
+ for (int i = 0; i < NUM_LONGJMP_NAMES; i++)
+ {
+ struct breakpoint *b;
+ const char *func_name;
+ CORE_ADDR addr;
+ struct explicit_location explicit_loc;
+
+ if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
+ continue;
+
+ func_name = longjmp_names[i];
+ if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
+ {
+ struct bound_minimal_symbol m;
+
+ m = lookup_minimal_symbol_text (func_name, objfile);
+ if (m.minsym == NULL)
+ {
+ /* Prevent future lookups in this objfile. */
+ bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
continue;
}
+ bp_objfile_data->longjmp_msym[i] = m;
+ }
- if (!gdbarch_get_longjmp_target_p (gdbarch))
- continue;
+ addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+ b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+ &internal_breakpoint_ops);
+ initialize_explicit_location (&explicit_loc);
+ explicit_loc.function_name = ASTRDUP (func_name);
+ b->location = new_explicit_location (&explicit_loc);
+ b->enable_state = bp_disabled;
+ installed_bp++;
+ }
- for (i = 0; i < NUM_LONGJMP_NAMES; i++)
- {
- struct breakpoint *b;
- const char *func_name;
- CORE_ADDR addr;
- struct explicit_location explicit_loc;
+ return installed_bp > 0;
+}
- if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
- continue;
+/* Create a master longjmp breakpoint. */
- func_name = longjmp_names[i];
- if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
- {
- struct bound_minimal_symbol m;
+static void
+create_longjmp_master_breakpoint (void)
+{
+ scoped_restore_current_program_space restore_pspace;
- m = lookup_minimal_symbol_text (func_name, objfile);
- if (m.minsym == NULL)
- {
- /* Prevent future lookups in this objfile. */
- bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
- continue;
- }
- bp_objfile_data->longjmp_msym[i] = m;
- }
+ for (struct program_space *pspace : program_spaces)
+ {
+ set_current_program_space (pspace);
- addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
- b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
- &internal_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
- b->enable_state = bp_disabled;
- }
+ for (objfile *obj : current_program_space->objfiles ())
+ {
+ /* Skip separate debug object, it's handled in the loop below. */
+ if (obj->separate_debug_objfile_backlink != nullptr)
+ continue;
+
+ /* Try a probe kind breakpoint on main objfile. */
+ if (create_longjmp_master_breakpoint_probe (obj))
+ continue;
+
+ /* Try longjmp_names kind breakpoints on main and separate_debug
+ objfiles. */
+ for (objfile *debug_objfile : obj->separate_debug_objfiles ())
+ if (create_longjmp_master_breakpoint_names (debug_objfile))
+ break;
}
}
}