diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | tapsets.cxx | 39 | ||||
-rwxr-xr-x | testsuite/semko/thirtytwo.stp | 4 |
3 files changed, 50 insertions, 0 deletions
@@ -1,3 +1,10 @@ +2005-11-03 Frank Ch. Eigler <fche@elastic.org> + + PR 1329. + * tapsets.cxx (dwarf_query::add_probe_point): Look up section name + containing given address. Skip request if it came from .init.*. + * testsuite/semko/thirtytwo.stp: New test. + 2005-11-02 Martin Hunt <hunt@redhat.com> * Makefile.am (EXTRA_DIST): Add session.h. diff --git a/tapsets.cxx b/tapsets.cxx index f9969434..ede2092f 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1635,6 +1635,7 @@ target_variable_flavour_calculating_visitor::visit_target_symbol (target_symbol } } + void dwarf_query::add_probe_point(string const & funcname, char const * filename, @@ -1644,6 +1645,44 @@ dwarf_query::add_probe_point(string const & funcname, { dwarf_derived_probe *probe = NULL; + // Check whether the given address points into an .init section, + // which will have been unmapped by the kernel by the time we get to + // insert the probe. In this case, just ignore this call. + Dwarf_Addr baseaddr; + Elf* elf = dwfl_module_getelf (dw.module, & baseaddr); + Dwarf_Addr rel_addr = addr - baseaddr; + if (elf) + { + // Iterate through section headers to find which one + // contains the given rel_addr. + Elf_Scn* scn = 0; + size_t shstrndx; + dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); + while (scn = elf_nextscn (elf, scn)) + { + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); + if (! shdr) continue; // XXX error? + + // check for address inclusion + GElf_Addr start = shdr->sh_addr; + GElf_Addr end = start + shdr->sh_size; + if (! (rel_addr >= start && rel_addr < end)) + continue; + + // check for section name + const char* name = elf_strptr (elf, shstrndx, shdr->sh_name); + if (name && strncmp (name, ".init.", 6) == 0) + { + if (sess.verbose) + clog << "skipping function '" << funcname << "' base 0x" + << hex << addr << dec << " is within section '" + << name << "'" << endl; + return; + } + } + } + if (probe_has_no_target_variables) { assert(probe_flavours.size() == 1); diff --git a/testsuite/semko/thirtytwo.stp b/testsuite/semko/thirtytwo.stp new file mode 100755 index 00000000..f2fae56d --- /dev/null +++ b/testsuite/semko/thirtytwo.stp @@ -0,0 +1,4 @@ +#! stap -p2 + +// should fail since init_setup should be skipped because it is in .init.text +probe kernel.function("init_setup") { } |