]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Optionally exit on the first error with --exit-on-first-error=<yes|no>.
authorIvo Raisr <ivosh@ivosh.net>
Sat, 4 Nov 2017 13:29:48 +0000 (14:29 +0100)
committerIvo Raisr <ivosh@ivosh.net>
Sat, 4 Nov 2017 13:31:22 +0000 (14:31 +0100)
Fixes BZ#385939.
Slightly modified patch by: Fauchet Gauthier <gauthier.fauchet@free.fr>

13 files changed:
NEWS
coregrind/m_errormgr.c
coregrind/m_main.c
coregrind/m_options.c
coregrind/pub_core_options.h
docs/xml/manual-core.xml
memcheck/tests/Makefile.am
memcheck/tests/exit_on_first_error.stderr.exp [new file with mode: 0644]
memcheck/tests/exit_on_first_error.vgtest [new file with mode: 0644]
memcheck/tests/exit_on_first_error_with_xml.stderr.exp [new file with mode: 0644]
memcheck/tests/exit_on_first_error_with_xml.vgtest [new file with mode: 0644]
none/tests/cmdline1.stdout.exp
none/tests/cmdline2.stdout.exp

diff --git a/NEWS b/NEWS
index d6acccd4ca412d82a0f5c379b4ae282174239be5..436e287ce92f02c8b30841ea0bb2a4b77b8049a7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,7 @@ where XXXXXX is the bug number as listed below.
 385334  PPC64, fix vpermr, xxperm, xxpermr mask value.
 385868  glibc ld.so _dl_runtime_resolve_avx_slow conditional jump warning.
 385912  none/tests/rlimit_nofile fails on newer glibc/kernel.
+385939  Optionally exit on the first error
 386397  PPC64, valgrind truncates powerpc timebase to 32-bits.
 
 n-i-bz  Fix missing workq_ops operations (macOS)
index fd900ee660064be1241f2662971ef9c3f25204a8..c1f8006cfc5c2d67b5cc5eaecc92e1b2000ec873 100644 (file)
@@ -511,11 +511,10 @@ Bool VG_(is_action_requested) ( const HChar* action, Bool* clo )
 }
 
 
-/* Do text-mode actions on error, that is, immediately after an error
-   is printed.  These are:
+/* Do actions on error, that is, immediately after an error is printed.
+   These are:
    * possibly, call the GDB server
    * possibly, generate a suppression.
-   Note this should not be called in XML mode! 
 */
 static 
 void do_actions_on_error(const Error* err, Bool allow_db_attach)
@@ -540,6 +539,14 @@ void do_actions_on_error(const Error* err, Bool allow_db_attach)
    }
    if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
       VG_(clo_gen_suppressions) = 0;
+
+   if (VG_(clo_exit_on_first_error)) {
+      if (VG_(clo_xml))
+         VG_(printf_xml)("</valgrindoutput>\n");
+      VG_(umsg)("\n");
+      VG_(umsg)("Exit program on first error (--exit-on-first-error=yes)\n");
+      VG_(client_exit)( VG_(clo_error_exitcode) );
+   }
 }
 
 
@@ -566,6 +573,8 @@ void do_actions_on_error(const Error* err, Bool allow_db_attach)
 
    * prints the tool-specific parts of the message
 
+   In both modes:
+
    * calls do_actions_on_error.  This optionally does a gdbserver call
      and optionally prints a suppression; both of these may require user input.
 */
index a37bbb67268a8315cb74af7a767161d1d4e34bc0..4526b1259d248a8a0262fa205ffb4672ad53ba5d 100644 (file)
@@ -125,6 +125,7 @@ static void usage_NORETURN ( Bool debug_help )
 "    --demangle=no|yes         automatically demangle C++ names? [yes]\n"
 "    --num-callers=<number>    show <number> callers in stack traces [12]\n"
 "    --error-limit=no|yes      stop showing new errors if too many? [yes]\n"
+"    --exit-on-first-error=no|yes exit code on the first error found? [no]\n"
 "    --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
 "    --error-markers=<begin>,<end> add lines with begin/end markers before/after\n"
 "                              each error output in plain text mode [none]\n"
@@ -252,7 +253,7 @@ static void usage_NORETURN ( Bool debug_help )
 "    --core-redzone-size=<number>  set minimum size of redzones added before/after\n"
 "                              heap blocks allocated for Valgrind internal use (in bytes) [4]\n"
 "    --wait-for-gdb=yes|no     pause on startup to wait for gdb attach\n"
