struct cleanup *cleanup;
enum exception_event_kind kind = classify_exception_breakpoint (self);
struct event_location *location;
- struct sym_search_scope pspace_scope = null_search_scope ();
- struct program_space *filter_pspace = search_scope->pspace;
-
- /* Re-set in the whole pspace for now. */
- pspace_scope.pspace = search_scope->pspace;
- search_scope = &pspace_scope;
+ struct sym_search_scope pspace_search_scope;
/* We first try to use the probe interface. */
TRY
location
= new_probe_location (exception_functions[kind].probe);
cleanup = make_cleanup_delete_event_location (location);
- sals = parse_probes (location, filter_pspace, NULL);
+ sals = parse_probes (location, search_scope, NULL);
do_cleanups (cleanup);
}
CATCH (e, RETURN_MASK_ERROR)
{
/* Using the probe interface failed. Let's fallback to the normal
catchpoint mode. */
+
+ /* However, we may have already found a probe in another
+ objfile. In that case, leave it be. */
+ if (search_scope->objfile != NULL)
+ {
+ struct bp_location *l;
+
+ for (l = self->loc; l != NULL; l = l->next)
+ {
+ if (l->pspace == search_scope->pspace
+ && l->sal.probe != NULL)
+ return;
+ }
+ }
+
TRY
{
struct explicit_location explicit_loc;
}
END_CATCH
+ /* If we found a probe, remove all by-symbol locations
+ (__cxa_begin_catch, etc.) we may have found earlier on other
+ objfiles of the same progspace. E.g., if you set a catchpoint
+ before the program is running, we'll find __cxa_begin_catch@plt
+ in the main executable. Then when the program starts, we'll find
+ the real __cxa_begin_catch text minsym in
+ /usr/lib/debug/usr/lib64/libstdc++.so.debug, and then only later
+ will we find the probe when /lib64/libstdc++.so.6 is finally
+ loaded. */
+ if (sals.nelts == 1 && sals.sals[0].probe != NULL && search_scope->objfile != NULL)
+ {
+ pspace_search_scope = null_search_scope ();
+ pspace_search_scope.pspace = search_scope->pspace;
+ search_scope = &pspace_search_scope;
+ }
+
cleanup = make_cleanup (xfree, sals.sals);
update_breakpoint_locations (self, search_scope, sals, sals_end);
do_cleanups (cleanup);
enum bptype type_wanted)
{
struct linespec_sals lsal;
+ struct sym_search_scope search_scope = null_search_scope ();
- lsal.sals = parse_probes (location, NULL, canonical);
+ lsal.sals = parse_probes (location, &search_scope, canonical);
lsal.canonical = xstrdup (event_location_to_string (canonical->location));
VEC_safe_push (linespec_sals, canonical->sals, &lsal);
}
struct sym_search_scope *search_scope,
struct symtabs_and_lines *sals)
{
- *sals = parse_probes (location, search_scope->pspace, NULL);
+ *sals = parse_probes (location, search_scope, NULL);
if (!sals->sals)
error (_("probe not found"));
}
\f
/* A helper for parse_probes that decodes a probe specification in
- SEARCH_PSPACE. It appends matching SALs to RESULT. */
+ OBJFILE. It appends matching SALs to RESULT. */
static void
-parse_probes_in_pspace (const struct probe_ops *probe_ops,
- struct program_space *search_pspace,
- const char *objfile_namestr,
- const char *provider,
- const char *name,
- struct symtabs_and_lines *result)
+parse_probes_in_objfile (const struct probe_ops *probe_ops,
+ struct objfile *objfile,
+ const char *objfile_namestr,
+ const char *provider,
+ const char *name,
+ struct symtabs_and_lines *result)
{
- struct objfile *objfile;
-
- ALL_PSPACE_OBJFILES (search_pspace, objfile)
- {
- VEC (probe_p) *probes;
- struct probe *probe;
- int ix;
+ VEC (probe_p) *probes;
+ struct probe *probe;
+ int ix;
- if (!objfile->sf || !objfile->sf->sym_probe_fns)
- continue;
+ if (!objfile->sf || !objfile->sf->sym_probe_fns)
+ return;
- if (objfile_namestr
- && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0
- && FILENAME_CMP (lbasename (objfile_name (objfile)),
- objfile_namestr) != 0)
- continue;
+ if (objfile_namestr
+ && FILENAME_CMP (objfile_name (objfile), objfile_namestr) != 0
+ && FILENAME_CMP (lbasename (objfile_name (objfile)),
+ objfile_namestr) != 0)
+ return;
- probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
+ probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile);
- for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
- {
- struct symtab_and_line *sal;
+ for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
+ {
+ struct symtab_and_line *sal;
- if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
- continue;
+ if (probe_ops != &probe_ops_any && probe->pops != probe_ops)
+ continue;
- if (provider && strcmp (probe->provider, provider) != 0)
- continue;
+ if (provider && strcmp (probe->provider, provider) != 0)
+ continue;
- if (strcmp (probe->name, name) != 0)
- continue;
+ if (strcmp (probe->name, name) != 0)
+ continue;
- ++result->nelts;
- result->sals = XRESIZEVEC (struct symtab_and_line, result->sals,
- result->nelts);
- sal = &result->sals[result->nelts - 1];
+ ++result->nelts;
+ result->sals = XRESIZEVEC (struct symtab_and_line, result->sals,
+ result->nelts);
+ sal = &result->sals[result->nelts - 1];
- init_sal (sal);
+ init_sal (sal);
- sal->pc = get_probe_address (probe, objfile);
- sal->explicit_pc = 1;
- sal->section = find_pc_overlay (sal->pc);
- sal->pspace = search_pspace;
- sal->probe = probe;
- sal->objfile = objfile;
- }
+ sal->pc = get_probe_address (probe, objfile);
+ sal->explicit_pc = 1;
+ sal->section = find_pc_overlay (sal->pc);
+ sal->pspace = objfile->pspace;
+ sal->probe = probe;
+ sal->objfile = objfile;
}
}
struct symtabs_and_lines
parse_probes (const struct event_location *location,
- struct program_space *search_pspace,
+ struct sym_search_scope *search_scope,
struct linespec_result *canonical)
{
char *arg_end, *arg;
struct symtabs_and_lines result;
const struct probe_ops *probe_ops;
const char *arg_start, *cs;
+ struct program_space *pspace_iter;
+ struct objfile *objfile_iter;
result.sals = NULL;
result.nelts = 0;
if (objfile_namestr && *objfile_namestr == '\0')
error (_("invalid objfile name"));
- if (search_pspace != NULL)
+ ALL_SEARCH_SCOPE_OBJFILES (search_scope, pspace_iter, objfile_iter)
{
- parse_probes_in_pspace (probe_ops, search_pspace, objfile_namestr,
- provider, name, &result);
- }
- else
- {
- struct program_space *pspace;
-
- ALL_PSPACES (pspace)
- parse_probes_in_pspace (probe_ops, pspace, objfile_namestr,
- provider, name, &result);
+ parse_probes_in_objfile (probe_ops, objfile_iter, objfile_namestr,
+ provider, name, &result);
}
if (result.nelts == 0)