From 8f497c23fd73345bd73b085a853f9c8be548715c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 24 Apr 2009 14:28:26 -0700 Subject: Tweak error message in kprobe.function registration --- tapsets.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 4ab61942..d16ae487 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8588,7 +8588,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline(1) << "sdp->registered_p = 0;"; s.op->newline() << "if (rc == -EINVAL)"; s.op->newline() << "{"; - s.op->newline() << " _stp_error (\"Error registering kprobe,possibly an incorrect name %s OR addr = %p, rc = %d \", sdp->symbol_string, sdp->address, rc);"; + s.op->newline() << " _stp_error (\"Error registering kprobe, possibly an incorrect name %s OR addr = %p, rc = %d \", sdp->symbol_string, sdp->address, rc);"; s.op->newline() << " atomic_set (&session_state, STAP_SESSION_ERROR);"; s.op->newline() << " goto out;"; s.op->newline() << "}"; -- cgit From 5badd4d0d1fc3f7dce2dc26a3ad5a69275ff07d2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 24 Apr 2009 18:07:12 -0700 Subject: Don't terminate when a dwarfless kprobe fails All of our other kprobe types will let the script continue after a registration failure, as per PR6749. The dwarfless kprobes should be no exception. Also, the way they were exiting was causing an unclean shutdown, so I added tests to badkprobe.exp to make sure that cleanup is always allowed to run. --- tapsets.cxx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index d16ae487..511289df 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8586,14 +8586,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline(-1) << "}"; s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe. s.op->newline(1) << "sdp->registered_p = 0;"; - s.op->newline() << "if (rc == -EINVAL)"; - s.op->newline() << "{"; - s.op->newline() << " _stp_error (\"Error registering kprobe, possibly an incorrect name %s OR addr = %p, rc = %d \", sdp->symbol_string, sdp->address, rc);"; - s.op->newline() << " atomic_set (&session_state, STAP_SESSION_ERROR);"; - s.op->newline() << " goto out;"; - s.op->newline() << "}"; - s.op->newline() << "else"; - s.op->newline() << "_stp_warn (\"probe %s for %s registration error (rc %d)\", probe_point, sdp->pp, rc);"; + s.op->newline() << "_stp_warn (\"probe %s registration error (rc %d)\", probe_point, rc);"; s.op->newline() << "rc = 0;"; // continue with other probes // XXX: shall we increment numskipped? s.op->newline(-1) << "}"; -- cgit From 46856d8d04167a05b62f8d3a480b2be7509fcf86 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 24 Apr 2009 18:37:35 -0700 Subject: Fill out the pp() for dwarfless kprobes --- tapsets.cxx | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 511289df..9a8524b1 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8350,11 +8350,33 @@ kprobe_derived_probe::kprobe_derived_probe (probe *base, #define USHRT_MAX 32767 #endif - // Expansion of $target variables in the probe body produces an error during translate phase + // Expansion of $target variables in the probe body produces an error during + // translate phase, since we're not using debuginfo + vector comps; + comps.push_back (new probe_point::component(TOK_KPROBE)); - if (has_return) - comps.push_back (new probe_point::component(TOK_RETURN)); + if (has_statement) + { + comps.push_back (new probe_point::component(TOK_STATEMENT, new literal_number(addr))); + comps.push_back (new probe_point::component(TOK_ABSOLUTE)); + } + else + { + size_t pos = name.find(':'); + if (pos != string::npos) + { + string module = name.substr(0, pos); + string function = name.substr(pos + 1); + comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module))); + comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(function))); + } + else + comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(name))); + + if (has_return) + comps.push_back (new probe_point::component(TOK_RETURN)); + } this->sole_location()->components = comps; } -- cgit From c8d9d15e8d696f556fd27ae43db12552bcc63512 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 24 Apr 2009 19:30:59 -0700 Subject: Simplify dwarfless kprobe stmt vs. name logic --- tapsets.cxx | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 9a8524b1..51c7d360 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8440,7 +8440,6 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "static struct stap_dwarfless_probe {"; s.op->newline(1) << "const unsigned return_p:1;"; s.op->newline() << "const unsigned maxactive_p:1;"; - s.op->newline() << "const unsigned statement_p:1;"; s.op->newline() << "unsigned registered_p:1;"; s.op->newline() << "const unsigned short maxactive_val;"; @@ -8486,17 +8485,11 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX); s.op->line() << " .maxactive_val=" << p->maxactive_val << ","; } + if (p->has_statement) - { - s.op->line() << " .statement_p=1,"; - s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,"; - s.op->line() << " .symbol_string=\"" << "\","; - } + s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,"; else - { - s.op->line() << " .address=(unsigned long)0x" << hex << 0 << dec << "ULL,"; - s.op->line() << " .symbol_string=\"" << p->symbol_name << "\","; - } + s.op->line() << " .symbol_string=\"" << p->symbol_name << "\","; s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ","; s.op->line() << " .ph=&" << p->name; @@ -8552,21 +8545,15 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) void kprobe_derived_probe_group::emit_module_init (systemtap_session& s) { -#define CHECK_STMT(var) \ - s.op->newline() << "if (sdp->statement_p) {"; \ - s.op->newline() << var << ".symbol_name = NULL;"; \ - s.op->newline() << "} else {"; \ - s.op->newline() << var << ".symbol_name = sdp->symbol_string;"; \ - s.op->newline() << "}"; - s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {"; - s.op->newline() << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];"; + s.op->newline(1) << "struct stap_dwarfless_probe *sdp = & stap_dwarfless_probes[i];"; s.op->newline() << "struct stap_dwarfless_kprobe *kp = & stap_dwarfless_kprobes[i];"; - s.op->newline() << "unsigned long relocated_addr = sdp->address;"; + s.op->newline() << "void *addr = (void *) sdp->address;"; + s.op->newline() << "const char *symbol_name = addr ? NULL : sdp->symbol_string;"; s.op->newline() << "probe_point = sdp->pp;"; // for error messages s.op->newline() << "if (sdp->return_p) {"; - s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;"; - CHECK_STMT("kp->u.krp.kp"); + s.op->newline(1) << "kp->u.krp.kp.addr = addr;"; + s.op->newline() << "kp->u.krp.kp.symbol_name = symbol_name;"; s.op->newline() << "if (sdp->maxactive_p) {"; s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;"; s.op->newline(-1) << "} else {"; @@ -8575,9 +8562,9 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 s.op->newline() << "#ifdef __ia64__"; - s.op->newline() << "kp->dummy.pre_handler = NULL;"; s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;"; - CHECK_STMT("kp->dummy"); + s.op->newline() << "kp->dummy.symbol_name = kp->u.krp.kp.symbol_name;"; + s.op->newline() << "kp->dummy.pre_handler = NULL;"; s.op->newline() << "rc = register_kprobe (& kp->dummy);"; s.op->newline() << "if (rc == 0) {"; s.op->newline(1) << "rc = register_kretprobe (& kp->u.krp);"; @@ -8589,13 +8576,13 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "#endif"; s.op->newline(-1) << "} else {"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 - s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;"; - CHECK_STMT("kp->u.kp"); - s.op->newline(1) << "kp->u.kp.pre_handler = &enter_kprobe_probe;"; + s.op->newline(1) << "kp->u.kp.addr = addr;"; + s.op->newline() << "kp->u.kp.symbol_name = symbol_name;"; + s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;"; s.op->newline() << "#ifdef __ia64__"; - s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;"; s.op->newline() << "kp->dummy.pre_handler = NULL;"; - CHECK_STMT("kp->dummy"); + s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;"; + s.op->newline() << "kp->dummy.symbol_name = kp->u.kp.symbol_name;"; s.op->newline() << "rc = register_kprobe (& kp->dummy);"; s.op->newline() << "if (rc == 0) {"; s.op->newline(1) << "rc = register_kprobe (& kp->u.kp);"; @@ -8615,7 +8602,6 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "else sdp->registered_p = 1;"; s.op->newline(-1) << "}"; // for loop -#undef CHECK_STMT } void -- cgit From b6371390a999711146084ed6377a64e4c9480d83 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 24 Apr 2009 20:06:58 -0700 Subject: Enable kprobe.function.return.maxactive The code to emit maxactive was almost there; it just needed to enable the maxactive probe component and pass the value down. --- tapsets.cxx | 92 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 35 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 51c7d360..1d194720 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2635,7 +2635,9 @@ struct kprobe_derived_probe: public derived_probe const string& name, int64_t stmt_addr, bool has_return, - bool has_statement + bool has_statement, + bool has_maxactive, + long maxactive_val ); string symbol_name; Dwarf_Addr addr; @@ -8334,14 +8336,17 @@ static string TOK_KPROBE("kprobe"); kprobe_derived_probe::kprobe_derived_probe (probe *base, probe_point *location, - const string& name, + const string& name, int64_t stmt_addr, - bool if_return, - bool if_statement -): + bool has_return, + bool has_statement, + bool has_maxactive, + long maxactive_val + ): derived_probe (base, location), symbol_name (name), addr (stmt_addr), - has_return (if_return), has_statement (if_statement) + has_return (has_return), has_statement (has_statement), + has_maxactive (has_maxactive), maxactive_val (maxactive_val) { this->tok = base->tok; this->access_var = false; @@ -8373,11 +8378,13 @@ kprobe_derived_probe::kprobe_derived_probe (probe *base, } else comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(name))); - - if (has_return) - comps.push_back (new probe_point::component(TOK_RETURN)); } + if (has_return) + comps.push_back (new probe_point::component(TOK_RETURN)); + if (has_maxactive) + comps.push_back (new probe_point::component(TOK_MAXACTIVE, new literal_number(maxactive_val))); + this->sole_location()->components = comps; } @@ -8693,36 +8700,46 @@ kprobe_builder::build(systemtap_session & sess, vector & finished_results) { string function_string_val, module_string_val; - int64_t statement_num_val = 0; - bool has_function_str, has_module_str, has_statement_num, has_absolute, has_return; + int64_t statement_num_val = 0, maxactive_val = 0; + bool has_function_str, has_module_str, has_statement_num; + bool has_absolute, has_return, has_maxactive; - has_function_str = this->get_param(parameters, TOK_FUNCTION, function_string_val); - has_module_str = this->get_param(parameters, TOK_MODULE, module_string_val); - has_return = this->has_null_param (parameters, TOK_RETURN); - has_statement_num = this->get_param(parameters, TOK_STATEMENT, statement_num_val); - has_absolute = this->has_null_param (parameters, TOK_ABSOLUTE); + has_function_str = get_param(parameters, TOK_FUNCTION, function_string_val); + has_module_str = get_param(parameters, TOK_MODULE, module_string_val); + has_return = has_null_param (parameters, TOK_RETURN); + has_maxactive = get_param(parameters, TOK_MAXACTIVE, maxactive_val); + has_statement_num = get_param(parameters, TOK_STATEMENT, statement_num_val); + has_absolute = has_null_param (parameters, TOK_ABSOLUTE); - if ( has_function_str ) - { - if ( has_module_str ) - function_string_val = module_string_val + ":" + function_string_val; - finished_results.push_back ( new kprobe_derived_probe ( base, - location, function_string_val, - 0, has_return, - has_statement_num) ); - } + if (has_function_str) + { + if (has_module_str) + function_string_val = module_string_val + ":" + function_string_val; + + finished_results.push_back (new kprobe_derived_probe (base, + location, function_string_val, + 0, has_return, + has_statement_num, + has_maxactive, + maxactive_val)); + } else - { - // assert guru mode for absolute probes - if ( has_statement_num && has_absolute && !base->privileged ) - throw semantic_error ("absolute statement probe in unprivileged script", base->tok); - - finished_results.push_back(new kprobe_derived_probe ( base, - location,"", - statement_num_val, has_return, - has_statement_num)); - } + { + // assert guru mode for absolute probes + if ( has_statement_num && has_absolute && !base->privileged ) + throw semantic_error ("absolute statement probe in unprivileged script", base->tok); + + finished_results.push_back (new kprobe_derived_probe (base, + location, "", + statement_num_val, + has_return, + has_statement_num, + has_maxactive, + maxactive_val)); + } } + + // ------------------------------------------------------------------------ // timer derived probes // ------------------------------------------------------------------------ @@ -11856,8 +11873,13 @@ register_standard_tapsets(systemtap_session & s) ->bind_str(TOK_FUNCTION)->bind(new kprobe_builder()); s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN) ->bind(new kprobe_builder()); + s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_FUNCTION)->bind(TOK_RETURN) + ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder()); s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE) ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN)->bind(new kprobe_builder()); + s.pattern_root->bind(TOK_KPROBE)->bind_str(TOK_MODULE) + ->bind_str(TOK_FUNCTION)->bind(TOK_RETURN) + ->bind_num(TOK_MAXACTIVE)->bind(new kprobe_builder()); s.pattern_root->bind(TOK_KPROBE)->bind_num(TOK_STATEMENT) ->bind(TOK_ABSOLUTE)->bind(new kprobe_builder()); } -- cgit From 88747011872d35bdb5dac1a01569e88b385d0519 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 25 Apr 2009 21:47:54 -0400 Subject: fix kprobe.* probes so they don't break -p4 if script also has kernel.* probes * tapsets.cxx (kprobe_derived_probe): Use enter_k[ret]probe>>2<<_probe. * testsuite/buildok/thirtyone.stp: Test this. --- tapsets.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 1d194720..4aeff584 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8424,9 +8424,9 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); // Forward declare the master entry functions - s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,"; + s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,"; s.op->line() << " struct pt_regs *regs);"; - s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,"; + s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,"; s.op->line() << " struct pt_regs *regs);"; // Emit an array of kprobe/kretprobe pointers @@ -8507,7 +8507,7 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) // Emit the kprobes callback function s.op->newline(); - s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,"; + s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,"; s.op->line() << " struct pt_regs *regs) {"; // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);"; @@ -8526,7 +8526,7 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) // Same for kretprobes s.op->newline(); - s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,"; + s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,"; s.op->line() << " struct pt_regs *regs) {"; s.op->newline(1) << "struct kretprobe *krp = inst->rp;"; @@ -8566,7 +8566,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline(-1) << "} else {"; s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);"; s.op->newline(-1) << "}"; - s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;"; + s.op->newline() << "kp->u.krp.handler = &enter_kretprobe2_probe;"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 s.op->newline() << "#ifdef __ia64__"; s.op->newline() << "kp->dummy.addr = kp->u.krp.kp.addr;"; @@ -8585,7 +8585,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) // to ensure safeness of bspcache, always use aggr_kprobe on ia64 s.op->newline(1) << "kp->u.kp.addr = addr;"; s.op->newline() << "kp->u.kp.symbol_name = symbol_name;"; - s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;"; + s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe2_probe;"; s.op->newline() << "#ifdef __ia64__"; s.op->newline() << "kp->dummy.pre_handler = NULL;"; s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;"; -- cgit From 9f38e65363878d1e1bc8f51a0ad2cc4fd0316e13 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 26 Apr 2009 17:17:04 +0200 Subject: Handle kprobe struct field symbol_name as either char * or const char *. Older (2.6.18) based kernels defined struct kprobes symbol_name as char *, but newer (2.6.27) based kernels defined the same field as const char *. * tapsets.cxx (kprobe_derived_probe_group::emit_module_init): Always cast to char * when assigning to kprobes.symbol_name field. --- tapsets.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 4aeff584..bc8df243 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8560,7 +8560,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "probe_point = sdp->pp;"; // for error messages s.op->newline() << "if (sdp->return_p) {"; s.op->newline(1) << "kp->u.krp.kp.addr = addr;"; - s.op->newline() << "kp->u.krp.kp.symbol_name = symbol_name;"; + s.op->newline() << "kp->u.krp.kp.symbol_name = (char *) symbol_name;"; s.op->newline() << "if (sdp->maxactive_p) {"; s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;"; s.op->newline(-1) << "} else {"; @@ -8584,7 +8584,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline(-1) << "} else {"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 s.op->newline(1) << "kp->u.kp.addr = addr;"; - s.op->newline() << "kp->u.kp.symbol_name = symbol_name;"; + s.op->newline() << "kp->u.kp.symbol_name = (char *) symbol_name;"; s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe2_probe;"; s.op->newline() << "#ifdef __ia64__"; s.op->newline() << "kp->dummy.pre_handler = NULL;"; -- cgit