diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | tapsets.cxx | 297 |
2 files changed, 169 insertions, 135 deletions
@@ -1,5 +1,11 @@ 2005-08-05 Frank Ch. Eigler <fche@elastic.org> + * tapsets.cxx (query_statement|function|cu|module): Add explicit + nested try/catch, since elfutils iteration seems to block + exception catching. + +2005-08-05 Frank Ch. Eigler <fche@elastic.org> + PR translator/1175 * translate.cxx (*): Added unlikely() markers to most emitted error checks. @@ -12,7 +18,6 @@ * systemtap.spec.in: Prereq kernel-devel, kernel-debuginfo, and not tcl. * tapsets.cxx: Make slightly less verbose. - * translate.cxx 2005-08-03 Graydon Hoare <graydon@redhat.com> diff --git a/tapsets.cxx b/tapsets.cxx index cd3764f0..887ddd60 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -998,85 +998,99 @@ dwarf_query::parse_function_spec(string & spec) static void query_statement(Dwarf_Addr stmt_addr, dwarf_query * q) { - // XXX: implement - if (q->has_relative) - throw semantic_error("incomplete: do not know how to interpret .relative", - q->base_probe->tok); - - q->results.push_back(new dwarf_derived_probe(*q, stmt_addr)); + try + { + // XXX: implement + if (q->has_relative) + throw semantic_error("incomplete: do not know how to interpret .relative", + q->base_probe->tok); + + q->results.push_back(new dwarf_derived_probe(*q, stmt_addr)); + } + catch (const semantic_error& e) + { + q->sess.print_error (e); + } } static int query_function(Dwarf_Func * func, void * arg) { - dwarf_query * q = static_cast<dwarf_query *>(arg); - // XXX: implement - if (q->has_callees) - throw semantic_error("incomplete: do not know how to interpret .callees", - q->base_probe->tok); - - if (q->has_label) - throw semantic_error("incomplete: do not know how to interpret .label", - q->base_probe->tok); - - q->dw.focus_on_function(func); - - Dwarf_Addr entry_addr; - - if (q->has_statement_str || q->has_function_str) + try { - if (q->dw.function_name_matches(q->function)) - { - // XXX: This code is duplicated below, but it's important - // for performance reasons to test things in this order. - - if (!q->dw.function_prologue_end(&entry_addr)) - { - if (q->sess.verbose) - clog << "WARNING: cannot find prologue-end PC for function " - << q->dw.function_name << endl; - return DWARF_CB_OK; - } - - // If this function's name matches a function or statement - // pattern, we use its entry pc, but we do not abort iteration - // since there might be other functions matching the pattern. - query_statement(entry_addr, q); - } + // XXX: implement + if (q->has_callees) + throw semantic_error("incomplete: do not know how to interpret .callees", + q->base_probe->tok); + + if (q->has_label) + throw semantic_error("incomplete: do not know how to interpret .label", + q->base_probe->tok); + + q->dw.focus_on_function(func); + + Dwarf_Addr entry_addr; + + if (q->has_statement_str || q->has_function_str) + { + if (q->dw.function_name_matches(q->function)) + { + // XXX: This code is duplicated below, but it's important + // for performance reasons to test things in this order. + + if (!q->dw.function_prologue_end(&entry_addr)) + { + if (q->sess.verbose) + clog << "WARNING: cannot find prologue-end PC for function " + << q->dw.function_name << endl; + return DWARF_CB_OK; + } + + // If this function's name matches a function or statement + // pattern, we use its entry pc, but we do not abort iteration + // since there might be other functions matching the pattern. + query_statement(entry_addr, q); + } + } + else + { + if (q->has_function_num || q->has_statement_num) + { + Dwarf_Addr query_addr = (q->has_function_num + ? q->function_num_val + : q->statement_num_val); + + // Adjust module-relative address to global + + if (q->has_module) + query_addr = q->dw.module_address_to_global(query_addr); + + if (q->dw.function_includes_global_addr(query_addr)) + { + + if (!q->dw.function_prologue_end(&entry_addr)) + { + if (false && q->sess.verbose) + clog << "WARNING: cannot find prologue-end PC for function " + << q->dw.function_name << endl; + return DWARF_CB_OK; + } + + query_statement(q->has_function_num ? entry_addr : query_addr, q); + return DWARF_CB_ABORT; + } + } + } + + return DWARF_CB_OK; } - else + catch (const semantic_error& e) { - if (q->has_function_num || q->has_statement_num) - { - Dwarf_Addr query_addr = (q->has_function_num - ? q->function_num_val - : q->statement_num_val); - - // Adjust module-relative address to global - - if (q->has_module) - query_addr = q->dw.module_address_to_global(query_addr); - - if (q->dw.function_includes_global_addr(query_addr)) - { - - if (!q->dw.function_prologue_end(&entry_addr)) - { - if (false && q->sess.verbose) - clog << "WARNING: cannot find prologue-end PC for function " - << q->dw.function_name << endl; - return DWARF_CB_OK; - } - - query_statement(q->has_function_num ? entry_addr : query_addr, q); - return DWARF_CB_ABORT; - } - } + q->sess.print_error (e); + return DWARF_CB_ABORT; } - - return DWARF_CB_OK; } static int @@ -1084,33 +1098,41 @@ query_cu (Dwarf_Die * cudie, void * arg) { dwarf_query * q = static_cast<dwarf_query *>(arg); - q->dw.focus_on_cu(cudie); - - // If we have enough information in the pattern to skip a CU - // and the CU does not match that information, return early. - if ((q->has_statement_str || q->has_function_str) - && (q->spec_type == function_file_and_line || - q->spec_type == function_and_file) - && (!q->dw.cu_name_matches(q->file))) - return DWARF_CB_OK; - - if (q->has_statement_str - && (q->spec_type == function_file_and_line) - && q->dw.cu_name_matches(q->file)) + try { - // If we have a complete file:line statement - // functor (not function functor) landing on - // this CU, we can look up a specific address - // for the statement, and skip scanning - // the remaining functions within the CU. - query_statement(q->dw.global_addr_of_line_in_cu(q->line), q); + q->dw.focus_on_cu(cudie); + + // If we have enough information in the pattern to skip a CU + // and the CU does not match that information, return early. + if ((q->has_statement_str || q->has_function_str) + && (q->spec_type == function_file_and_line || + q->spec_type == function_and_file) + && (!q->dw.cu_name_matches(q->file))) + return DWARF_CB_OK; + + if (q->has_statement_str + && (q->spec_type == function_file_and_line) + && q->dw.cu_name_matches(q->file)) + { + // If we have a complete file:line statement + // functor (not function functor) landing on + // this CU, we can look up a specific address + // for the statement, and skip scanning + // the remaining functions within the CU. + query_statement(q->dw.global_addr_of_line_in_cu(q->line), q); + } + else + { + // Otherwise we need to scan all the functions in this CU. + q->dw.iterate_over_functions(&query_function, q); + } + return DWARF_CB_OK; } - else + catch (const semantic_error& e) { - // Otherwise we need to scan all the functions in this CU. - q->dw.iterate_over_functions(&query_function, q); + q->sess.print_error (e); + return DWARF_CB_ABORT; } - return DWARF_CB_OK; } static int @@ -1119,56 +1141,63 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)), const char *name, Dwarf_Addr base, void *arg __attribute__ ((unused))) { - dwarf_query * q = static_cast<dwarf_query *>(arg); - q->dw.focus_on_module(mod); - - // If we have enough information in the pattern to skip a module and - // the module does not match that information, return early. - - if (q->has_kernel && !q->dw.module_name_matches(TOK_KERNEL)) - return DWARF_CB_OK; - - if (q->has_module && !q->dw.module_name_matches(q->module_val)) - return DWARF_CB_OK; - - if (q->has_function_num || q->has_statement_num) + try { - // If we have module("foo").function(0xbeef) or - // module("foo").statement(0xbeef), the address is relative - // to the start of the module, so we seek the function - // number plus the module's bias. - Dwarf_Addr addr; - if (q->has_function_num) - addr = q->function_num_val; - else - addr = q->statement_num_val; - - if (q->has_kernel) - q->dw.focus_on_cu_containing_global_address(addr); + q->dw.focus_on_module(mod); + + // If we have enough information in the pattern to skip a module and + // the module does not match that information, return early. + + if (q->has_kernel && !q->dw.module_name_matches(TOK_KERNEL)) + return DWARF_CB_OK; + + if (q->has_module && !q->dw.module_name_matches(q->module_val)) + return DWARF_CB_OK; + + if (q->has_function_num || q->has_statement_num) + { + // If we have module("foo").function(0xbeef) or + // module("foo").statement(0xbeef), the address is relative + // to the start of the module, so we seek the function + // number plus the module's bias. + Dwarf_Addr addr; + if (q->has_function_num) + addr = q->function_num_val; + else + addr = q->statement_num_val; + + if (q->has_kernel) + q->dw.focus_on_cu_containing_global_address(addr); + else + q->dw.focus_on_cu_containing_module_address(addr); + + q->dw.iterate_over_functions(&query_function, q); + } else - q->dw.focus_on_cu_containing_module_address(addr); - - q->dw.iterate_over_functions(&query_function, q); + { + // Otherwise if we have a function("foo") or statement("foo") + // specifier, we have to scan over all the CUs looking for + // the function in question + assert(q->has_function_str || q->has_statement_str); + q->dw.iterate_over_cus(&query_cu, q); + } + + // If we just processed the module "kernel", and the user asked for + // the kernel pattern, there's no need to iterate over any further + // modules + + if (q->has_kernel && q->dw.module_name_matches(TOK_KERNEL)) + return DWARF_CB_ABORT; + + return DWARF_CB_OK; } - else + catch (const semantic_error& e) { - // Otherwise if we have a function("foo") or statement("foo") - // specifier, we have to scan over all the CUs looking for - // the function in question - assert(q->has_function_str || q->has_statement_str); - q->dw.iterate_over_cus(&query_cu, q); + q->sess.print_error (e); + return DWARF_CB_ABORT; } - - // If we just processed the module "kernel", and the user asked for - // the kernel pattern, there's no need to iterate over any further - // modules - - if (q->has_kernel && q->dw.module_name_matches(TOK_KERNEL)) - return DWARF_CB_ABORT; - - return DWARF_CB_OK; } struct |