From: Ivo Raisr Date: Sat, 4 Nov 2017 13:29:48 +0000 (+0100) Subject: Optionally exit on the first error with --exit-on-first-error=. X-Git-Tag: VALGRIND_3_14_0~208 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c46053cc386be5757420abbd4b8a8cc6219ed33f;p=thirdparty%2Fvalgrind.git Optionally exit on the first error with --exit-on-first-error=. Fixes BZ#385939. Slightly modified patch by: Fauchet Gauthier --- diff --git a/NEWS b/NEWS index d6acccd4ca..436e287ce9 100644 --- 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) diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c index fd900ee660..c1f8006cfc 100644 --- a/coregrind/m_errormgr.c +++ b/coregrind/m_errormgr.c @@ -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)("\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. */ diff --git a/coregrind/m_main.c b/coregrind/m_main.c index a37bbb6726..4526b1259d 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -125,6 +125,7 @@ static void usage_NORETURN ( Bool debug_help ) " --demangle=no|yes automatically demangle C++ names? [yes]\n" " --num-callers= show 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= exit code to return if errors found [0=disable]\n" " --error-markers=, 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= 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) { diff --git a/coregrind/m_options.c b/coregrind/m_options.c index 1bf2cc02e8..bae161baed 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -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) \ diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index 88eeaf4d09..cc6bb835c5 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -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. */ diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 4cd26a5200..ff596b5214 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -1180,6 +1180,19 @@ that can report errors, e.g. Memcheck, but not Cachegrind. + + + + + + If this option is enabled, Valgrind exits on the first error. + A nonzero exit value must be defined using + --error-exitcode option. + Useful if you are running regression tests or have some other + automated test machinery. + + + diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index b9ba67b258..dbbeabff19 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -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 index 0000000000..f08618193e --- /dev/null +++ b/memcheck/tests/exit_on_first_error.stderr.exp @@ -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 index 0000000000..8ce05b17bf --- /dev/null +++ b/memcheck/tests/exit_on_first_error.vgtest @@ -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 index 0000000000..3a02ca5323 --- /dev/null +++ b/memcheck/tests/exit_on_first_error_with_xml.stderr.exp @@ -0,0 +1,67 @@ + + + + +4 +memcheck + + + ... + ... + ... + ... + + +... +... +memcheck + + + ... + + ./badaddrvalue + + + + + RUNNING + + + + + 0x........ + ... + InvalidWrite + Invalid write of size 1 + + + 0x........ + ... + main + ... + badaddrvalue.c + ... + + + Address 0x........ is 1 bytes before a block of size 8 alloc'd + + + 0x........ + ... + malloc + ... + vg_replace_malloc.c + ... + + + 0x........ + ... + main + ... + badaddrvalue.c + ... + + + + + 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 index 0000000000..9247bf88a1 --- /dev/null +++ b/memcheck/tests/exit_on_first_error_with_xml.vgtest @@ -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 + diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index e35b38274d..248511936d 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -39,6 +39,7 @@ usage: valgrind [options] prog-and-args --demangle=no|yes automatically demangle C++ names? [yes] --num-callers= show 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= exit code to return if errors found [0=disable] --error-markers=, add lines with begin/end markers before/after each error output in plain text mode [none] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index 21bec9fbd0..df8f85a684 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -39,6 +39,7 @@ usage: valgrind [options] prog-and-args --demangle=no|yes automatically demangle C++ names? [yes] --num-callers= show 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= exit code to return if errors found [0=disable] --error-markers=, 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= 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: