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 From 9c73606142525f521a44c4907832b2d1e1f3c659 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 20 Mar 2009 16:30:02 -0400 Subject: PR9967: don't count -DINTERRUPTIBLE=1 reentrancy against MAXSKIPPED * tapsets.cxx (common_probe_entryfn_prologue): Become conditional on !INTERRUPTIBLE. * translate.cxx (emit_module_exit): Still print skipped_count_reentrant with -t, even if skipped_count was zero. --- translate.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 377a11fb..e7c23672 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1360,9 +1360,10 @@ c_unparser::emit_module_exit () o->newline() << "#endif"; } - // print final error/reentrancy counts if non-zero + // print final error/skipped counts if non-zero o->newline() << "if (atomic_read (& skipped_count) || " - << "atomic_read (& error_count)) {"; + << "atomic_read (& error_count) || " + << "atomic_read (& skipped_count_reentrant)) {"; // PR9967 o->newline(1) << "_stp_warn (\"Number of errors: %d, " << "skipped probes: %d\\n\", " << "(int) atomic_read (& error_count), " -- cgit From 11dc6a07aa2aa1c7da1738c20cbc5c19f878374b Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 20 Mar 2009 19:13:45 -0400 Subject: fix build regression w/o -t * translate.cxx (emit_common_header): Always emit atomic_t skipped_* counters. --- translate.cxx | 2 -- 1 file changed, 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index e7c23672..40bb82c2 100644 --- a/translate.cxx +++ b/translate.cxx @@ -867,12 +867,10 @@ c_unparser::emit_common_header () o->newline() << "static atomic_t session_state = ATOMIC_INIT (STAP_SESSION_STARTING);"; o->newline() << "static atomic_t error_count = ATOMIC_INIT (0);"; o->newline() << "static atomic_t skipped_count = ATOMIC_INIT (0);"; - o->newline() << "#ifdef STP_TIMING"; o->newline() << "static atomic_t skipped_count_lowstack = ATOMIC_INIT (0);"; o->newline() << "static atomic_t skipped_count_reentrant = ATOMIC_INIT (0);"; o->newline() << "static atomic_t skipped_count_uprobe_reg = ATOMIC_INIT (0);"; o->newline() << "static atomic_t skipped_count_uprobe_unreg = ATOMIC_INIT (0);"; - o->newline() << "#endif"; o->newline(); o->newline() << "struct context {"; o->newline(1) << "atomic_t busy;"; -- cgit From 148f987f1bbc4a8fe23012a56bf89bb9fc69beb9 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 24 Mar 2009 15:15:10 -0400 Subject: accelerate pass-3 symbol/unwind generation * translate.cxx (emit_symbol_data): Abort dwfl_getmodules loop as soon as we run out of modules we're looking for. --- translate.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 40bb82c2..798d52fe 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4826,7 +4826,7 @@ emit_symbol_data (systemtap_session& s) if (pending_interrupts) return; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } - while (off > 0); + while (off > 0 && !ctx.undone_unwindsym_modules.empty()); dwfl_assert("dwfl_getmodules", off == 0); } dwfl_end(dwfl); @@ -4864,7 +4864,7 @@ emit_symbol_data (systemtap_session& s) if (pending_interrupts) return; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } - while (off > 0); + while (off > 0 && !ctx.undone_unwindsym_modules.empty()); dwfl_assert("dwfl_getmodules", off == 0); } dwfl_end(dwfl); -- cgit From 5d6b014268ca47386ef92525b8669429dec6e49c Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 24 Mar 2009 16:41:31 -0400 Subject: further accelerate pass-3 symbol/unwind process, skip one more iteration --- translate.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 798d52fe..55b266bf 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4824,9 +4824,10 @@ emit_symbol_data (systemtap_session& s) do { if (pending_interrupts) return; + if (ctx.undone_unwindsym_modules.empty()) return; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } - while (off > 0 && !ctx.undone_unwindsym_modules.empty()); + while (off > 0); dwfl_assert("dwfl_getmodules", off == 0); } dwfl_end(dwfl); @@ -4862,9 +4863,10 @@ emit_symbol_data (systemtap_session& s) do { if (pending_interrupts) return; + if (ctx.undone_unwindsym_modules.empty()) return; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } - while (off > 0 && !ctx.undone_unwindsym_modules.empty()); + while (off > 0); dwfl_assert("dwfl_getmodules", off == 0); } dwfl_end(dwfl); -- cgit From c87193cfb18258abbad947d009e6ca0bd2d5e0cf Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Tue, 24 Mar 2009 19:14:57 -0400 Subject: brown paper bag fix for commit 5d6b0142 return != break --- translate.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 55b266bf..0b81d9bb 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4824,7 +4824,7 @@ emit_symbol_data (systemtap_session& s) do { if (pending_interrupts) return; - if (ctx.undone_unwindsym_modules.empty()) return; + if (ctx.undone_unwindsym_modules.empty()) break; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } while (off > 0); @@ -4863,7 +4863,7 @@ emit_symbol_data (systemtap_session& s) do { if (pending_interrupts) return; - if (ctx.undone_unwindsym_modules.empty()) return; + if (ctx.undone_unwindsym_modules.empty()) break; off = dwfl_getmodules (dwfl, &dump_unwindsyms, (void *) &ctx, 0); } while (off > 0); -- cgit From 432f054fc20511d487d18234b6408b5df89a8c4d Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 27 Mar 2009 11:54:42 -0400 Subject: PR10000: emit _stp_relocate* calculations correctly for kernel/module global $data * translate.cxx (dump_unwindsyms): Also emit STT_OBJECT symbols, therefore .data etc. sections into stap-symbols.h. * tapsets.cxx (iterate_over_modules): Omit a dwfl_getmodules() RC-checking assertion that blocked meaningful $context var error messages. (dwflpp::emit_address): Bypass dwfl_module_relocate_address() for kernel symbols as it has been unreliable; subtract sess.sym_stext manually. * testsuite/buildok/seventeen.stp: Extend test with module $global. --- translate.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 0b81d9bb..47fffd1e 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4564,7 +4564,7 @@ dump_unwindsyms (Dwfl_Module *m, // 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; + clog << "Found kernel _stext extra offset 0x" << hex << extra_offset << dec << endl; } // We only need the function symbols to identify kernel-mode @@ -4572,8 +4572,9 @@ dump_unwindsyms (Dwfl_Module *m, // These fake absolute addresses occur in some older i386 // kernels to indicate they are vDSO symbols, not real // functions in the kernel. - if (GELF_ST_TYPE (sym.st_info) == STT_FUNC && - ! (sym.st_shndx == SHN_UNDEF || sym.st_shndx == SHN_ABS)) + if ((GELF_ST_TYPE (sym.st_info) == STT_FUNC || + GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: also need .data + && !(sym.st_shndx == SHN_UNDEF || sym.st_shndx == SHN_ABS)) { Dwarf_Addr sym_addr = sym.st_value; const char *secname = NULL; -- cgit From dcfd7fed7088871f46d9da7183e485877fb2d81f Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Wed, 1 Apr 2009 22:50:47 -0400 Subject: PR10019: --skip-badvars to suppress run-time memory errors too * NEWS: Note this change. * hash.cxx (find_script_hash): Add s.skip_badvars into hash. * translate.cxx (translate_pass): Emit STP_SKIP_BADVARS. * runtime/loc2c-runtime.h (DEREF_FAULT, STORE_DEREF_FAULT): Provide dummy implementation if STP_SKIP_BADVARS. --- translate.cxx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 47fffd1e..9085349e 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4955,6 +4955,8 @@ translate_pass (systemtap_session& s) s.op->newline() << "#define STP_OVERLOAD"; s.op->newline() << "#endif"; + s.op->newline() << "#define STP_SKIP_BADVARS " << (s.skip_badvars ? 1 : 0); + if (s.bulk_mode) s.op->newline() << "#define STP_BULKMODE"; -- cgit From 093421c6ba933754aa52cf6399aae5b8f86d86d9 Mon Sep 17 00:00:00 2001 From: William Cohen Date: Thu, 2 Apr 2009 17:41:20 -0400 Subject: Reorder includes so regs.c and regs-ia64.c included before task_finder.c. --- translate.cxx | 2 -- 1 file changed, 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 9085349e..cab37487 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4967,9 +4967,7 @@ translate_pass (systemtap_session& s) s.op->newline() << "#define STP_PERFMON"; s.op->newline() << "#include \"runtime.h\""; - s.op->newline() << "#include \"regs.c\""; s.op->newline() << "#include \"stack.c\""; - s.op->newline() << "#include \"regs-ia64.c\""; s.op->newline() << "#include \"stat.c\""; s.op->newline() << "#include "; s.op->newline() << "#include "; -- cgit From 3e3bd7b6b9dd2ba282990f39d60e3ad5ecfec023 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 6 Apr 2009 16:11:30 -0700 Subject: PR10026: Read marker/tracepoint args directly We already stash the context variables for markers and tracepoints into the locals for the probe body, but then we were using separate functions to read those locals for each particular probe body. This patch instead teaches the unparser how to emit the local name directly for those context variables. The resulting code from the translator is much simpler now. --- translate.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index cab37487..c42097bb 100644 --- a/translate.cxx +++ b/translate.cxx @@ -918,6 +918,7 @@ c_unparser::emit_common_header () ostringstream oss; oss << "c->statp = & time_" << dp->basest()->name << ";" << endl; // -t anti-dupe oss << "# needs_global_locks: " << dp->needs_global_locks () << endl; + dp->print_dupe_stamp (oss); dp->body->print(oss); // NB: dependent probe conditions *could* be listed here, but don't need to be. // That's because they're only dependent on the probe body, which is already @@ -1507,6 +1508,7 @@ c_unparser::emit_probe (derived_probe* v) // be very different with or without -t. oss << "c->statp = & time_" << v->basest()->name << ";" << endl; + v->print_dupe_stamp (oss); v->body->print(oss); // Since the generated C changes based on whether or not the probe @@ -3488,7 +3490,10 @@ c_unparser_assignment::visit_symbol (symbol *e) void c_unparser::visit_target_symbol (target_symbol* e) { - throw semantic_error("cannot translate general target-symbol expression", e->tok); + if (!e->probe_context_var.empty()) + o->line() << "l->" << e->probe_context_var; + else + throw semantic_error("cannot translate general cast expression", e->tok); } -- cgit From dc31eb39ab70d9d6b81d1ab02fd49795a4d8f2d0 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 8 Apr 2009 12:35:01 +0200 Subject: Omit symbols that have suspicious addresses (before base) from symbol table. * translate.cxx (dump_unwindsyms): Filter out sym.st_value < base values. --- translate.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index c42097bb..3442703d 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4576,10 +4576,13 @@ dump_unwindsyms (Dwfl_Module *m, // PC's, so we omit undefined or "fake" absolute addresses. // These fake absolute addresses occur in some older i386 // kernels to indicate they are vDSO symbols, not real - // functions in the kernel. + // functions in the kernel. We also omit symbols that have + // suspicious addresses (before base). if ((GELF_ST_TYPE (sym.st_info) == STT_FUNC || GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: also need .data - && !(sym.st_shndx == SHN_UNDEF || sym.st_shndx == SHN_ABS)) + && !(sym.st_shndx == SHN_UNDEF + || sym.st_shndx == SHN_ABS + || sym.st_value < base)) { Dwarf_Addr sym_addr = sym.st_value; const char *secname = NULL; -- cgit From d6377d4452bb469ea97dc6747cd02cfb1df4af27 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 9 Apr 2009 23:18:46 +0200 Subject: Cleanup symbol table sanity checking. * translate.cxx (dump_unwindsyms): Get and check against module end, only check STT_FUNC && SHN_ABS for kernel, check shndxp for non-allocated section. --- translate.cxx | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 3442703d..a22e9a5b 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4486,7 +4486,7 @@ dump_unwindsyms (Dwfl_Module *m, // In the future, we'll also care about data symbols. int syments = dwfl_module_getsymtab(m); - assert(syments); + dwfl_assert ("Getting symbol table for " + modname, syments >= 0); //extract build-id from debuginfo file int build_id_len = 0; @@ -4532,6 +4532,10 @@ dump_unwindsyms (Dwfl_Module *m, } } + // Use end as sanity check when resolving symbol addresses. + Dwarf_Addr end; + dwfl_module_info (m, NULL, NULL, &end, NULL, NULL, NULL, NULL); + // Look up the relocation basis for symbols int n = dwfl_module_relocations (m); @@ -4546,10 +4550,11 @@ dump_unwindsyms (Dwfl_Module *m, Dwarf_Addr extra_offset = 0; - for (int i = 1 /* XXX: why not 0? */ ; i < syments; ++i) + for (int i = 0; i < syments; ++i) { GElf_Sym sym; - const char *name = dwfl_module_getsym(m, i, &sym, NULL); + GElf_Word shndxp; + const char *name = dwfl_module_getsym(m, i, &sym, &shndxp); if (name) { // NB: Yey, we found the kernel's _stext value. @@ -4572,17 +4577,15 @@ dump_unwindsyms (Dwfl_Module *m, clog << "Found kernel _stext extra offset 0x" << hex << extra_offset << dec << endl; } - // We only need the function symbols to identify kernel-mode - // PC's, so we omit undefined or "fake" absolute addresses. - // These fake absolute addresses occur in some older i386 - // kernels to indicate they are vDSO symbols, not real - // functions in the kernel. We also omit symbols that have - // suspicious addresses (before base). + // We are only interested in "real" symbols. + // We omit symbols that have suspicious addresses (before base, + // or after end). if ((GELF_ST_TYPE (sym.st_info) == STT_FUNC || GELF_ST_TYPE (sym.st_info) == STT_OBJECT) // PR10000: also need .data - && !(sym.st_shndx == SHN_UNDEF - || sym.st_shndx == SHN_ABS - || sym.st_value < base)) + && !(sym.st_shndx == SHN_UNDEF // Value undefined, + || shndxp == (GElf_Word) -1 // in a non-allocated section, + || sym.st_value >= end // beyond current module, + || sym.st_value < base)) // before first section. { Dwarf_Addr sym_addr = sym.st_value; const char *secname = NULL; @@ -4607,6 +4610,16 @@ dump_unwindsyms (Dwfl_Module *m, { // This is a symbol within a (possibly relocatable) // kernel image. + + // We only need the function symbols to identify kernel-mode + // PC's, so we omit undefined or "fake" absolute addresses. + // These fake absolute addresses occur in some older i386 + // kernels to indicate they are vDSO symbols, not real + // functions in the kernel. We also omit symbols that have + if (GELF_ST_TYPE (sym.st_info) == STT_FUNC + && sym.st_shndx == SHN_ABS) + continue; + secname = "_stext"; // NB: don't subtract session.sym_stext, which could be inconveniently NULL. // Instead, sym_addr will get compensated later via extra_offset. @@ -4666,10 +4679,10 @@ dump_unwindsyms (Dwfl_Module *m, // There would be only a small benefit to warning. A user // likely can't do anything about this; backtraces for the // affected module would just get all icky heuristicy. -#if 0 - c->session.print_warning ("No unwind data for " + modname - + ", " + dwfl_errmsg (-1)); -#endif + // So only report in verbose mode. + if (c->session.verbose > 2) + c->session.print_warning ("No unwind data for " + modname + + ", " + dwfl_errmsg (-1)); } for (unsigned secidx = 0; secidx < seclist.size(); secidx++) -- cgit From 60ad8ebae62f472a9f089f51053a2d0d66c67a95 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 14 Apr 2009 19:30:56 +0200 Subject: Keep track of relocation section sizes. * runtime/sym.h (_stp_section): Add size field. * translate.cxx (dump_unwindsyms): Get start of module address space, turn seclist into vector of secname, size pairs, track relocation section size, or add module address range if no sections, output size in _stp_section list. --- translate.cxx | 58 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index a22e9a5b..d81287ee 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4532,9 +4532,14 @@ dump_unwindsyms (Dwfl_Module *m, } } - // Use end as sanity check when resolving symbol addresses. - Dwarf_Addr end; - dwfl_module_info (m, NULL, NULL, &end, NULL, NULL, NULL, NULL); + // 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. + // Use end as sanity check when resolving symbol addresses and to + // calculate size for .dynamic and .absolute sections. + const char *mainfile; + Dwarf_Addr start, end; + dwfl_module_info (m, NULL, &start, &end, NULL, NULL, &mainfile, NULL); // Look up the relocation basis for symbols int n = dwfl_module_relocations (m); @@ -4545,7 +4550,8 @@ dump_unwindsyms (Dwfl_Module *m, // XXX: unfortunate duplication with tapsets.cxx:emit_address() typedef map addrmap_t; // NB: plain map, sorted by address - vector seclist; // encountered relocation bases (section names) + vector > seclist; // encountered relocation bases + // (section names and sizes) map addrmap; // per-relocation-base sorted addrmap Dwarf_Addr extra_offset = 0; @@ -4588,11 +4594,11 @@ dump_unwindsyms (Dwfl_Module *m, || sym.st_value < base)) // before first section. { Dwarf_Addr sym_addr = sym.st_value; + Dwarf_Addr save_addr = sym_addr; const char *secname = NULL; 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); @@ -4645,10 +4651,31 @@ dump_unwindsyms (Dwfl_Module *m, // Compute our section number unsigned secidx; for (secidx=0; secidxsh_size; + } + seclist.push_back (make_pair(secname,size)); + } (addrmap[secidx])[sym_addr] = name; } @@ -4709,12 +4736,17 @@ dump_unwindsyms (Dwfl_Module *m, } c->output << "static struct _stp_section _stp_module_" << stpmod_idx<< "_sections[] = {\n"; + // For the kernel, executables (ET_EXEC) or shared libraries (ET_DYN) + // there is just one section that covers the whole address space of + // the module. For kernel modules (ET_REL) there can be multiple + // sections that get relocated separately. for (unsigned secidx = 0; secidx < seclist.size(); secidx++) { c->output << "{\n" - << ".name = " << lex_cast_qstring(seclist[secidx]) << ",\n" + << ".name = " << lex_cast_qstring(seclist[secidx].first) << ",\n" + << ".size = 0x" << hex << seclist[secidx].second << dec << ",\n" << ".symbols = _stp_module_" << stpmod_idx << "_symbols_" << secidx << ",\n" - << ".num_symbols = sizeof(_stp_module_" << stpmod_idx << "_symbols_" << secidx << ")/sizeof(struct _stp_symbol)\n" + << ".num_symbols = " << addrmap[secidx].size() << "\n" << "},\n"; } c->output << "};\n"; @@ -4722,11 +4754,6 @@ 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"; @@ -4861,7 +4888,8 @@ emit_symbol_data (systemtap_session& s) { NULL, /* dwfl_linux_kernel_find_elf, */ dwfl_standard_find_debuginfo, - dwfl_offline_section_address, + NULL, /* ET_REL not supported for user space, only ET_EXEC and ET_DYN. + dwfl_offline_section_address, */ (char **) & debuginfo_path }; -- cgit From 62d950bbff7f29156f6dbd0bcfa1fd4ae65cca38 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 19 Apr 2009 14:24:20 +0200 Subject: Micro-optimization: no-modules translate pass 3 case. Saves 250ms in the unlikely case there are no modules needed. * translate.cxx (emit_symbol_data_done): New function. (emit_symbol_data): Call emit_symbol_data_done immediately when no module data is needed. --- translate.cxx | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index d81287ee..46fea6e7 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4818,6 +4818,7 @@ dump_unwindsyms (Dwfl_Module *m, // Emit symbol table & unwind data, plus any calls needed to register // them with the runtime. +void emit_symbol_data_done (unwindsym_dump_context*, systemtap_session&); void emit_symbol_data (systemtap_session& s) @@ -4830,6 +4831,14 @@ emit_symbol_data (systemtap_session& s) unwindsym_dump_context ctx = { s, kallsyms_out, 0, s.unwindsym_modules }; + // Micro optimization, mainly to speed up tiny regression tests + // using just begin probe. + if (s.unwindsym_modules.size () == 0) + { + emit_symbol_data_done(&ctx, s); + return; + } + // XXX: copied from tapsets.cxx dwflpp::, sadly static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); @@ -4922,20 +4931,25 @@ emit_symbol_data (systemtap_session& s) dwfl_end(dwfl); } + emit_symbol_data_done (&ctx, s); +} +void +emit_symbol_data_done (unwindsym_dump_context *ctx, systemtap_session& s) +{ // Print out a definition of the runtime's _stp_modules[] globals. - kallsyms_out << "\n"; - kallsyms_out << "static struct _stp_module *_stp_modules [] = {\n"; - for (unsigned i=0; ioutput << "\n"; + ctx->output << "static struct _stp_module *_stp_modules [] = {\n"; + for (unsigned i=0; istp_module_index; i++) { - kallsyms_out << "& _stp_module_" << i << ",\n"; + ctx->output << "& _stp_module_" << i << ",\n"; } - kallsyms_out << "};\n"; - kallsyms_out << "static unsigned _stp_num_modules = " << ctx.stp_module_index << ";\n"; + ctx->output << "};\n"; + ctx->output << "static unsigned _stp_num_modules = " << ctx->stp_module_index << ";\n"; // Some nonexistent modules may have been identified with "-d". Note them. - for (set::iterator it = ctx.undone_unwindsym_modules.begin(); - it != ctx.undone_unwindsym_modules.end(); + for (set::iterator it = ctx->undone_unwindsym_modules.begin(); + it != ctx->undone_unwindsym_modules.end(); it ++) { s.print_warning ("missing unwind/symbol data for module '" + (*it) + "'"); -- cgit From 764b562f42c6ac7f02e0911cab47f87c827bf3bd Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Mon, 20 Apr 2009 12:56:51 +0200 Subject: fix a bug with %% in format strings * translate.cxx (c_unparser::visit_print_format): Always use _stp_printf if a format string contains "%%". Previously a format string with no arguments would always be printed with _stp_print. * testsuite/systemtap.printf/basic6.stp: New test for %% in format strings. * testsuite/systemtap.printf/basic6.exp: test driver * testsuite/systemtap.examples/grapher.stp: Remove workaround for "%%" literal problem. --- translate.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 46fea6e7..f7868ceb 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4172,7 +4172,8 @@ c_unparser::visit_print_format (print_format* e) int use_print = 0; string format_string = print_format::components_to_string(components); - if (tmp.size() == 0 || (tmp.size() == 1 && format_string == "%s")) + if ((tmp.size() == 0 && format_string.find("%%") == std::string::npos) + || (tmp.size() == 1 && format_string == "%s")) use_print = 1; else if (tmp.size() == 1 && e->args[0]->tok->type == tok_string -- cgit From eadbd95761af3c2815e1b36df5a7d18dd28112a4 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 22 Apr 2009 12:53:39 +0200 Subject: Simplify section size logic. * translate.cxx (dump_unwindsyms): Just check that dwfl_module_relocations() return more than 1 relocation section bases before calling dwfl_module_address_section(). --- translate.cxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index f7868ceb..3fa8857b 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4659,11 +4659,7 @@ dump_unwindsyms (Dwfl_Module *m, // absolute, dynamic or kernel have just one relocation // section, which covers the whole module address range. unsigned size; - if (secidx == 0 - && (n == 0 - || (n == 1 - && (strcmp(secname, ".dynamic") == 0 - || strcmp(secname, "_stext") == 0)))) + if (n <= 1) size = end - start; else { -- cgit From a12a8a3f1b4f7cdb743aeaaa5ee6c5a4ff28bb7e Mon Sep 17 00:00:00 2001 From: Rajan Arora Date: Wed, 22 Apr 2009 12:10:37 -0400 Subject: PR 9941: Add predicate function callback to check for an early abort * tapsets.cxx: Add dwfl_report_offline_predicate to check pending interrupts for an early abort. * tapsets.h: Declare it. * translate.cxx: Add callback to function call. --- translate.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 3fa8857b..87811e9f 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4871,7 +4871,7 @@ emit_symbol_data (systemtap_session& s) int rc = dwfl_linux_kernel_report_offline (dwfl, elfutils_kernel_path.c_str(), - NULL /* XXX: filtering callback */); + &dwfl_report_offline_predicate); dwfl_report_end (dwfl, NULL, NULL); if (rc == 0) // tolerate missing data; will warn user about it anyway { -- cgit