diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2010-04-13 15:11:15 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2010-04-13 15:11:15 -0400 |
commit | 17c0b69c7725db3c10e47b6fde7b9066588932d4 (patch) | |
tree | a9ba16d2cf9ed1927824a568204dc3ca192319bc /translate.cxx | |
parent | 7f7ef35a9e24055b96621f2b0f7c6405d4ae94fd (diff) | |
download | systemtap-steved-17c0b69c7725db3c10e47b6fde7b9066588932d4.tar.gz systemtap-steved-17c0b69c7725db3c10e47b6fde7b9066588932d4.tar.xz systemtap-steved-17c0b69c7725db3c10e47b6fde7b9066588932d4.zip |
PR11498: hang loose, don't freak, if facing giganormous debug_frame's.
* translate.cxx (MAX_UNWIND_TABLE_SIZE): Double to 6MB.
(dump_unwindsyms): Handle excess .eh_frame, .eh_frame_hdr,
.debug_frame sizes as suppressible warnings instead of
semantic_errors.
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/translate.cxx b/translate.cxx index c02c84a0..6fb335f6 100644 --- a/translate.cxx +++ b/translate.cxx @@ -31,8 +31,9 @@ extern "C" { // Max unwind table size (debug or eh) per module. Somewhat arbitrary // limit (a bit more than twice the .debug_frame size of my local -// vmlinux for 2.6.31.4-83.fc12.x86_64) -#define MAX_UNWIND_TABLE_SIZE (3 * 1024 * 1024) +// vmlinux for 2.6.31.4-83.fc12.x86_64). +// A larger value was recently found in a libxul.so build. +#define MAX_UNWIND_TABLE_SIZE (6 * 1024 * 1024) using namespace std; @@ -4884,64 +4885,76 @@ dump_unwindsyms (Dwfl_Module *m, &eh_frame_hdr, &eh_frame_hdr_len, &eh_frame_hdr_addr); if (debug_frame != NULL && debug_len > 0) { - if (debug_len > MAX_UNWIND_TABLE_SIZE) - throw semantic_error ("module debug unwind table size too big"); - c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n"; c->output << "static uint8_t _stp_module_" << stpmod_idx << "_debug_frame[] = \n"; c->output << " {"; - for (size_t i = 0; i < debug_len; i++) - { - int h = ((uint8_t *)debug_frame)[i]; - c->output << "0x" << hex << h << dec << ","; - if ((i + 1) % 16 == 0) - c->output << "\n" << " "; - } + if (debug_len > MAX_UNWIND_TABLE_SIZE) + { + if (! c->session.suppress_warnings) + c->session.print_warning ("skipping module " + modname + " debug_frame unwind table (too big: " + + lex_cast(debug_len) + " > " + lex_cast(MAX_UNWIND_TABLE_SIZE) + ")"); + } + else + for (size_t i = 0; i < debug_len; i++) + { + int h = ((uint8_t *)debug_frame)[i]; + c->output << "0x" << hex << h << dec << ","; + if ((i + 1) % 16 == 0) + c->output << "\n" << " "; + } c->output << "};\n"; c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n"; } if (eh_frame != NULL && eh_len > 0) { - if (eh_len > MAX_UNWIND_TABLE_SIZE) - throw semantic_error ("module eh unwind table size too big"); - c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n"; c->output << "static uint8_t _stp_module_" << stpmod_idx << "_eh_frame[] = \n"; c->output << " {"; - for (size_t i = 0; i < eh_len; i++) - { - int h = ((uint8_t *)eh_frame)[i]; - c->output << "0x" << hex << h << dec << ","; - if ((i + 1) % 16 == 0) - c->output << "\n" << " "; - } + if (eh_len > MAX_UNWIND_TABLE_SIZE) + { + if (! c->session.suppress_warnings) + c->session.print_warning ("skipping module " + modname + " eh_frame table (too big: " + + lex_cast(eh_len) + " > " + lex_cast(MAX_UNWIND_TABLE_SIZE) + ")"); + } + else + for (size_t i = 0; i < eh_len; i++) + { + int h = ((uint8_t *)eh_frame)[i]; + c->output << "0x" << hex << h << dec << ","; + if ((i + 1) % 16 == 0) + c->output << "\n" << " "; + } c->output << "};\n"; c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n"; } if (eh_frame_hdr != NULL && eh_frame_hdr_len > 0) { - if (eh_frame_hdr_len > MAX_UNWIND_TABLE_SIZE) - throw semantic_error ("module eh header size too big"); - c->output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n"; c->output << "static uint8_t _stp_module_" << stpmod_idx << "_eh_frame_hdr[] = \n"; c->output << " {"; - for (size_t i = 0; i < eh_frame_hdr_len; i++) - { - int h = ((uint8_t *)eh_frame_hdr)[i]; - c->output << "0x" << hex << h << dec << ","; - if ((i + 1) % 16 == 0) - c->output << "\n" << " "; - } + if (eh_frame_hdr_len > MAX_UNWIND_TABLE_SIZE) + { + if (! c->session.suppress_warnings) + c->session.print_warning ("skipping module " + modname + " eh_frame_hdr table (too big: " + + lex_cast(eh_frame_hdr_len) + " > " + lex_cast(MAX_UNWIND_TABLE_SIZE) + ")"); + } + else + for (size_t i = 0; i < eh_frame_hdr_len; i++) + { + int h = ((uint8_t *)eh_frame_hdr)[i]; + c->output << "0x" << hex << h << dec << ","; + if ((i + 1) % 16 == 0) + c->output << "\n" << " "; + } c->output << "};\n"; c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n"; } - + if (debug_frame == NULL && eh_frame == NULL) { // There would be only a small benefit to warning. A user |