From 7774095b25424019098226eaa7c1148ff24b800b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 21 Feb 2009 00:40:23 +0100 Subject: Adjust ET_DYN symbol addresses against module base. * translate.cxx (dump_unwindsyms): Adjust sym_addr for ET_DYN always against module base as workaround for buggy elfutils < 0.138. --- translate.cxx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index c0e76a02..530b077d 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4551,10 +4551,19 @@ dump_unwindsyms (Dwfl_Module *m, if (n > 0) // only try to relocate if there exist relocation bases { + Dwarf_Addr save_addr = sym_addr; int ki = dwfl_module_relocate_address (m, &sym_addr); dwfl_assert ("dwfl_module_relocate_address", ki >= 0); secname = dwfl_module_relocation_info (m, ki, NULL); - } + + // For ET_DYN files (secname == "") we do ignore the + // dwfl_module_relocate_address adjustment. libdwfl + // up to 0.137 would substract the wrong bias. So we do + // it ourself, it is always just the module base address + // in this case. + if (ki == 0 && secname != NULL && secname[0] == '\0') + sym_addr = save_addr - base; + } if (n == 1 && modname == "kernel") { -- cgit From 98e45bcea73ee4642e6bfda672f5266089cb5586 Mon Sep 17 00:00:00 2001 From: David Smith Date: Mon, 23 Feb 2009 09:45:24 -0600 Subject: Made probe_start()/probe_exit() function definitions match their declarations. 2009-02-23 David Smith * translate.cxx (translate_pass): Made probe_start()/probe_exit() function definitions match their declarations. --- translate.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 530b077d..e6985504 100644 --- a/translate.cxx +++ b/translate.cxx @@ -5009,11 +5009,11 @@ translate_pass (systemtap_session& s) s.op->newline(); // XXX impedance mismatch - s.op->newline() << "static int probe_start () {"; + s.op->newline() << "static int probe_start (void) {"; s.op->newline(1) << "return systemtap_module_init () ? -1 : 0;"; s.op->newline(-1) << "}"; s.op->newline(); - s.op->newline() << "static void probe_exit () {"; + s.op->newline() << "static void probe_exit (void) {"; s.op->newline(1) << "systemtap_module_exit ();"; s.op->newline(-1) << "}"; s.op->assert_0_indent(); -- cgit From cfba34fccd99924a47622c5082706867f0a34b12 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 24 Feb 2009 11:04:00 +0100 Subject: Adjust extra_offset address against module base. * translate.cxx (dump_unwindsyms): Adjust extra_offset always against module base as workaround for buggy elfutils < 0.138. --- translate.cxx | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index e6985504..135830df 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4534,6 +4534,10 @@ dump_unwindsyms (Dwfl_Module *m, ki = dwfl_module_relocate_address (m, &extra_offset); dwfl_assert ("dwfl_module_relocate_address extra_offset", ki >= 0); + // Sadly dwfl_module_relocate_address is broken on + // elfutils < 0.138, so we need to adjust for the module + // base address outself. (see also below). + extra_offset = sym.st_value - base; if (c->session.verbose > 2) clog << "Found kernel _stext 0x" << hex << extra_offset << dec << endl; } -- cgit From 0e4c80225fc77cfa5b830ddac3f60a28d47ce7bb Mon Sep 17 00:00:00 2001 From: Wenji Huang Date: Tue, 24 Feb 2009 21:36:32 -0500 Subject: Skip generating empty struct global Impact: trivial cleanup. Avoid emitting empty struct global code that is harmless. Signed-off-by: Wenji Huang --- translate.cxx | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 135830df..655937d7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4954,21 +4954,23 @@ translate_pass (systemtap_session& s) s.op->newline() << s.embeds[i]->code << "\n"; } - s.op->newline() << "static struct {"; - s.op->indent(1); - for (unsigned i=0; iemit_global (s.globals[i]); - } - s.op->newline(-1) << "} global = {"; - s.op->newline(1); - for (unsigned i=0; iemit_global_init (s.globals[i]); - } - s.op->newline(-1) << "};"; - s.op->assert_0_indent(); + if (s.globals.size()>0) { + s.op->newline() << "static struct {"; + s.op->indent(1); + for (unsigned i=0; iemit_global (s.globals[i]); + } + s.op->newline(-1) << "} global = {"; + s.op->newline(1); + for (unsigned i=0; iemit_global_init (s.globals[i]); + } + s.op->newline(-1) << "};"; + s.op->assert_0_indent(); + } for (map::iterator it = s.functions.begin(); it != s.functions.end(); it++) { -- cgit From cd1db1dd034141535648a66d9896db6c5e74dd9e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 4 Mar 2009 11:55:56 +0100 Subject: PR9919: Set last_stmt for array (scalar or statistical) assignments. * translate.cxx (visit_arrayindex): Update last_stmt. --- translate.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 655937d7..23a24100 100644 --- a/translate.cxx +++ b/translate.cxx @@ -3882,7 +3882,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e) assert (rvalue->type == pe_long); mapvar mvar = parent->getmap (array->referent, e->tok); - // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; + o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; o->newline() << mvar.add (idx, rvar) << ";"; res = rvar; // no need for these dummy assignments @@ -3892,7 +3892,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e) else { mapvar mvar = parent->getmap (array->referent, e->tok); - // o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; + o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";"; if (op != "=") // don't bother fetch slot if we will just overwrite it parent->c_assign (lvar, mvar.get(idx), e->tok); c_assignop (res, lvar, rvar, e->tok); -- cgit From bc9a523d505c604c187dd2e81be1e24ec877d1af Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 7 Mar 2009 12:11:45 -0500 Subject: Tweak tracepoint logic to run on tracepoint_synchronize_unregister()-less RHEL5 --- translate.cxx | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 23a24100..c679e0f1 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1236,6 +1236,11 @@ c_unparser::emit_module_init () o->newline() << getvar (v).fini(); } + // For any partially registered/unregistered kernel facilities. + o->newline() << "#ifdef STAPCONF_SYNCHRONIZE_SCHED"; + o->newline() << "synchronize_sched();"; + o->newline() << "#endif"; + o->newline() << "return rc;"; o->newline(-1) << "}\n"; } -- cgit From ee53a613180a780ea377b4f1c857aaeabcf44240 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 8 Mar 2009 22:30:03 -0400 Subject: Check pending_interrupts more frequently during unwindsyms (pass 3) processing --- translate.cxx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index c679e0f1..b2ba5c72 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4458,6 +4458,9 @@ dump_unwindsyms (Dwfl_Module *m, string modname = name; + if (pending_interrupts) + return DWARF_CB_ABORT; + // skip modules/files we're not actually interested in if (c->session.unwindsym_modules.find(modname) == c->session.unwindsym_modules.end()) return DWARF_CB_OK; -- cgit From e0a17418b9d12e2a95dc345e95080ba31a41677f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 9 Mar 2009 19:12:02 -0700 Subject: Let -DINTERRUPTIBLE=0 mask interrupts in probes Some time ago we loosened up the code for all probe types to allow interrupts during the handler. However, when probing something like kernel.trace("*"), you get a mix of probes in and out of the interrupt path, and it becomes much more common to have probes skipped due to interrupt reentrancy. The common_probe_entryfn_prologue and common_probe_entryfn_epilogue functions had an interruptible flag, but this was no longer used anywhere. I removed this flag, but then reused the logic to check an INTERRUPTIBLE macro instead. Now users can use -DINTERRUPTIBLE=0 to prevent interrupt reentrancy in their script, at the cost of a bit more overhead to toggle the interrupt mask. --- translate.cxx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index b2ba5c72..17c37dc3 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4908,6 +4908,9 @@ translate_pass (systemtap_session& s) s.op->newline() << "#ifndef MINSTACKSPACE"; s.op->newline() << "#define MINSTACKSPACE 1024"; s.op->newline() << "#endif"; + s.op->newline() << "#ifndef INTERRUPTIBLE"; + s.op->newline() << "#define INTERRUPTIBLE 1"; + s.op->newline() << "#endif"; // Overload processing s.op->newline() << "#ifndef STP_OVERLOAD_INTERVAL"; -- cgit From 1bb61ae1fd02086560f5cd019db320b5a217ba05 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 16 Mar 2009 14:19:20 +0100 Subject: Add workaround for dwfl_module_build_id bug with elfutils < 0.140. * translate.cxx (dump_unwindsyms): Check elfutils version and whether build_id_vaddr < base, and if so add main_bias to address. --- translate.cxx | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 17c37dc3..f4c28536 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4497,17 +4497,35 @@ dump_unwindsyms (Dwfl_Module *m, // see https://bugzilla.redhat.com/show_bug.cgi?id=465872 // and http://sourceware.org/ml/systemtap/2008-q4/msg00579.html #ifdef _ELFUTILS_PREREQ -#if _ELFUTILS_PREREQ(0,138) + #if _ELFUTILS_PREREQ(0,138) // Let's standardize to the buggy "end of build-id bits" behavior. build_id_vaddr += build_id_len; + #endif + #if !_ELFUTILS_PREREQ(0,141) + #define NEED_ELFUTILS_BUILDID_WORKAROUND + #endif +#else + #define NEED_ELFUTILS_BUILDID_WORKAROUND #endif + + // And check for another workaround needed. + // see https://bugzilla.redhat.com/show_bug.cgi?id=489439 + // and http://sourceware.org/ml/systemtap/2009-q1/msg00513.html +#ifdef NEED_ELFUTILS_BUILDID_WORKAROUND + if (build_id_vaddr < base && dwfl_module_relocations (m) == 1) + { + GElf_Addr main_bias; + dwfl_module_getelf (m, &main_bias); + build_id_vaddr += main_bias; + } #endif - if (c->session.verbose > 1) { - clog << "Found build-id in " << name - << ", length " << build_id_len; - clog << ", end at 0x" << hex << build_id_vaddr - << dec << endl; - } + if (c->session.verbose > 1) + { + clog << "Found build-id in " << name + << ", length " << build_id_len; + clog << ", end at 0x" << hex << build_id_vaddr + << dec << endl; + } } // Look up the relocation basis for symbols -- cgit From 30cb532a560ed152b86506b80490e99195970271 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 17 Mar 2009 13:50:33 +0100 Subject: Get the canonical path of the main file for comparison at runtime. When given directly by the user through -d or in case of the kernel name and path might differ. path should be used for matching. * runtime/sym.h (_stp_module): Add path field. * runtime/task_finder.c (__stp_tf_vm_cb): Use module path to compare vm_path. * translate.cxx (dump_unwindsyms): Output canonical path. --- translate.cxx | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index f4c28536..377a11fb 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4700,6 +4700,15 @@ dump_unwindsyms (Dwfl_Module *m, c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n"; c->output << ".name = " << lex_cast_qstring (modname) << ", \n"; + + // Get the canonical path of the main file for comparison at runtime. + // When given directly by the user through -d or in case of the kernel + // name and path might differ. path should be used for matching. + const char *mainfile; + dwfl_module_info (m, NULL, NULL, NULL, NULL, NULL, &mainfile, NULL); + mainfile = canonicalize_file_name(mainfile); + c->output << ".path = " << lex_cast_qstring (mainfile) << ",\n"; + c->output << ".dwarf_module_base = 0x" << hex << base << dec << ", \n"; if (unwind != NULL) -- cgit