]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
New command line option: --trace-children-skip-by-arg, which allows
authorJulian Seward <jseward@acm.org>
Mon, 6 Dec 2010 11:40:04 +0000 (11:40 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 6 Dec 2010 11:40:04 +0000 (11:40 +0000)
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

coregrind/m_main.c
coregrind/m_options.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/pub_core_options.h
docs/xml/manual-core.xml
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp

index e5871c42c6b949ec324bec01643a2dae3acb35fd..d5e762dcb276bcefa7a82c549af9d4b1815d2717 100644 (file)
@@ -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) {}
index a347c7d492985583b0c78e5d3abcc3accb2ca2a4..888e2c782d28a0968963bea6e0ac4989c0ca320a 100644 (file)
@@ -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;
index 22eae2891b5b4e5e60fcc15b992a25172025a1f4..2a58ea1fd67feaf46c88229c08a7c138d4ae110b 100644 (file)
@@ -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
index 06b5701c47873da69bff8cd59c58e04b82938521..ecfbd9bd31e03e824925f58f2e8050956d9489ab 100644 (file)
@@ -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
 
index 59eb7878d62d6dceb7ed9a93adb17b0d497c92b0..0fb6c9d33423a3a29fce6056c8a072f7b63c4350 100644 (file)
@@ -663,7 +663,7 @@ in most cases.  We group the available options by rough categories.</para>
 
   <varlistentry id="opt.trace-children-skip" xreflabel="--trace-children-skip">
     <term>
-      <option><![CDATA[--trace-children-skip=patt1,patt2 ]]></option>
+      <option><![CDATA[--trace-children-skip=patt1,patt2,... ]]></option>
     </term>
     <listitem>
       <para>This option only has an effect when 
@@ -687,6 +687,20 @@ in most cases.  We group the available options by rough categories.</para>
     </listitem>
   </varlistentry>
 
+  <varlistentry id="opt.trace-children-skip-by-arg"
+                xreflabel="--trace-children-skip-by-arg">
+    <term>
+      <option><![CDATA[--trace-children-skip-by-arg=patt1,patt2,... ]]></option>
+    </term>
+    <listitem>
+      <para>This is the same as  
+        <option>--trace-children-skip</option>, 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.</para>
+    </listitem>
+  </varlistentry>
+
   <varlistentry id="opt.child-silent-after-fork"
                 xreflabel="--child-silent-after-fork">
     <term>
index 9c6d5feb73237b9bdebc872d63ed29f4ecda1a59..fadaa59537135a220ab787538d4ed4e21efdb17d 100644 (file)
@@ -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]
index d27316f1a96b8ecd870cfd6ae9b5ac38db2bcb02..6603e25b44aa120c89dcbc0074bc58d9aeaf730d 100644 (file)
@@ -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]