From: Julian Seward Date: Mon, 6 Dec 2010 11:40:04 +0000 (+0000) Subject: New command line option: --trace-children-skip-by-arg, which allows X-Git-Tag: svn/VALGRIND_3_7_0~717 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=906915e79beb41ef2d22cf7c2e88bae03842c041;p=thirdparty%2Fvalgrind.git New command line option: --trace-children-skip-by-arg, which allows chase/nochase decisions for child processes to be made on the basis of their argv[] entries rather than on the name of their executables. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11483 --- diff --git a/coregrind/m_main.c b/coregrind/m_main.c index e5871c42c6..d5e762dcb2 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -124,6 +124,9 @@ static void usage_NORETURN ( Bool debug_help ) " --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]\n" " --trace-children-skip=patt1,patt2,... specifies a list of executables\n" " that --trace-children=yes should not trace into\n" +" --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip=\n" +" but check the argv[] entries for children, rather\n" +" than the exe name, to make a follow/no-follow decision\n" " --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n" " --track-fds=no|yes track open file descriptors? [no]\n" " --time-stamp=no|yes add timestamps to log messages? [no]\n" @@ -503,7 +506,10 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd, else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {} - else if VG_STR_CLO (arg, "--trace-children-skip", VG_(clo_trace_children_skip)) {} + else if VG_STR_CLO (arg, "--trace-children-skip", + VG_(clo_trace_children_skip)) {} + else if VG_STR_CLO (arg, "--trace-children-skip-by-arg", + VG_(clo_trace_children_skip_by_arg)) {} else if VG_BINT_CLO(arg, "--vex-iropt-verbosity", VG_(clo_vex_control).iropt_verbosity, 0, 10) {} diff --git a/coregrind/m_options.c b/coregrind/m_options.c index a347c7d492..888e2c782d 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -57,6 +57,7 @@ HChar* VG_(clo_xml_user_comment) = NULL; Bool VG_(clo_demangle) = True; Bool VG_(clo_trace_children) = False; HChar* VG_(clo_trace_children_skip) = NULL; +HChar* VG_(clo_trace_children_skip_by_arg) = NULL; Bool VG_(clo_child_silent_after_fork) = False; Char* VG_(clo_log_fname_expanded) = NULL; Char* VG_(clo_xml_fname_expanded) = NULL; @@ -255,9 +256,13 @@ static HChar const* consume_field ( HChar const* c ) { } /* Should we trace into this child executable (across execve etc) ? - This involves considering --trace-children=, --trace-children-skip= - and the name of the executable. */ -Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name ) + This involves considering --trace-children=, + --trace-children-skip=, --trace-children-skip-by-arg=, and the name + of the executable. 'child_argv' must not include the name of the + executable itself; iow child_argv[0] must be the first arg, if any, + for the child. */ +Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name, + HChar** child_argv ) { // child_exe_name is pulled out of the guest's space. We // should be at least marginally cautious with it, lest it @@ -265,13 +270,13 @@ Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name ) if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0) return VG_(clo_trace_children); // we know narfink - // the main logic // If --trace-children=no, the answer is simply NO. if (! VG_(clo_trace_children)) return False; - // otherwise, return True, unless the exe name matches any of the - // patterns specified by --trace-children-skip=. + // Otherwise, look for other reasons to say NO. First, + // see if the exe name matches any of the patterns specified + // by --trace-children-skip=. if (VG_(clo_trace_children_skip)) { HChar const* last = VG_(clo_trace_children_skip); HChar const* name = (HChar const*)child_exe_name; @@ -294,7 +299,36 @@ Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name ) return False; } } - + + // Check if any of the args match any of the patterns specified + // by --trace-children-skip-by-arg=. + if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) { + HChar const* last = VG_(clo_trace_children_skip_by_arg); + while (*last) { + Int i; + Bool matches; + HChar* patt; + HChar const* first = consume_commas(last); + last = consume_field(first); + if (first == last) + break; + vg_assert(last > first); + /* copy the candidate string into a temporary malloc'd block + so we can use VG_(string_match) on it. */ + patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1); + VG_(memcpy)(patt, first, last - first); + vg_assert(patt[last-first] == 0); + for (i = 0; child_argv[i]; i++) { + matches = VG_(string_match)(patt, child_argv[i]); + if (matches) { + VG_(free)(patt); + return False; + } + } + VG_(free)(patt); + } + } + // --trace-children=yes, and this particular executable isn't // excluded return True; diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 22eae2891b..2a58ea1fd6 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2550,8 +2550,29 @@ PRE(sys_execve) return; } + // debug-only printing + if (0) { + VG_(printf)("ARG1 = %p(%s)\n", (void*)ARG1, (HChar*)ARG1); + if (ARG2) { + VG_(printf)("ARG2 = "); + Int q; + HChar** vec = (HChar**)ARG2; + for (q = 0; vec[q]; q++) + VG_(printf)("%p(%s) ", vec[q], vec[q]); + VG_(printf)("\n"); + } else { + VG_(printf)("ARG2 = null\n"); + } + } + // Decide whether or not we want to follow along - trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG1 ); + { // Make 'child_argv' be a pointer to the child's arg vector + // (skipping the exe name) + HChar** child_argv = (HChar**)ARG2; + if (child_argv && child_argv[0] == NULL) + child_argv = NULL; + trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG1, child_argv ); + } // Do the important checks: it is a file, is executable, permissions are // ok, etc. We allow setuid executables to run only in the case when diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index 06b5701c47..ecfbd9bd31 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -70,6 +70,10 @@ extern Bool VG_(clo_trace_children); /* String containing comma-separated patterns for executable names that should not be traced into even when --trace-children=yes */ extern HChar* VG_(clo_trace_children_skip); +/* The same as VG_(clo_trace_children), except that these patterns are + tested against the arguments for child processes, rather than the + executable name. */ +extern HChar* VG_(clo_trace_children_skip_by_arg); /* After a fork, the child's output can become confusingly intermingled with the parent's output. This is especially problematic when VG_(clo_xml) is True. Setting @@ -220,9 +224,13 @@ extern HChar* VG_(clo_kernel_variant); extern Bool VG_(clo_dsymutil); /* Should we trace into this child executable (across execve etc) ? - This involves considering --trace-children=, --trace-children-skip= - and the name of the executable. */ -extern Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name ); + This involves considering --trace-children=, + --trace-children-skip=, --trace-children-skip-by-arg=, and the name + of the executable. 'child_argv' must not include the name of the + executable itself; iow child_argv[0] must be the first arg, if any, + for the child. */ +extern Bool VG_(should_we_trace_this_child) ( HChar* child_exe_name, + HChar** child_argv ); #endif // __PUB_CORE_OPTIONS_H diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 59eb7878d6..0fb6c9d334 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -663,7 +663,7 @@ in most cases. We group the available options by rough categories. - + This option only has an effect when @@ -687,6 +687,20 @@ in most cases. We group the available options by rough categories. + + + + + + This is the same as + , with one difference: + the decision as to whether to trace into a child process is + made by examining the arguments to the child process, rather + than the name of its executable. + + + diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index 9c6d5feb73..fadaa59537 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -12,6 +12,9 @@ usage: valgrind [options] prog-and-args --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no] --trace-children-skip=patt1,patt2,... specifies a list of executables that --trace-children=yes should not trace into + --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip= + but check the argv[] entries for children, rather + than the exe name, to make a follow/no-follow decision --child-silent-after-fork=no|yes omit child output between fork & exec? [no] --track-fds=no|yes track open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index d27316f1a9..6603e25b44 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -12,6 +12,9 @@ usage: valgrind [options] prog-and-args --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no] --trace-children-skip=patt1,patt2,... specifies a list of executables that --trace-children=yes should not trace into + --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip= + but check the argv[] entries for children, rather + than the exe name, to make a follow/no-follow decision --child-silent-after-fork=no|yes omit child output between fork & exec? [no] --track-fds=no|yes track open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no]