From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4779 invoked by alias); 20 Jan 2012 15:49:29 -0000 Received: (qmail 4764 invoked by uid 22791); 20 Jan 2012 15:49:26 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,TW_RG,TW_TM 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; Fri, 20 Jan 2012 15:49:12 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1RoGiF-0002YJ-JX from wade_farnsworth@mentor.com for systemtap@sourceware.org; Fri, 20 Jan 2012 07:49:11 -0800 Received: from SVR-ORW-FEM-04.mgc.mentorg.com ([147.34.97.41]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 20 Jan 2012 07:48:45 -0800 Received: from [172.30.9.133] (147.34.91.1) by svr-orw-fem-04.mgc.mentorg.com (147.34.97.41) with Microsoft SMTP Server id 14.1.289.1; Fri, 20 Jan 2012 07:49:10 -0800 Message-ID: <4F198CF6.7080007@mentor.com> Date: Fri, 20 Jan 2012 15: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: Re: [PATCH] Add --sysroot option References: <4F0AFEEE.30909@mentor.com> In-Reply-To: <4F0AFEEE.30909@mentor.com> Content-Type: text/plain; charset="ISO-8859-1"; format=flowed 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/msg00024.txt.bz2 Wade Farnsworth wrote: > This adds a --sysroot option to facilitate different file locations for > user-space processes and libraries at compile-time versus run-time when > generating stap kernel modules for a remote system. > > For example if we compile the probe: > > process("/bin/foo").begin {} > > while passing "--sysroot=/bar/baz" to stap, symbols will be taken from > /bar/baz/bin/foo, but the resulting .ko will still refer to /bin/foo. > This allows the probe to be used on a different machine than the one it > is compiled on, so long as the compiling machine replicates the > necessary files in the sysroot directory. This is a fairly typical use case > for embedded Linux. > > Known limitations: > 1. Probes must contain the absolute file path to the process or library. > If a relative path is used, it will be assumed to be located in the > top level of the sysroot. > 2. Similarly probes on scripts containing "#!/usr/bin/env bash" or similar > will also assume that the interpreter is located in the sysroot > top level. > The reason for these limitations is that we do not have access to the > target machine's environment compile-time, so some assumptions must > necessarily be made. > > Signed-off-by: Wade Farnsworth Any comments on this patch? In particular, I'm wondering if I'm on the right track here. Any advice would be appreciated. Thanks! -Wade > --- > session.cxx | 16 ++++++++++++++++ > session.h | 1 + > tapset-itrace.cxx | 5 ++++- > tapset-utrace.cxx | 5 ++++- > tapsets.cxx | 53 +++++++++++++++++++++++++++++++++++++++++------------ > 5 files changed, 66 insertions(+), 14 deletions(-) > > diff --git a/session.cxx b/session.cxx > index f4ce8a6..1c1adbf 100644 > --- a/session.cxx > +++ b/session.cxx > @@ -84,6 +84,7 @@ systemtap_session::systemtap_session (): > kernel_release = string (buf.release); > release = kernel_release; > kernel_build_tree = "/lib/modules/" + kernel_release + "/build"; > + sysroot = string(); > architecture = machine = normalize_machine(buf.machine); > > for (unsigned i=0; i<5; i++) perpass_verbose[i]=0; > @@ -534,6 +535,8 @@ 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 executables are located" > , compatible.c_str())<< endl > ; > > @@ -587,6 +590,7 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) > #define LONG_OPT_PRIVILEGE 28 > #define LONG_OPT_SUPPRESS_HANDLER_ERRORS 29 > #define LONG_OPT_MODINFO 30 > +#define LONG_OPT_SYSROOT 31 > // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page > static struct option long_options[] = { > { "kelf", 0,&long_opt, LONG_OPT_KELF }, > @@ -625,6 +629,7 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) > { "privilege", 1,&long_opt, LONG_OPT_PRIVILEGE }, > { "suppress-handler-errors", 0,&long_opt, LONG_OPT_SUPPRESS_HANDLER_ERRORS }, > { "modinfo", 1,&long_opt, LONG_OPT_MODINFO }, > + { "sysroot", 1,&long_opt, LONG_OPT_SYSROOT }, > { NULL, 0, NULL, 0 } > }; > int grc = getopt_long (argc, argv, "hVvtp:I:e:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:WG:", > @@ -1151,6 +1156,17 @@ systemtap_session::parse_cmdline (int argc, char * const argv []) > modinfos.push_back (string(optarg)); > break; > > + case LONG_OPT_SYSROOT: > + { > + 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) + "/"; > + break; > + } > + > default: > // NOTREACHED unless one added a getopt option but not a corresponding switch/case: > cerr<< _F("Unhandled long argument id %d", long_opt)<< endl; > diff --git a/session.h b/session.h > index 64a22a5..f1a301b 100644 > --- a/session.h > +++ b/session.h > @@ -140,6 +140,7 @@ public: > std::string kernel_base_release; > std::string kernel_build_tree; > std::string kernel_source_tree; > + std::string sysroot; > std::map kernel_config; > std::set kernel_exports; > std::string machine; > diff --git a/tapset-itrace.cxx b/tapset-itrace.cxx > index 1a9bf67..77811d5 100644 > --- a/tapset-itrace.cxx > +++ b/tapset-itrace.cxx > @@ -114,8 +114,11 @@ struct itrace_builder: public derived_probe_builder > // If we have a path, we need to validate it. > if (has_path) > { > - path = find_executable (path); > + size_t pos; > + path = find_executable (sess.sysroot + path); > sess.unwindsym_modules.insert (path); > + if (!sess.sysroot.empty()&& ((pos = path.find(sess.sysroot)) != string::npos)) > + path.replace(pos, sess.sysroot.length(), "/"); > } > > finished_results.push_back(new itrace_derived_probe(sess, base, location, > diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx > index 64ba900..11cf292 100644 > --- a/tapset-utrace.cxx > +++ b/tapset-utrace.cxx > @@ -679,8 +679,11 @@ struct utrace_builder: public derived_probe_builder > } > else if (has_path) > { > - path = find_executable (path); > + size_t pos; > + path = find_executable (sess.sysroot + path); > sess.unwindsym_modules.insert (path); > + if (!sess.sysroot.empty()&& ((pos = path.find(sess.sysroot)) != string::npos)) > + path.replace(pos, sess.sysroot.length(), "/"); > } > else if (has_pid) > { > diff --git a/tapsets.cxx b/tapsets.cxx > index 177f565..50464dc 100644 > --- a/tapsets.cxx > +++ b/tapsets.cxx > @@ -584,13 +584,13 @@ 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 (sess.sysroot + module_val); > if (has_library) > { > if (! contains_glob_chars (library_name)) > { > path = module_val; > - module_val = find_executable (library_name, "LD_LIBRARY_PATH"); > + module_val = find_executable (sess.sysroot + library_name, "LD_LIBRARY_PATH"); > } > else > path = library_name; > @@ -1139,7 +1139,7 @@ dwarf_query::add_probe_point(const string& dw_funcname, > { > string reloc_section; // base section for relocation purposes > Dwarf_Addr reloc_addr; // relocated > - const string& module = dw.module_name; // "kernel" or other > + string& module = dw.module_name; // "kernel" or other > string funcname = dw_funcname; > > assert (! has_absolute); // already handled in dwarf_builder::build() > @@ -1190,6 +1190,14 @@ dwarf_query::add_probe_point(const string& dw_funcname, > > if (has_process) > { > + if (!sess.sysroot.empty()) > + { > + size_t pos; > + if ((pos = module.find(sess.sysroot)) != string::npos) > + module.replace(pos, sess.sysroot.length(), "/"); > + if ((pos = path.find(sess.sysroot)) != string::npos) > + path.replace(pos, sess.sysroot.length(), "/"); > + } > results.push_back (new uprobe_derived_probe(funcname, filename, line, > module, reloc_section, addr, reloc_addr, > *this, scope_die)); > @@ -6548,13 +6556,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&& > @@ -6607,9 +6616,15 @@ 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; > + if (!sess.sysroot.empty()) > + { > + size_t pos; > + if ((pos = eglobbed.find(sess.sysroot)) != string::npos) > + eglobbed.replace(pos, sess.sysroot.length(), "/"); > + } > > probe_point::component* ppc = new probe_point::component (TOK_PROCESS, > - new literal_string (eglobbed)); > + new literal_string (eglobbed)); > ppc->tok = location->components[0]->tok; // overwrite [0] slot, pattern matched above > pp->components[0] = ppc; > > @@ -6681,12 +6696,12 @@ 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 (sess.sysroot + env_path); > } > } > else > { > - user_path = find_executable (path); > + user_path = find_executable (sess.sysroot + path); > } > > struct stat st; > @@ -6707,8 +6722,12 @@ 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 = user_path; > + size_t pos; > + if (!sess.sysroot.empty()&& ((pos = path.find(sess.sysroot)) != string::npos)) > + user_path_tgt.replace(pos, sess.sysroot.length(), "/"); > 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; > > @@ -6727,7 +6746,7 @@ 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 (sess.sysroot + user_lib, "LD_LIBRARY_PATH"); > else > module_name = user_path; // canonicalize it > > @@ -8195,7 +8214,7 @@ 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, > @@ -8218,9 +8237,19 @@ kprobe_builder::build(systemtap_session&, > has_library = get_param (parameters, TOK_LIBRARY, library); > > if (has_path) > - path = find_executable (path); > + { > + size_t pos; > + path = find_executable (sess.sysroot + path); > + if (!sess.sysroot.empty()&& ((pos = path.find(sess.sysroot)) != string::npos)) > + path.replace(pos, sess.sysroot.length(), "/"); > + } > if (has_library) > - library = find_executable (library, "LD_LIBRARY_PATH"); > + { > + size_t pos; > + library = find_executable (sess.sysroot + library, "LD_LIBRARY_PATH"); > + if (!sess.sysroot.empty()&& ((pos = library.find(sess.sysroot)) != string::npos)) > + library.replace(pos, sess.sysroot.length(), "/"); > + } > > if (has_function_str) > {