-"    --sym-offsets=yes|no      show syms in form 'name+offset' ? [no]\n"
+"    --sym-offsets=yes|no      show syms in form 'name+offset'? [no]\n"
 "    --command-line-only=no|yes  only use command line options [no]\n"
 "\n"
 "  Vex options for all Valgrind tools:\n"
@@ -601,6 +602,7 @@ void main_process_cmd_line_options( void )
       else if VG_BOOL_CLO(arg, "--demangle",       VG_(clo_demangle)) {}
       else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
       else if VG_BOOL_CLO(arg, "--error-limit",    VG_(clo_error_limit)) {}
+      else if VG_BOOL_CLO(arg, "--exit-on-first-error", VG_(clo_exit_on_first_error)) {}
       else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
       else if VG_STR_CLO (arg, "--error-markers",  tmp_str) {
          Int m;
@@ -934,6 +936,11 @@ void main_process_cmd_line_options( void )
          "Can't use --gen-suppressions= with %s\n"
          "because it doesn't generate errors.\n", VG_(details).name);
    }
+   if ((VG_(clo_exit_on_first_error)) &&
+       (VG_(clo_error_exitcode)==0)) {
+      VG_(fmsg_bad_option)("--exit-on-first-error=yes",
+         "You must define a non nul exit error code, with --error-exitcode=...\n");
+   }
 
 #  if !defined(VGO_darwin)
    if (VG_(clo_resync_filter) != 0) {
index 1bf2cc02e8311ab5a7eaa512501309d653f594df..bae161baed90dcb3706d0ac1245d582bc4f6edca 100644 (file)
@@ -52,6 +52,7 @@ VexRegisterUpdates VG_(clo_px_file_backed) = VexRegUpd_INVALID;
 Bool   VG_(clo_error_limit)    = True;
 Int    VG_(clo_error_exitcode) = 0;
 HChar *VG_(clo_error_markers)[2] = {NULL, NULL};
+Bool   VG_(clo_exit_on_first_error) = False;
 
 #if defined(VGPV_arm_linux_android) \
     || defined(VGPV_x86_linux_android) \
index 88eeaf4d09c5f57642df0f96f192e2b6b7b669e2..cc6bb835c553818fbcde0a76c4dab0d59cdd88ca 100644 (file)
@@ -44,6 +44,8 @@ extern const HChar *VG_(clo_toolname);
 
 /* Should we stop collecting errors if too many appear?  default: YES */
 extern Bool  VG_(clo_error_limit);
+/* Should we exit if an error appears?  default: NO */
+extern Bool  VG_(clo_exit_on_first_error);
 /* Alternative exit code to hand to parent if errors were found.
    default: 0 (no, return the application's exit code in the normal
    way. */
index 4cd26a52006e766f0135242d29482e8288f64e76..ff596b52147523a4d20a773064847215e0b737fa 100644 (file)
@@ -1180,6 +1180,19 @@ that can report errors, e.g. Memcheck, but not Cachegrind.</para>
     </listitem>
   </varlistentry>
 
+  <varlistentry id="opt.exit-on-first-error" xreflabel="--exit-on-first-error">
+    <term>
+      <option><![CDATA[--exit-on-first-error=<yes|no> [default: no] ]]></option>
+    </term>
+    <listitem>
+      <para>If this option is enabled, Valgrind exits on the first error.
+      A nonzero exit value must be defined using
+      <computeroutput>--error-exitcode</computeroutput> option.
+      Useful if you are running regression tests or have some other
+      automated test machinery.</para>
+    </listitem>
+  </varlistentry>
+
   <varlistentry id="opt.error-markers" xreflabel="--error-markers">
     <term>
       <option><![CDATA[--error-markers=<begin>,<end> [default: none]]]></option>
index b9ba67b25851503849d24fa38e8d91fdaf7955e8..dbbeabff1956a7905b0d5e5016f9884e6457c18e 100644 (file)
@@ -80,6 +80,10 @@ EXTRA_DIST = \
        atomic_incs.stdout.exp-32bit atomic_incs.stdout.exp-64bit \
        badaddrvalue.stderr.exp \
        badaddrvalue.stdout.exp badaddrvalue.vgtest \
+        exit_on_first_error.stderr.exp \
+        exit_on_first_error.vgtest \
+        exit_on_first_error_with_xml.stderr.exp \
+        exit_on_first_error_with_xml.vgtest \
        badfree-2trace.stderr.exp badfree-2trace.vgtest \
        badfree.stderr.exp badfree.vgtest \
        badfree3.stderr.exp badfree3.vgtest \
diff --git a/memcheck/tests/exit_on_first_error.stderr.exp b/memcheck/tests/exit_on_first_error.stderr.exp
new file mode 100644 (file)
index 0000000..f086181
--- /dev/null
@@ -0,0 +1,9 @@
+
+Invalid write of size 1
+   ...
+ Address 0x........ is 1 bytes before a block of size 8 alloc'd
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   ...
+
+
+Exit program on first error (--exit-on-first-error=yes)
diff --git a/memcheck/tests/exit_on_first_error.vgtest b/memcheck/tests/exit_on_first_error.vgtest
new file mode 100644 (file)
index 0000000..8ce05b1
--- /dev/null
@@ -0,0 +1,2 @@
+prog: badaddrvalue
+vgopts: --exit-on-first-error=yes --error-exitcode=3
diff --git a/memcheck/tests/exit_on_first_error_with_xml.stderr.exp b/memcheck/tests/exit_on_first_error_with_xml.stderr.exp
new file mode 100644 (file)
index 0000000..3a02ca5
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>memcheck</protocoltool>
+
+<preamble>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+  <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>memcheck</tool>
+
+<args>
+  <vargv>...</vargv>
+  <argv>
+    <exe>./badaddrvalue</exe>
+  </argv>
+</args>
+
+<status>
+  <state>RUNNING</state>
+  <time>...</time>
+</status>
+
+<error>
+  <unique>0x........</unique>
+  <tid>...</tid>
+  <kind>InvalidWrite</kind>
+  <what>Invalid write of size 1</what>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>badaddrvalue.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+  <auxwhat>Address 0x........ is 1 bytes before a block of size 8 alloc'd</auxwhat>
+  <stack>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>malloc</fn>
+      <dir>...</dir>
+      <file>vg_replace_malloc.c</file>
+      <line>...</line>
+    </frame>
+    <frame>
+      <ip>0x........</ip>
+      <obj>...</obj>
+      <fn>main</fn>
+      <dir>...</dir>
+      <file>badaddrvalue.c</file>
+      <line>...</line>
+    </frame>
+  </stack>
+</error>
+
+</valgrindoutput>
diff --git a/memcheck/tests/exit_on_first_error_with_xml.vgtest b/memcheck/tests/exit_on_first_error_with_xml.vgtest
new file mode 100644 (file)
index 0000000..9247bf8
--- /dev/null
@@ -0,0 +1,4 @@
+prog: badaddrvalue
+vgopts: --exit-on-first-error=yes --error-exitcode=3  --xml=yes --xml-fd=2 --log-file=/dev/null
+stderr_filter: filter_xml
+
index e35b38274de6c31c7a36f5481b8c5d4d4262e0d0..248511936db8b97966a847af8b5d6448ee684d2c 100644 (file)
@@ -39,6 +39,7 @@ usage: valgrind [options] prog-and-args
     --demangle=no|yes         automatically demangle C++ names? [yes]
     --num-callers=<number>    show <number> callers in stack traces [12]
     --error-limit=no|yes      stop showing new errors if too many? [yes]
+    --exit-on-first-error=no|yes exit code on the first error found? [no]
     --error-exitcode=<number> exit code to return if errors found [0=disable]
     --error-markers=<begin>,<end> add lines with begin/end markers before/after
                               each error output in plain text mode [none]
index 21bec9fbd0df9f76121dd760ad624a7e87f393f0..df8f85a6843d6d6cbbb78bd9fb4db57578b6adbc 100644 (file)
@@ -39,6 +39,7 @@ usage: valgrind [options] prog-and-args
     --demangle=no|yes         automatically demangle C++ names? [yes]
     --num-callers=<number>    show <number> callers in stack traces [12]
     --error-limit=no|yes      stop showing new errors if too many? [yes]
+    --exit-on-first-error=no|yes exit code on the first error found? [no]
     --error-exitcode=<number> exit code to return if errors found [0=disable]
     --error-markers=<begin>,<end> add lines with begin/end markers before/after
                               each error output in plain text mode [none]
@@ -164,7 +165,7 @@ usage: valgrind [options] prog-and-args
     --core-redzone-size=<number>  set minimum size of redzones added before/after
                               heap blocks allocated for Valgrind internal use (in bytes) [4]
     --wait-for-gdb=yes|no     pause on startup to wait for gdb attach
-    --sym-offsets=yes|no      show syms in form 'name+offset' ? [no]
+    --sym-offsets=yes|no      show syms in form 'name+offset'? [no]
     --command-line-only=no|yes  only use command line options [no]
 
   Vex options for all Valgrind tools: