From 031fda598f1616a7aa563132111ad5acf65599e6 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Mon, 8 Nov 2010 14:48:01 -0500 Subject: [PATCH] PR11811: warn on missing unwind info with 'stap -d FOO' * unwind.c (unwind_frame): Demote common warnings to dbug_unwind messages. (unwind): Print a warning for unwind operations foiled by modules that did not have pre-uploaded unwind data. * buildrun.cxx (compile_pass): Check for exported __module_text_address. --- buildrun.cxx | 1 + runtime/unwind.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/buildrun.cxx b/buildrun.cxx index b373de61a..26e4e545c 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -193,6 +193,7 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-utrace-regset.c", "STAPCONF_UTRACE_REGSET", NULL); output_autoconf(s, o, "autoconf-uprobe-get-pc.c", "STAPCONF_UPROBE_GET_PC", NULL); output_exportconf(s, o, "cpu_khz", "STAPCONF_CPU_KHZ"); + output_exportconf(s, o, "__module_text_address", "STAPCONF_MODULE_TEXT_ADDRESS"); output_autoconf(s, o, "autoconf-probe-kernel.c", "STAPCONF_PROBE_KERNEL", NULL); output_autoconf(s, o, "autoconf-save-stack-trace.c", diff --git a/runtime/unwind.c b/runtime/unwind.c index 589326ab1..da39223a8 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -998,11 +998,11 @@ static int unwind_frame(struct unwind_context *context, ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed; endLoc = startLoc + read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType); if (pc > endLoc) { - _stp_warn("pc (%lx) > endLoc(%lx)\n", pc, endLoc); + dbug_unwind(1, "pc (%lx) > endLoc(%lx)\n", pc, endLoc); goto done; } } else { - _stp_warn("fde found in header, but cie is bad!\n"); + dbug_unwind(1, "fde found in header, but cie is bad!\n"); fde = NULL; } } @@ -1271,6 +1271,7 @@ static int unwind(struct unwind_context *context, struct unwind_frame_info *frame = &context->info; unsigned long pc = UNW_PC(frame) - frame->call_frame; int res; + const char *module_name = 0; dbug_unwind(1, "pc=%lx, %lx", pc, UNW_PC(frame)); @@ -1279,14 +1280,33 @@ static int unwind(struct unwind_context *context, if (tsk) { - m = _stp_umod_lookup (pc, tsk, NULL, NULL, NULL); + m = _stp_umod_lookup (pc, tsk, & module_name, NULL, NULL); if (m) s = &m->sections[0]; } else - m = _stp_kmod_sec_lookup (pc, &s); + { + preempt_disable(); /* probably redundant */ + m = _stp_kmod_sec_lookup (pc, &s); + if (!m) { +#ifdef STAPCONF_MODULE_TEXT_ADDRESS + struct module *ko = __module_text_address (pc); + if (ko) { module_name = ko->name; } + else { + /* Possible heuristic: we could assume we're talking + about the kernel. If __kernel_text_address() + were SYMBOL_EXPORT'd, we could call that and be + more sure. */ + } +#endif + } + preempt_enable_no_resched(); + } if (unlikely(m == NULL)) { + if (module_name) + _stp_warn ("Missing unwind data for module, rerun with 'stap -d %s'\n", + module_name); // Don't _stp_warn about this, will use fallback unwinder. dbug_unwind(1, "No module found for pc=%lx", pc); return -EINVAL; @@ -1301,6 +1321,12 @@ static int unwind(struct unwind_context *context, m->eh_frame_len, 1); } + /* This situation occurs where some unwind data was found, but + it was lacking somehow. */ + if (res != 0) { + dbug_unwind (2, "unwinding failed: %d\n", res); + } + return res; } -- 2.43.5