From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2822 invoked by alias); 8 Mar 2012 14:49:39 -0000 Received: (qmail 2799 invoked by uid 22791); 8 Mar 2012 14:49:33 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,TW_CP,TW_DW,TW_FL,TW_RG X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 08 Mar 2012 14:49:09 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1S5eeT-00033n-55 from wade_farnsworth@mentor.com ; Thu, 08 Mar 2012 06:49:09 -0800 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 8 Mar 2012 06:49:08 -0800 Received: from [172.30.13.164] (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.1.289.1; Thu, 8 Mar 2012 06:49:08 -0800 Message-ID: <4F58C6E0.6010604@mentor.com> Date: Thu, 08 Mar 2012 14:49:00 -0000 From: Wade Farnsworth User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110424 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: , , Subject: [PATCH v4 1/3] PR12331: Introduce stap options --sysroot and --sysenv References: <4F0AFEEE.30909@mentor.com> <4F340FD7.9010205@mentor.com> <4F50DD69.1000601@mentor.com> <4F58C6B0.6020707@mentor.com> In-Reply-To: <4F58C6B0.6020707@mentor.com> Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2012-q1/txt/msg00262.txt.bz2 This adds new command-line options to facilitate different file locations at compile-time versus run-time when generating stap kernel modules for a remote system: 1. --sysroot=DIR Specifies a separate filesystem for the remote system on the local system. The following stap functionalities will make use of this: a. When compiling process and library probes with a remote filesystem path (e.g. process("/bin/foo") with --sysroot=/bar/baz). In this case symbols will be taken from the local filesystem (/bar/baz/bin/foo), but the resulting .ko will still contain paths on the remote filesystem (/bin/foo). b. When passing a kernel release with -r (not a full path), the kernel build directory will be expected in the sysroot. c. When DWARF debug info is contained in a separate file from the executable, the sysroot is used to find the debug info files. d. All calls to find_executable() search the path passed in the argument env_path relative to the sysroot. For example if PATH=/bin/foo, and --sysroot=/bar/baz is provided, then find_executable() called with env_path == "PATH" will search /bar/baz/bin/foo. e. stap attempts to detect if a path in a probe would be outside of the sysroot and errors appropriately. This situation may occur, for example, if the path contains several ".." directories. 2. --sysenv=VAR=VALUE Specifies a different environment variable for the remote system as opposed to the local one, and that the value on the remote system should be used. Currently only valid env_path arguments to find_executable() are handled (i.e. PATH, LD_LIBRARY_PATH). If --sysroot is provided and --sysenv is omitted, then the local environment relative to the sysroot will be used. These options are disabled for systemtap clients. Signed-off-by: Wade Farnsworth --- cmdline.cxx | 2 + cmdline.h | 2 + dwflpp.cxx | 4 +- hash.cxx | 3 +- main.cxx | 9 +++++++ session.cxx | 59 +++++++++++++++++++++++++++++++++++++++++++++++ session.h | 3 ++ setupdwfl.cxx | 37 +++++++++++++++++++++++++---- setupdwfl.h | 1 + tapset-itrace.cxx | 7 +++-- tapset-utrace.cxx | 7 +++-- tapsets.cxx | 66 ++++++++++++++++++++++++++++++++++++----------------- tapsets.h | 2 + translate.cxx | 4 +- util.cxx | 27 +++++++++++++++++----- util.h | 3 ++ 16 files changed, 193 insertions(+), 43 deletions(-) diff --git a/cmdline.cxx b/cmdline.cxx index 04d741e..720d34a 100644 --- a/cmdline.cxx +++ b/cmdline.cxx @@ -55,5 +55,7 @@ struct option stap_long_options[] = { { "rlimit-nproc", 1, &stap_long_opt, LONG_OPT_RLIMIT_NPROC }, { "rlimit-stack", 1, &stap_long_opt, LONG_OPT_RLIMIT_STACK }, { "rlimit-fsize", 1, &stap_long_opt, LONG_OPT_RLIMIT_FSIZE }, + { "sysroot", 1, &stap_long_opt, LONG_OPT_SYSROOT }, + { "sysenv", 1, &stap_long_opt, LONG_OPT_SYSENV }, { NULL, 0, NULL, 0 } }; diff --git a/cmdline.h b/cmdline.h index 4a09bd0..b41c734 100644 --- a/cmdline.h +++ b/cmdline.h @@ -49,6 +49,8 @@ extern "C" { #define LONG_OPT_RLIMIT_NPROC 33 #define LONG_OPT_RLIMIT_STACK 34 #define LONG_OPT_RLIMIT_FSIZE 35 +#define LONG_OPT_SYSROOT 36 +#define LONG_OPT_SYSENV 37 // NB: when adding new options, consider very carefully whether they // should be restricted from stap clients (after --client-options)! diff --git a/dwflpp.cxx b/dwflpp.cxx index dd42962..6cb2fdb 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -321,7 +321,7 @@ dwflpp::setup_kernel(const string& name, systemtap_session & s, bool debuginfo_n { if (debuginfo_needed) { // Suggest a likely kernel dir to find debuginfo rpm for - string dir = string("/lib/modules/" + sess.kernel_release ); + string dir = string(sess.sysroot + "/lib/modules/" + sess.kernel_release ); find_debug_rpms(sess, dir.c_str()); } throw semantic_error (_F("missing %s kernel/module debuginfo under '%s'", @@ -359,7 +359,7 @@ dwflpp::setup_kernel(const vector &names, bool debuginfo_needed) { if (debuginfo_needed) { // Suggest a likely kernel dir to find debuginfo rpm for - string dir = string("/lib/modules/" + sess.kernel_release ); + string dir = string(sess.sysroot + "/lib/modules/" + sess.kernel_release ); find_debug_rpms(sess, dir.c_str()); } throw semantic_error (_F("missing %s kernel/module debuginfo under '%s'", diff --git a/hash.cxx b/hash.cxx index c435a03..f665ac3 100644 --- a/hash.cxx +++ b/hash.cxx @@ -133,6 +133,7 @@ void create_hash_log(const string &type_str, const string &parms, const string & static const hash& get_base_hash (systemtap_session& s) { + map dummy; if (s.base_hash) return *s.base_hash; @@ -158,7 +159,7 @@ get_base_hash (systemtap_session& s) // Hash compiler path, size, and mtime. We're just going to assume // we'll be using gcc. XXX: getting kbuild to spit out out would be // better, especially since this is fooled by ccache. - h.add_path("Compiler ", find_executable("gcc")); + h.add_path("Compiler ", find_executable("gcc", "", dummy)); // Hash the systemtap size and mtime. We could use VERSION/DATE, // but when developing systemtap that doesn't work well (since you diff --git a/main.cxx b/main.cxx index c08cf18..84f6e7c 100644 --- a/main.cxx +++ b/main.cxx @@ -24,6 +24,7 @@ #include "csclient.h" #include "remote.h" #include "tapsets.h" +#include "setupdwfl.h" #include #include @@ -487,6 +488,14 @@ passes_0_4 (systemtap_session &s) s.kernel_base_release.assign(s.kernel_release, 0, s.kernel_release.find('-')); + // Update various paths to include the sysroot, if provided. + if (!s.sysroot.empty()) + { + if (s.update_release_sysroot && !s.sysroot.empty()) + s.kernel_build_tree = s.sysroot + s.kernel_build_tree; + debuginfo_path_insert_sysroot(s.sysroot); + } + // Now that no further changes to s.kernel_build_tree can occur, let's use it. if ((rc = parse_kernel_config (s)) != 0) { diff --git a/session.cxx b/session.cxx index b8fc17f..95ddda3 100644 --- a/session.cxx +++ b/session.cxx @@ -150,6 +150,8 @@ systemtap_session::systemtap_session (): download_dbinfo = 0; suppress_handler_errors = false; native_build = true; // presumed + sysroot = ""; + update_release_sysroot = false; /* adding in the XDG_DATA_DIRS variable path, * this searches in conjunction with SYSTEMTAP_TAPSET @@ -311,6 +313,9 @@ systemtap_session::systemtap_session (const systemtap_session& other, systemtap_v_check = other.systemtap_v_check; download_dbinfo = other.download_dbinfo; suppress_handler_errors = other.suppress_handler_errors; + sysroot = other.sysroot; + update_release_sysroot = other.update_release_sysroot; + sysenv = other.sysenv; include_path = other.include_path; runtime_path = other.runtime_path; @@ -534,6 +539,13 @@ systemtap_session::usage (int exitcode) " yes,no,ask,\n" " --dump-probe-types\n" " show a list of available probe types.\n" + " --sysroot=DIR\n" + " specify sysroot directory where target files (executables,\n" " libraries, etc.) are located.\n" + " --sysenv=VAR=VALUE\n" + " provide an alternate value for an environment variable\n" + " where the value on a remote system differs. Path\n" + " variables (e.g. PATH, LD_LIBRARY_PATH) are assumed to be\n" + " relative to the sysroot.\n" , compatible.c_str()) << endl ; @@ -1139,6 +1151,52 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) cerr << _F("Unable to set resource limits for rlimit_fsize : %s", strerror (errno)) << endl; break; + case LONG_OPT_SYSROOT: + if (client_options) { + cerr << _F("ERROR: %s invalid with %s", "--sysroot", "--client-options") << endl; + return 1; + } else if (!sysroot.empty()) { + cerr << "ERROR: multiple --sysroot options not supported" << endl; + return 1; + } else { + const char *spath = canonicalize_file_name (optarg); + if (spath == NULL) { + cerr << _F("ERROR: %s is an invalid directory for --sysroot", optarg) << endl; + return 1; + } + + sysroot = string(spath); + if (sysroot[sysroot.size() - 1] != '/') + sysroot.append("/"); + + break; + } + + case LONG_OPT_SYSENV: + if (client_options) { + cerr << _F("ERROR: %s invalid with %s", "--sysenv", "--client-options") << endl; + return 1; + } else { + string sysenv_str = optarg; + string value; + size_t pos; + if (sysroot.empty()) { + cerr << "ERROR: --sysenv must follow --sysroot" << endl; + return 1; + } + + pos = sysenv_str.find("="); + if (pos == string::npos) { + cerr << _F("ERROR: %s is an invalid argument for --sysenv", optarg) << endl; + return 1; + } + + value = sysenv_str.substr(pos + 1); + sysenv[sysenv_str.substr(0, pos)] = value; + + break; + } + default: // NOTREACHED unless one added a getopt option but not a corresponding switch/case: cerr << _F("Unhandled long argument id %d", stap_long_opt) << endl; @@ -1428,6 +1486,7 @@ systemtap_session::setup_kernel_release (const char* kstr) } else { + update_release_sysroot = true; kernel_release = string (kstr); if (!kernel_release.empty()) kernel_build_tree = "/lib/modules/" + kernel_release + "/build"; diff --git a/session.h b/session.h index e128b2f..a82f1d1 100644 --- a/session.h +++ b/session.h @@ -140,6 +140,9 @@ public: std::string kernel_base_release; std::string kernel_build_tree; std::string kernel_source_tree; + std::string sysroot; + std::map sysenv; + bool update_release_sysroot; std::map kernel_config; std::set kernel_exports; std::string machine; diff --git a/setupdwfl.cxx b/setupdwfl.cxx index 82bc42a..91bfd39 100644 --- a/setupdwfl.cxx +++ b/setupdwfl.cxx @@ -39,14 +39,14 @@ extern "C" { // XXX: also consider adding $HOME/.debug/ for perf build-id-cache static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:/var/cache/abrt-di/usr/lib/debug:build"; static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH"); -static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr); +static char *debuginfo_path = (char *)(debuginfo_env_arr ?: debuginfo_path_arr); // NB: kernel_build_tree doesn't enter into this, as it's for // kernel-side modules only. // XXX: also consider adding $HOME/.debug/ for perf build-id-cache static const char *debuginfo_usr_path_arr = "+:.debug:/usr/lib/debug:/var/cache/abrt-di/usr/lib/debug"; -static const char *debuginfo_usr_path = (debuginfo_env_arr - ?: debuginfo_usr_path_arr); +static char *debuginfo_usr_path = (char *)(debuginfo_env_arr + ?: debuginfo_usr_path_arr); // A pointer to the current systemtap session for use only by a few // dwfl calls. DO NOT rely on this, as it is cleared after use. @@ -146,7 +146,10 @@ setup_mod_deps() } else { - modulesdep = "/lib/modules/"; + string sysroot = ""; + if (current_session_for_find_debuginfo) + sysroot = current_session_for_find_debuginfo->sysroot; + modulesdep = sysroot + "/lib/modules/"; modulesdep += elfutils_kernel_path; modulesdep += "/modules.dep"; } @@ -280,6 +283,30 @@ setup_dwfl_report_kernel_p(const char* modname, const char* filename) } } +static char * path_insert_sysroot(string sysroot, string path) +{ + char * path_new; + size_t pos = 1; + if (path[0] == '/') + path.replace(0, 1, sysroot); + while (true) { + pos = path.find(":/", pos); + if (pos == string::npos) + break; + path.replace(pos, 2, ":" + sysroot); + ++pos; + } + path_new = new char[path.size()+1]; + strcpy (path_new, path.c_str()); + return path_new; +} + +void debuginfo_path_insert_sysroot(string sysroot) +{ + debuginfo_path = path_insert_sysroot(sysroot, debuginfo_path); + debuginfo_usr_path = path_insert_sysroot(sysroot, debuginfo_usr_path); +} + static DwflPtr setup_dwfl_kernel (unsigned *modules_found, systemtap_session &s) { @@ -295,7 +322,7 @@ setup_dwfl_kernel (unsigned *modules_found, systemtap_session &s) // no way to set the dwfl_callback.debuginfo_path and always // passs the plain kernel_release here. So instead we have to // hard-code this magic here. - if (s.kernel_build_tree == string("/lib/modules/" + if (s.kernel_build_tree == string(s.sysroot + "/lib/modules/" + s.kernel_release + "/build")) elfutils_kernel_path = s.kernel_release; diff --git a/setupdwfl.h b/setupdwfl.h index 48f9105..aa1c800 100644 --- a/setupdwfl.h +++ b/setupdwfl.h @@ -69,5 +69,6 @@ int internal_find_debuginfo (Dwfl_Module *mod, int execute_abrt_action_install_debuginfo_to_abrt_cache (std::string hex); std::string get_kernel_build_id (systemtap_session &s); int download_kernel_debuginfo (systemtap_session &s, std::string hex); +void debuginfo_path_insert_sysroot(std::string sysroot); #endif diff --git a/tapset-itrace.cxx b/tapset-itrace.cxx index 1a9bf67..982ad46 100644 --- a/tapset-itrace.cxx +++ b/tapset-itrace.cxx @@ -100,7 +100,7 @@ struct itrace_builder: public derived_probe_builder std::map const & parameters, vector & finished_results) { - string path; + string path, path_tgt; int64_t pid = 0; int single_step; @@ -114,12 +114,13 @@ struct itrace_builder: public derived_probe_builder // If we have a path, we need to validate it. if (has_path) { - path = find_executable (path); + path = find_executable (path, sess.sysroot, sess.sysenv); sess.unwindsym_modules.insert (path); + path_tgt = path_remove_sysroot(sess, path); } finished_results.push_back(new itrace_derived_probe(sess, base, location, - has_path, path, pid, + has_path, path_tgt, pid, single_step )); } diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index 64ba900..1ad99cf 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -642,7 +642,7 @@ struct utrace_builder: public derived_probe_builder literal_map_t const & parameters, vector & finished_results) { - string path; + string path, path_tgt; int64_t pid; bool has_path = get_param (parameters, TOK_PROCESS, path); @@ -679,8 +679,9 @@ struct utrace_builder: public derived_probe_builder } else if (has_path) { - path = find_executable (path); + path = find_executable (path, sess.sysroot, sess.sysenv); sess.unwindsym_modules.insert (path); + path_tgt = path_remove_sysroot(sess, path); } else if (has_pid) { @@ -693,7 +694,7 @@ struct utrace_builder: public derived_probe_builder } finished_results.push_back(new utrace_derived_probe(sess, base, location, - has_path, path, pid, + has_path, path_tgt, pid, flags)); } }; diff --git a/tapsets.cxx b/tapsets.cxx index 716e23c..7dee698 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -584,13 +584,14 @@ base_query::base_query(dwflpp & dw, literal_map_t const & params): has_statement = get_number_param(params, TOK_STATEMENT, statement_num_val); if (has_process) - module_val = find_executable (module_val); + module_val = find_executable (module_val, sess.sysroot, sess.sysenv); if (has_library) { if (! contains_glob_chars (library_name)) { - path = module_val; - module_val = find_executable (library_name, "LD_LIBRARY_PATH"); + path = path_remove_sysroot(sess, module_val); + module_val = find_executable (library_name, sess.sysroot, + sess.sysenv, "LD_LIBRARY_PATH"); } else path = library_name; @@ -1127,6 +1128,15 @@ bad: base_probe->tok); } +string path_remove_sysroot(const systemtap_session& sess, const string& path) +{ + size_t pos; + string retval = path; + if (!sess.sysroot.empty() && + (pos = retval.find(sess.sysroot)) != string::npos) + retval.replace(pos, sess.sysroot.length(), "/"); + return retval; +} void dwarf_query::add_probe_point(const string& dw_funcname, @@ -1188,8 +1198,9 @@ dwarf_query::add_probe_point(const string& dw_funcname, if (has_process) { + string module_tgt = path_remove_sysroot(sess, module); results.push_back (new uprobe_derived_probe(funcname, filename, line, - module, reloc_section, addr, reloc_addr, + module_tgt, reloc_section, addr, reloc_addr, *this, scope_die)); } else @@ -2051,7 +2062,8 @@ query_one_library (const char *library, dwflpp & dw, { if (dw.function_name_matches_pattern(library, user_lib)) { - string library_path = find_executable (library, "LD_LIBRARY_PATH"); + string library_path = find_executable (library, "", dw.sess.sysenv, + "LD_LIBRARY_PATH"); probe_point* specific_loc = new probe_point(*base_loc); specific_loc->optional = true; vector derived_comps; @@ -3906,7 +3918,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) } else { - module = find_executable (module); // canonicalize it + module = find_executable (module, "", s.sysenv); // canonicalize it dw = db.get_user_dw(s, module); } } @@ -6546,13 +6558,14 @@ dwarf_builder::build(systemtap_session & sess, } else if (get_param (parameters, TOK_PROCESS, module_name) || has_null_param(parameters, TOK_PROCESS)) { + module_name = sess.sysroot + module_name; if(has_null_param(filled_parameters, TOK_PROCESS)) { wordexp_t words; int rc = wordexp(sess.cmd.c_str(), &words, WRDE_NOCMD|WRDE_UNDEF); if(rc || words.we_wordc <= 0) throw semantic_error(_("unspecified process probe is invalid without a -c COMMAND")); - module_name = words.we_wordv[0]; + module_name = sess.sysroot + words.we_wordv[0]; filled_parameters[TOK_PROCESS] = new literal_string(module_name);// this needs to be used in place of the blank map // in the case of TOK_MARK we need to modify locations as well if(location->components[0]->functor==TOK_PROCESS && @@ -6605,9 +6618,10 @@ dwarf_builder::build(systemtap_session & sess, if (sess.verbose > 1) clog << _F("Expanded process(\"%s\") to process(\"%s\")", module_name.c_str(), eglobbed.c_str()) << endl; + string eglobbed_tgt = path_remove_sysroot(sess, eglobbed); probe_point::component* ppc = new probe_point::component (TOK_PROCESS, - new literal_string (eglobbed)); + new literal_string (eglobbed_tgt)); ppc->tok = location->components[0]->tok; // overwrite [0] slot, pattern matched above pp->components[0] = ppc; @@ -6633,7 +6647,7 @@ dwarf_builder::build(systemtap_session & sess, // PR13338: unquote glob results module_name = unescape_glob_chars (module_name); - user_path = find_executable (module_name); // canonicalize it + user_path = find_executable (module_name, "", sess.sysenv); // canonicalize it // if the executable starts with "#!", we look for the interpreter of the script { @@ -6679,12 +6693,13 @@ dwarf_builder::build(systemtap_session & sess, if (p3 != string::npos) { string env_path = path.substr(p3); - user_path = find_executable (env_path); + user_path = find_executable (env_path, sess.sysroot, + sess.sysenv); } } else { - user_path = find_executable (path); + user_path = find_executable (path, sess.sysroot, sess.sysenv); } struct stat st; @@ -6705,8 +6720,9 @@ dwarf_builder::build(systemtap_session & sess, // synthesize a new probe_point, with the expanded string probe_point *pp = new probe_point (*location); + string user_path_tgt = path_remove_sysroot(sess, user_path); probe_point::component* ppc = new probe_point::component (TOK_PROCESS, - new literal_string (user_path.c_str())); + new literal_string (user_path_tgt.c_str())); ppc->tok = location->components[0]->tok; // overwrite [0] slot, pattern matched above pp->components[0] = ppc; @@ -6725,7 +6741,8 @@ dwarf_builder::build(systemtap_session & sess, if(get_param (parameters, TOK_LIBRARY, user_lib) && user_lib.length() && ! contains_glob_chars (user_lib)) - module_name = find_executable (user_lib, "LD_LIBRARY_PATH"); + module_name = find_executable (user_lib, sess.sysroot, sess.sysenv, + "LD_LIBRARY_PATH"); else module_name = user_path; // canonicalize it @@ -8189,14 +8206,14 @@ struct kprobe_builder: public derived_probe_builder void -kprobe_builder::build(systemtap_session &, +kprobe_builder::build(systemtap_session & sess, probe * base, probe_point * location, literal_map_t const & parameters, vector & finished_results) { string function_string_val, module_string_val; - string path, library; + string path, library, path_tgt, library_tgt; 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; @@ -8212,9 +8229,16 @@ kprobe_builder::build(systemtap_session &, has_library = get_param (parameters, TOK_LIBRARY, library); if (has_path) - path = find_executable (path); + { + path = find_executable (path, sess.sysroot, sess.sysenv); + path_tgt = path_remove_sysroot(sess, path); + } if (has_library) - library = find_executable (library, "LD_LIBRARY_PATH"); + { + library = find_executable (library, sess.sysroot, sess.sysenv, + "LD_LIBRARY_PATH"); + library_tgt = path_remove_sysroot(sess, library); + } if (has_function_str) { @@ -8229,8 +8253,8 @@ kprobe_builder::build(systemtap_session &, has_path, has_library, maxactive_val, - path, - library)); + path_tgt, + library_tgt)); } else { @@ -8247,8 +8271,8 @@ kprobe_builder::build(systemtap_session &, has_path, has_library, maxactive_val, - path, - library)); + path_tgt, + library_tgt)); } } diff --git a/tapsets.h b/tapsets.h index c5fb30c..ad0ed70 100644 --- a/tapsets.h +++ b/tapsets.h @@ -31,6 +31,8 @@ void register_tapset_timers(systemtap_session& sess); void register_tapset_perf(systemtap_session& sess); void register_tapset_utrace(systemtap_session& sess); +std::string path_remove_sysroot(const systemtap_session& sess, + const std::string& path); // ------------------------------------------------------------------------ // Generic derived_probe_group: contains an ordinary vector of the diff --git a/translate.cxx b/translate.cxx index 97847a8..2b8d012 100644 --- a/translate.cxx +++ b/translate.cxx @@ -6242,10 +6242,10 @@ add_unwindsym_vdso (systemtap_session &s) // having the BUILDDIR we need to do a deep search (the specific // arch name dir in the kernel build tree is unknown). string vdso_dir; - if (s.kernel_build_tree == string("/lib/modules/" + if (s.kernel_build_tree == string(s.sysroot + "/lib/modules/" + s.kernel_release + "/build")) - vdso_dir = "/lib/modules/" + s.kernel_release + "/vdso"; + vdso_dir = s.sysroot + "/lib/modules/" + s.kernel_release + "/vdso"; else vdso_dir = s.kernel_build_tree + "/arch/"; diff --git a/util.cxx b/util.cxx index ea90732..a7d8c3b 100644 --- a/util.cxx +++ b/util.cxx @@ -387,7 +387,9 @@ tokenize_cxx(const string& str, vector& tokens) // same policy as execvp(). A program name not containing a slash // will be searched along the $PATH. -string find_executable(const string& name, const string& env_path) +string find_executable(const string& name, const string& sysroot, + map& sysenv, + const string& env_path) { string retpath; @@ -398,11 +400,15 @@ string find_executable(const string& name, const string& env_path) if (name.find('/') != string::npos) // slash in the path already? { - retpath = name; + retpath = sysroot + name; } else // Nope, search $PATH. { - char *path = getenv(env_path.c_str()); + char *path; + if (sysenv.count(env_path) != 0) + path = (char *)sysenv[env_path].c_str(); + else + path = getenv(env_path.c_str()); if (path) { // Split PATH up. @@ -412,7 +418,7 @@ string find_executable(const string& name, const string& env_path) // Search the path looking for the first executable of the right name. for (vector::iterator i = dirs.begin(); i != dirs.end(); i++) { - string fname = *i + "/" + name; + string fname = sysroot + *i + "/" + name; const char *f = fname.c_str(); // Look for a normal executable file. @@ -431,13 +437,22 @@ string find_executable(const string& name, const string& env_path) // Could not find the program on the $PATH. We'll just fall back to // the unqualified name, which our caller will probably fail with. if (retpath == "") - retpath = name; + retpath = sysroot + name; // Canonicalize the path name. char *cf = canonicalize_file_name (retpath.c_str()); if (cf) { - retpath = string(cf); + string scf = string(cf); + if (sysroot.empty()) + retpath = scf; + else { + int pos = scf.find(sysroot); + if (pos == 0) + retpath = scf; + else + throw runtime_error(_F("find_executable(): file %s not in sysroot %s", cf, sysroot.c_str())); + } free (cf); } diff --git a/util.h b/util.h index 64a9746..b4d9ebf 100644 --- a/util.h +++ b/util.h @@ -12,6 +12,7 @@ #include #include #include +#include extern "C" { #include #include @@ -53,6 +54,8 @@ void tokenize_full(const std::string& str, std::vector& tokens, const std::string& delimiters); void tokenize_cxx(const std::string& str, std::vector& tokens); std::string find_executable(const std::string& name, + const std::string& sysroot, + std::map& sysenv, const std::string& env_path = "PATH"); const std::string cmdstr_quoted(const std::string& cmd); const std::string cmdstr_join(const std::vector& cmds); -- 1.7.0.4