From 1b6d5734f74a46facd7e117c6f0100b4cb073728 Mon Sep 17 00:00:00 2001 From: Abegail Jakop Date: Fri, 30 May 2014 11:25:09 -0400 Subject: [PATCH] changed check for -x PID, added tests session.cxx: revised approach to checking path for given PID checks that the path produced from a given PID is valid using readlink(). added in new error messages to be more specific. tapsets.cxx: fixed spelling mistake proc_by_pid*: test files --- session.cxx | 67 +++++++++++++++--------- tapsets.cxx | 2 +- testsuite/systemtap.base/proc_by_pid.c | 18 +++++++ testsuite/systemtap.base/proc_by_pid.exp | 46 ++++++++++++++++ testsuite/systemtap.base/proc_by_pid.stp | 13 +++++ 5 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 testsuite/systemtap.base/proc_by_pid.c create mode 100644 testsuite/systemtap.base/proc_by_pid.exp create mode 100644 testsuite/systemtap.base/proc_by_pid.stp diff --git a/session.cxx b/session.cxx index 117f6d1c5..e183c31b0 100644 --- a/session.cxx +++ b/session.cxx @@ -1782,38 +1782,53 @@ string systemtap_session::cmd_file () { wordexp_t words; - int rc; + string file; + if (target_pid && cmd == "") { string pid_path = string("/proc/") + lex_cast(target_pid) + "/exe"; - rc = wordexp (pid_path.c_str (), &words, WRDE_NOCMD|WRDE_UNDEF); + char buf[1024]; + ssize_t path_len = readlink(pid_path.c_str(), buf, sizeof(buf) - 1); + + if (path_len > 0) + { + file = string(buf); + } + else + { + if (target_pid < 0) + { + throw SEMANTIC_ERROR(_("pid is a negative value")); + } + throw SEMANTIC_ERROR(_("pid does not correspond to a running process")); + } } else // default is to assume -c flag was given - rc = wordexp (cmd.c_str (), &words, WRDE_NOCMD|WRDE_UNDEF); - - string file; - if(rc == 0) - { - if (words.we_wordc > 0) - file = words.we_wordv[0]; - wordfree (& words); - } - else - { - switch (rc) + { + int rc = wordexp (cmd.c_str (), &words, WRDE_NOCMD|WRDE_UNDEF); + if(rc == 0) { - case WRDE_BADCHAR: - throw SEMANTIC_ERROR(_("command contains illegal characters")); - case WRDE_BADVAL: - throw SEMANTIC_ERROR(_("command contains undefined shell variables")); - case WRDE_CMDSUB: - throw SEMANTIC_ERROR(_("command contains command substitutions")); - case WRDE_NOSPACE: - throw SEMANTIC_ERROR(_("out of memory")); - case WRDE_SYNTAX: - throw SEMANTIC_ERROR(_("command contains shell syntax errors")); - default: - throw SEMANTIC_ERROR(_("unspecified wordexp failure")); + if (words.we_wordc > 0) + file = words.we_wordv[0]; + wordfree (& words); + } + else + { + switch (rc) + { + case WRDE_BADCHAR: + throw SEMANTIC_ERROR(_("command contains illegal characters")); + case WRDE_BADVAL: + throw SEMANTIC_ERROR(_("command contains undefined shell variables")); + case WRDE_CMDSUB: + throw SEMANTIC_ERROR(_("command contains command substitutions")); + case WRDE_NOSPACE: + throw SEMANTIC_ERROR(_("out of memory")); + case WRDE_SYNTAX: + throw SEMANTIC_ERROR(_("command contains shell syntax errors")); + default: + throw SEMANTIC_ERROR(_("unspecified wordexp failure")); + } } } return file; diff --git a/tapsets.cxx b/tapsets.cxx index e0c5fa0b3..04810dc40 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -7538,7 +7538,7 @@ dwarf_builder::build(systemtap_session & sess, catch (const semantic_error& e) { if(sess.target_pid) - throw SEMANTIC_ERROR(_("invlaid -x pid for unspecified process" + throw SEMANTIC_ERROR(_("invalid -x pid for unspecified process" " probe [man stapprobes]"), NULL, NULL, &e); else throw SEMANTIC_ERROR(_("invalid -c command for unspecified process" diff --git a/testsuite/systemtap.base/proc_by_pid.c b/testsuite/systemtap.base/proc_by_pid.c new file mode 100644 index 000000000..5fb0efaec --- /dev/null +++ b/testsuite/systemtap.base/proc_by_pid.c @@ -0,0 +1,18 @@ +#include "stdio.h" +#include "sys/sdt.h" + +void first_function() {} +void second_function() {first_function();} +void exit_probe_function() {} + +int main() +{ + sleep(30); + STAP_PROBE(proc_by_pid, main_start); + marker_here: + first_function(); + STAP_PROBE(proc_by_pid, main_end); + second_function(); + exit_probe_function(); + return 0; +} diff --git a/testsuite/systemtap.base/proc_by_pid.exp b/testsuite/systemtap.base/proc_by_pid.exp new file mode 100644 index 000000000..d9616f5bd --- /dev/null +++ b/testsuite/systemtap.base/proc_by_pid.exp @@ -0,0 +1,46 @@ +set test_name "proc_by_pid" +if {! [installtest_p]} { + untested $test_name + return +} + +# Build the test program +set compile_result [target_compile $srcdir/$subdir/$test_name.c ./$test_name executable "additional_flags=-g [sdt_includes]"] + +if {$compile_result != ""} { + verbose -log "target_compile failed: $compile_result" 2 + fail "$test_name - unable to compile, $compile_result" + untested "$test_name" + return +} else { + pass "$test_name - compiled successfully" +} + +# Expected output +set output_string "Encountered \[0-4\] functions, and \[0-2\] marks" + +# Running the test program and script +foreach runtime [get_runtime_list] { + # Run the instance of the test program + verbose -log "running test program" + spawn ./$test_name + set exe_id $spawn_id + + if {$runtime != ""} { + set cur_test_name "$test_name($runtime)" + + # Run stap with -x $PID + stap_run $cur_test_name no_load $output_string --runtime=$runtime $srcdir/$subdir/$test_name.stp -x [exp_pid -i $exe_id] + } elseif {[uprobes_p]} { + # Run stap with -x $PID + stap_run $test_name no_load $output_string $srcdir/$subdir/$test_name.stp -x [exp_pid -i $exe_id] + } else { + untested "$test_name (uprobes)" + continue + } + kill -INT -[exp_pid -i $exe_id] 2 + catch {close -i $exe_id} + catch {wait -i $exe_id} +} + +exec rm -f ./$test_name diff --git a/testsuite/systemtap.base/proc_by_pid.stp b/testsuite/systemtap.base/proc_by_pid.stp new file mode 100644 index 000000000..2e54e479e --- /dev/null +++ b/testsuite/systemtap.base/proc_by_pid.stp @@ -0,0 +1,13 @@ +global funcs +global marks + +probe begin { printf("systemtap starting probe\n") } +probe process.function("first_function"), + process.function("second_function") { funcs++ } +# Exit, since scripts with -x flag do not auto-stop when PID exits +probe process.function("exit_probe_function") { funcs++; exit (); } +probe process.mark("*") { marks++ } +probe end { + printf("systemtap ending probe\n"); + printf("Encountered %d functions, and %d marks\n", funcs, marks); +} -- 2.43.5