From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23803 invoked by alias); 17 Mar 2011 13:59:24 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 23775 invoked by uid 306); 17 Mar 2011 13:59:23 -0000 Date: Thu, 17 Mar 2011 13:59:00 -0000 Message-ID: <20110317135923.23760.qmail@sourceware.org> From: tromey@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-sergiodj-stap: implement longjmp probes this is still untested X-Git-Refname: refs/heads/archer-sergiodj-stap X-Git-Reftype: branch X-Git-Oldrev: d909b1c3af91be2fe436ed45662a8301cbd6c86d X-Git-Newrev: 8fed9947347921e703b14558a062699a1ba8b563 X-SW-Source: 2011-q1/txt/msg00214.txt.bz2 List-Id: The branch, archer-sergiodj-stap has been updated via 8fed9947347921e703b14558a062699a1ba8b563 (commit) from d909b1c3af91be2fe436ed45662a8301cbd6c86d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 8fed9947347921e703b14558a062699a1ba8b563 Author: Tom Tromey Date: Thu Mar 17 07:57:48 2011 -0600 implement longjmp probes this is still untested ----------------------------------------------------------------------- Summary of changes: gdb/breakpoint.c | 31 +++++++++++++++++++++++++++++-- gdb/infrun.c | 31 +++++++++++++------------------ gdb/stap-probe.c | 25 +++++++++++++++++++++++++ gdb/stap-probe.h | 6 ++++++ 4 files changed, 73 insertions(+), 20 deletions(-) First 500 lines of diff: diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 353b051..2126875 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2113,6 +2113,9 @@ struct breakpoint_objfile_data /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */ struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES]; + /* SystemTap probe point for longjmp (if any). */ + const struct stap_probe *longjmp_probe; + /* Minimal symbol for "std::terminate()" (if any). */ struct minimal_symbol *terminate_msym; @@ -2125,6 +2128,9 @@ struct breakpoint_objfile_data static const struct objfile_data *breakpoint_objfile_key; +/* SystemTap probe not found sentinel. */ +static const struct stap_probe probe_not_found; + /* Minimal symbol not found sentinel. */ static struct minimal_symbol msym_not_found; @@ -2232,6 +2238,29 @@ create_longjmp_master_breakpoint (void) bp_objfile_data = get_breakpoint_objfile_data (objfile); + if (bp_objfile_data->longjmp_probe != &probe_not_found) + { + if (bp_objfile_data->longjmp_probe == NULL) + bp_objfile_data->longjmp_probe + = find_probe_in_objfile (objfile, "libc", "longjmp"); + + if (bp_objfile_data->longjmp_probe) + { + struct breakpoint *b; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + + b = create_internal_breakpoint (gdbarch, + bp_objfile_data->longjmp_probe->address, + bp_longjmp_master); + b->addr_string = xstrdup ("probe:libc:longjmp"); + b->enable_state = bp_disabled; + + continue; + } + else + bp_objfile_data->longjmp_probe = &probe_not_found; + } + for (i = 0; i < NUM_LONGJMP_NAMES; i++) { struct breakpoint *b; @@ -2328,8 +2357,6 @@ create_std_terminate_master_breakpoint (void) void create_exception_master_breakpoint (void) { - static struct stap_probe probe_not_found; - struct objfile *objfile; const char *const func_name = "_Unwind_DebugHook"; diff --git a/gdb/infrun.c b/gdb/infrun.c index 0779215..751c9ef 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -4166,9 +4166,17 @@ process_event_stop_test: if (what.is_longjmp) { - if (!gdbarch_get_longjmp_target_p (gdbarch) - || !gdbarch_get_longjmp_target (gdbarch, - frame, &jmp_buf_pc)) + struct value *arg_value; + + /* If we set the longjmp breakpoint via a SystemTap probe, + then use it to extract the arguments. The destination + PC is the third argument to the probe. */ + arg_value = stap_safe_evaluate_at_pc (frame, 2); + if (arg_value) + jmp_buf_pc = value_as_address (arg_value); + else if (!gdbarch_get_longjmp_target_p (gdbarch) + || !gdbarch_get_longjmp_target (gdbarch, + frame, &jmp_buf_pc)) { if (debug_infrun) fprintf_unfiltered (gdb_stdlog, @@ -5269,27 +5277,14 @@ insert_exception_resume_from_probe (struct thread_info *tp, struct objfile *objfile, struct frame_info *frame) { - int n_probes; struct value *arg_value; CORE_ADDR handler; struct breakpoint *bp; - /* This is really a "can't happen", but we are paranoid. */ - if (!objfile->sf || !objfile->sf->sym_probe_fns) + arg_value = stap_safe_evaluate_at_pc (frame, 1); + if (!arg_value) return; - n_probes - = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile, - probe); - if (n_probes < 2) - return; - - /* We are interested in the second argument to the probe. */ - arg_value - = objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile, - probe, - frame, - 1); handler = value_as_address (arg_value); if (debug_infrun) diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index dd86b62..90c6c4f 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -1160,6 +1160,31 @@ stap_evaluate_probe_argument (struct objfile *objfile, return stap_evaluate_probe_argument_1 (objfile, probe, frame, n); } +/* See documentation in stap-probe.h. */ + +struct value * +stap_safe_evaluate_at_pc (struct frame_info *frame, int n) +{ + const struct stap_probe *probe; + struct objfile *objfile; + int n_probes; + + probe = find_probe_by_pc (get_frame_pc (frame), &objfile); + if (!probe) + return NULL; + gdb_assert (objfile->sf && objfile->sf->sym_probe_fns); + + n_probes + = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile, + probe); + if (n >= n_probes) + return NULL; + + return objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile, + probe, + frame, + n); +} void stap_free_parsed_args (struct stap_args_info *parsed_args) diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h index a2c9b30..f6e67c2 100644 --- a/gdb/stap-probe.h +++ b/gdb/stap-probe.h @@ -86,4 +86,10 @@ extern struct value *stap_evaluate_probe_argument (struct objfile *objfile, struct frame_info *frame, int n); +/* A convenience function that finds a probe at the PC in FRAME and + evaluates argument N. If there is no probe at that location, or if + the probe does not have enough arguments, this returns NULL. */ +extern struct value *stap_safe_evaluate_at_pc (struct frame_info *frame, + int n); + #endif /* !defined (STAP_PROBE_H) */ hooks/post-receive -- Repository for Project Archer.