diff options
author | fche <fche> | 2006-11-26 23:28:15 +0000 |
---|---|---|
committer | fche <fche> | 2006-11-26 23:28:15 +0000 |
commit | c931ec8ab64f5b6667e28b0f64338643d4b9ed03 (patch) | |
tree | 80b739d8a696c6acc3ce26853ebc9c8de603c52f /tapsets.cxx | |
parent | cc7d24cd109128d558445507e508f5b43906ef16 (diff) | |
download | systemtap-steved-c931ec8ab64f5b6667e28b0f64338643d4b9ed03.tar.gz systemtap-steved-c931ec8ab64f5b6667e28b0f64338643d4b9ed03.tar.xz systemtap-steved-c931ec8ab64f5b6667e28b0f64338643d4b9ed03.zip |
2006-11-26 Frank Ch. Eigler <fche@redhat.com>
PRs 2685, 3596, toward 2725.
* tapsets.cxx (common_probe_entryfn_prologue): Skip probe on
insufficient stack.
(build_blacklist): Add a slew of lock-related calls.
(query_module): Check for debuginfo architecture match.
* translate.cxx (translate_pass): Add default MINSTACKSPACE.
* configure.ac: Link stap with -lebl too.
* configure: Regenerated.
* stap.1.in: Document MINSTACKSPACE parameter.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r-- | tapsets.cxx | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index 55a53cca..852ef378 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -29,6 +29,7 @@ extern "C" { #include <fcntl.h> #include <elfutils/libdwfl.h> #include <elfutils/libdw.h> +#include <elfutils/libebl.h> #include <dwarf.h> #include <elf.h> #include <obstack.h> @@ -174,6 +175,16 @@ common_probe_entryfn_prologue (translator_output* o, string statestr) o->newline() << "local_irq_save (flags);"; + // Check for enough free enough stack space + o->newline() << "if ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; + o->newline(1) << "< (THREAD_SIZE - MINSTACKSPACE - sizeof (struct task_struct))) {"; + o->newline() << "if (atomic_inc_return (& skipped_count) > MAXSKIPPED) {"; + o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);"; + o->newline() << "_stp_exit ();"; + o->newline(-1) << "}"; + o->newline() << "goto probe_epilogue;"; + o->newline(-1) << "}"; + o->newline() << "if (atomic_read (&session_state) != " << statestr << ")"; o->newline(1) << "goto probe_epilogue;"; o->indent(-1); @@ -717,7 +728,7 @@ struct dwflpp // NB: "rc == 0" means OK in this case - void dwfl_assert(string desc, int rc, string extra_msg = "") + static void dwfl_assert(string desc, int rc, string extra_msg = "") { string msg = "libdwfl failure (" + desc + "): "; if (rc < 0) msg += dwfl_errmsg (rc); @@ -2037,6 +2048,18 @@ dwarf_query::build_blacklist() blacklisted_probes.insert("unhandled_fault"); blacklisted_probes.insert("unknown_nmi_error"); + blacklisted_probes.insert("_read_trylock"); + blacklisted_probes.insert("_read_lock"); + blacklisted_probes.insert("_read_unlock"); + blacklisted_probes.insert("_write_trylock"); + blacklisted_probes.insert("_write_lock"); + blacklisted_probes.insert("_write_unlock"); + blacklisted_probes.insert("_spin_lock"); + blacklisted_probes.insert("_spin_lock_irqsave"); + blacklisted_probes.insert("_spin_trylock"); + blacklisted_probes.insert("_spin_unlock"); + blacklisted_probes.insert("_spin_unlock_irqrestore"); + // __switch_to is only disallowed on x86_64 if (sess.architecture == "x86_64") blacklisted_probes.insert("__switch_to"); @@ -2748,11 +2771,57 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), if (q->has_module && !q->dw.module_name_matches(q->module_val)) return DWARF_CB_OK; + // Validate the machine code in this elf file against the + // session machine. This is important, in case the wrong kind + // of debuginfo is being automagically processed by elfutils. + // Unfortunately, while we can tell i686 apart from x86-64, + // we can't help confusing i586 vs i686 (both EM_386). + + Dwarf_Addr _junk; + Elf* elf = dwfl_module_getelf (mod, &_junk); + Ebl* ebl = ebl_openbackend (elf); + int elf_machine = ebl_get_elfmachine (ebl); + const char* debug_filename = ""; + const char* main_filename = ""; + (void) dwfl_module_info (mod, NULL, NULL, + NULL, NULL, NULL, + & main_filename, + & debug_filename); + const string& sess_machine = q->sess.architecture; + string expect_machine; + switch (elf_machine) + { + case EM_386: expect_machine = "i686"; break; + case EM_X86_64: expect_machine = "x86_64"; break; + case EM_PPC: expect_machine = "ppc"; break; + case EM_PPC64: expect_machine = "ppc64"; break; + case EM_S390: expect_machine = "s390x"; break; + case EM_IA_64: expect_machine = "ia64"; break; + // XXX: fill in some more of these + default: expect_machine = "?"; break; + } + + if (! debug_filename) debug_filename = main_filename; + if (! debug_filename) debug_filename = name; + + if (sess_machine != expect_machine) + { + stringstream msg; + msg << "ELF machine " << expect_machine << " (code " << elf_machine + << ") mismatch with target " << sess_machine + << " in '" << debug_filename << "'"; + throw semantic_error(msg.str ()); + } + if (q->sess.verbose>2) clog << "focused on module '" << q->dw.module_name - << "' = [" << hex << q->dw.module_start + << " = [" << hex << q->dw.module_start << "-" << q->dw.module_end - << ", bias " << q->dw.module_bias << "]" << dec << "\n"; + << ", bias " << q->dw.module_bias << "]" << dec + << " file " << debug_filename + << " ELF machine " << expect_machine + << " (code " << elf_machine << ")" + << "\n"; if (q->has_inline_num || q->has_function_num || q->has_statement_num) { |