From c65358e84b38bc84951a4e3c5e8e4f3cace9f63e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 25 Jun 2009 23:07:17 +0200 Subject: PR10323 Some ustack exelib.exp tests fail with prelinked shared libs. For shared libraries (.dynamic sections) we need the eh frame section address offset. This is the sh_addr if the shared library isn't prelinked (since the base load address is zero in that case), otherwise it is the module start address minus the bias (which also works for the non-prelinked case). * translate.cxx (get_unwind_data): Adjust eh_addr for module start and bias if module isn't absolute (has no relocations). * testsuite/systemtap.exelib/ustack.tcl: Accept all prelink tests. --- testsuite/systemtap.exelib/ustack.tcl | 3 --- translate.cxx | 11 ++++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/testsuite/systemtap.exelib/ustack.tcl b/testsuite/systemtap.exelib/ustack.tcl index 07dcec10..b70b8334 100644 --- a/testsuite/systemtap.exelib/ustack.tcl +++ b/testsuite/systemtap.exelib/ustack.tcl @@ -7,9 +7,6 @@ lib: lib_func=lib_func lib: lib_func=lib_func lib: lib_func=lib_func} -# BUG XXX PR10323 skip all prelink scenarios for now. -if {[string match "*prelink*" "$testname"]} { return } - # Only run on make installcheck if {! [installtest_p]} { untested "ustack-$testname"; return } if {! [utrace_p]} { untested "ustack-$testname"; return } diff --git a/translate.cxx b/translate.cxx index cc634555..a0164661 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4438,13 +4438,13 @@ struct unwindsym_dump_context // Get the .debug_frame end .eh_frame sections for the given module. // Also returns the lenght of both sections when found, plus the section -// address of the eh_frame data. +// address (offset) of the eh_frame data. static void get_unwind_data (Dwfl_Module *m, void **debug_frame, void **eh_frame, size_t *debug_len, size_t *eh_len, Dwarf_Addr *eh_addr) { - Dwarf_Addr bias = 0; + Dwarf_Addr start, bias = 0; GElf_Ehdr *ehdr, ehdr_mem; GElf_Shdr *shdr, shdr_mem; Elf_Scn *scn; @@ -4452,6 +4452,7 @@ static void get_unwind_data (Dwfl_Module *m, Elf *elf; // fetch .eh_frame info preferably from main elf file. + dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL); elf = dwfl_module_getelf(m, &bias); ehdr = gelf_getehdr(elf, &ehdr_mem); scn = NULL; @@ -4464,7 +4465,11 @@ static void get_unwind_data (Dwfl_Module *m, data = elf_rawdata(scn, NULL); *eh_frame = data->d_buf; *eh_len = data->d_size; - *eh_addr = shdr->sh_addr; + // For ".dynamic" sections we want the offset, not absolute addr. + if (dwfl_module_relocations (m) > 0) + *eh_addr = shdr->sh_addr - start + bias; + else + *eh_addr = shdr->sh_addr; break; } } -- cgit From f0d57904d70d912ca3fc82eeaaacccdac0307a87 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 26 Jun 2009 16:36:58 +0200 Subject: PR10335 systemtap.base/strftime.exp hangs. This only happened if there was a lot of cruft in the testsuite dir since expect wasn't "draining" the output of the spawned ls command for some reason. Work around it by just using tcl file globs to match. * testsuite/systemtap.base/strftime.exp: Test with glob and file exists. --- testsuite/systemtap.base/strftime.exp | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/testsuite/systemtap.base/strftime.exp b/testsuite/systemtap.base/strftime.exp index ad9e471d..decd7a65 100644 --- a/testsuite/systemtap.base/strftime.exp +++ b/testsuite/systemtap.base/strftime.exp @@ -7,15 +7,9 @@ system "rm -f %*" set format %%%S_%T exec stap -o $format -we {probe begin {println("hello");exit()}} -spawn ls -1 -set ok 0 -expect { - -re {%([0-9][0-9])_[0-9][0-9]:[0-9][0-9]:\1} {incr ok} - eof { } -} -wait +set file [glob -nocomplain -types f %\[0-9\]\[0-9\]_\[0-9\]\[0-9\]:\[0-9\]\[0-9\]:\[0-9\]\[0-9\]] -if {$ok == 1} { +if {[llength $file] == 1} { pass "$test (%S and %T)" } else { fail "$test (%S and %T)" @@ -27,19 +21,8 @@ set format %%,%C,%Y,%y,%m,%d,%e,%F,%H,%I,%j,%k,%l,%M,%R,%u,%w set date1 [exec date +$format] # run stapio with strftime exec stap -o $format -we {probe begin {println("hello");exit()}} -# check whether stap outputs stapio pid -set date2 [exec date +$format] - -spawn ls -1 -set ok 0 -expect { - $date1 {incr ok} - $date2 {incr ok} - eof { } -} -wait -if {$ok == 1} { +if {[file exists $date1]} { pass "$test (except %S and %T)" } else { fail "$test (except %S and %T)" -- cgit From 0c3bfb1ef9f5415ec92afac94a72db5a827fa634 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Fri, 26 Jun 2009 14:28:46 -0400 Subject: Use_utrace_syscall_arg with sdt utrace probes to avoid i386 arg fetching problems. * tapsets.cxx (probe_table): Add is_uprobe and is_utrace. (probe_table::convert_probe): Use _utrace_syscall_arg. (sdt_var_expanding_visitor): Add utrace_probe. (sdt_var_expanding_visitor::visit_target_symbol): Use _utrace_syscall_arg. --- tapsets.cxx | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/tapsets.cxx b/tapsets.cxx index cd6bc28e..9d8dd51e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -672,6 +672,8 @@ struct dwarf_builder: public derived_probe_builder string & mark_name; string probe_name; probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw); + bool is_uprobe() {return probe_type == uprobe_type;}; + bool is_utrace() {return probe_type == utrace_type;}; bool get_next_probe(); void convert_probe(probe *new_base); void convert_location(probe *new_base, probe_point *new_location); @@ -849,9 +851,9 @@ dwarf_builder::probe_table::convert_probe (probe *new_base) betid->left = task_tid; functioncall *arg2tid = new functioncall; arg2tid->tok = new_base->body->tok; - arg2tid->function = "ulong_arg"; + arg2tid->function = "_utrace_syscall_arg"; arg2tid->tok = new_base->body->tok; - literal_number* littid = new literal_number(2); + literal_number* littid = new literal_number(1); littid->tok = new_base->body->tok; arg2tid->args.push_back(littid); @@ -862,9 +864,9 @@ dwarf_builder::probe_table::convert_probe (probe *new_base) // Generate: if (arg1 != mark("label")) next; functioncall *fc = new functioncall; - fc->function = "ulong_arg"; + fc->function = (probe_type == utrace_type) ? "_utrace_syscall_arg" : "ulong_arg"; fc->tok = new_base->body->tok; - literal_number* num = new literal_number(1); + literal_number* num = new literal_number((probe_type == utrace_type) ? 0 : 1); num->tok = new_base->body->tok; fc->args.push_back(num); @@ -3325,15 +3327,17 @@ dwarf_derived_probe_group::emit_module_exit (systemtap_session& s) struct sdt_var_expanding_visitor: public var_expanding_visitor { sdt_var_expanding_visitor(string & process_name, string & probe_name, - int arg_count, bool have_reg_args): + int arg_count, bool have_reg_args, bool utrace_probe): process_name (process_name), probe_name (probe_name), - have_reg_args (have_reg_args), arg_count (arg_count) + have_reg_args (have_reg_args), utrace_probe (utrace_probe), + arg_count (arg_count) { assert(!have_reg_args || (arg_count >= 0 && arg_count <= 10)); } string & process_name; string & probe_name; bool have_reg_args; + bool utrace_probe; int arg_count; void visit_target_symbol (target_symbol* e); @@ -3365,10 +3369,10 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) // First two args are hidden: 1. pointer to probe name 2. task id if (arg_count < 2) { - fc->function = "ulong_arg"; + fc->function = utrace_probe ? "_utrace_syscall_arg" : "ulong_arg"; fc->type = pe_long; fc->tok = e->tok; - literal_number* num = new literal_number(argno + 2); + literal_number* num = new literal_number(argno + (utrace_probe ? 1 : 2)); num->tok = e->tok; fc->args.push_back(num); } @@ -3379,9 +3383,9 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) binary_expression *be = new binary_expression; be->tok = e->tok; functioncall *get_arg1 = new functioncall; - get_arg1->function = "pointer_arg"; + get_arg1->function = utrace_probe ? "_utrace_syscall_arg" : "pointer_arg"; get_arg1->tok = e->tok; - literal_number* num = new literal_number(3); + literal_number* num = new literal_number((utrace_probe ? 2 : 3)); num->tok = e->tok; get_arg1->args.push_back(num); @@ -3453,7 +3457,7 @@ dwarf_builder::build(systemtap_session & sess, if (sess.verbose > 3) clog << "TOK_MARK: " << probe_table.mark_name << endl; - if (probe_table.probe_type == probe_table.uprobe_type) + if (probe_table.is_uprobe()) { do { @@ -3478,7 +3482,7 @@ dwarf_builder::build(systemtap_session & sess, // Now expand the local variables in the probe body sdt_var_expanding_visitor svv (module_name, probe_table.probe_name, - probe_table.probe_arg, false); + probe_table.probe_arg, false, false); new_base->body = svv.require (new_base->body); dwarf_query q(sess, new_base, new_location, *dw, parameters, finished_results); @@ -3518,7 +3522,8 @@ dwarf_builder::build(systemtap_session & sess, // Expand the local variables in the probe body sdt_var_expanding_visitor svv (module_name, probe_table.probe_name, - probe_table.probe_arg, true); + probe_table.probe_arg, true, + probe_table.is_utrace()); new_base->body = svv.require (new_base->body); probe_table.convert_location(new_base, new_location); derive_probes(sess, new_base, finished_results); -- cgit From 2fd285e65eb8e1f77cb5b70a1f81377896ad6b2c Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Fri, 26 Jun 2009 16:34:00 -0400 Subject: An i386 kprobe needs regparm(0) to access args. * tapsets.cxx (probe_table::convert_probe): Add regparm for kprobe. --- tapsets.cxx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tapsets.cxx b/tapsets.cxx index 9d8dd51e..765c2cd3 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -887,6 +887,23 @@ dwarf_builder::probe_table::convert_probe (probe *new_base) be->right = new literal_string(mark_name); is->condition = be; b->statements.insert(b->statements.begin(),(statement*) is); + +#ifdef __i386__ + if (probe_type == kprobe_type) + { + functioncall *rp = new functioncall; + rp->tok = new_base->body->tok; + rp->function = "regparm"; + rp->tok = new_base->body->tok; + literal_number* littid = new literal_number(0); + littid->tok = new_base->body->tok; + rp->args.push_back(littid); + expr_statement* es = new expr_statement; + es->tok = new_base->body->tok; + es->value = rp; + b->statements.insert(b->statements.begin(),(statement*) es); + } +#endif } -- cgit