From e1837dc7da78055ab3e355c3e941a7415146c1b8 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 29 Dec 2016 03:36:05 +0300 Subject: Print signal/core dump like shell/make --- tests/test/script/runner/driver.cxx | 96 +++++++++++++++++++++++++++++++----- tests/test/script/runner/status.test | 15 ++++++ 2 files changed, 99 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/tests/test/script/runner/driver.cxx b/tests/test/script/runner/driver.cxx index a82b083..6a3698f 100644 --- a/tests/test/script/runner/driver.cxx +++ b/tests/test/script/runner/driver.cxx @@ -4,6 +4,7 @@ #include // numeric_limits #include +#include // abort() #include #include // endl, *bit #include // istream::traits_type::eof() @@ -11,20 +12,65 @@ #include #include +#include #include #include using namespace std; using namespace butl; +// Call itself recursively causing stack overflow. Parameterized to avoid +// "stack overflow" warning. +// +static void +stack_overflow (bool overflow) +{ + if (overflow) + stack_overflow (true); +} + int main (int argc, char* argv[]) { - // Usage: driver [-i ] [-s ] (-o )* (-e )* - // (-f )* (-d )* + // Usage: driver [-i ] (-o )* (-e )* (-f )* + // (-d )* [(-t (a|m|s|z)) | (-s )] + // + // Execute actions specified by -i, -o, -e, -f, -d options in the order as + // they appear on the command line. After that terminate abnormally if -t + // option is provided, otherwise exit normally with the status specified by + // -s option (0 by default). + // + // -i + // Forward STDIN data to the standard stream denoted by the file + // descriptor. Read and discard if 0. + // + // -o + // Print the line to STDOUT. + // + // -e + // Print the line to STDERR. + // + // -f + // Create an empty file with the path specified. + // + // -d + // Create a directory with the path specified. Create parent directories + // if required. + // + // -t + // Abnormally terminate itself using one of the following methods: + // + // a - call abort() + // m - dereference null-pointer + // s - cause stack overflow using infinite function call recursion + // z - divide integer by zero + // + // -s + // Exit normally with the status specified. The default status is 0. // - int status (256); int ifd (3); + optional status; + char aterm ('\0'); // Abnormal termination method. cout.exceptions (ostream::failbit | ostream::badbit); cerr.exceptions (ostream::failbit | ostream::badbit); @@ -64,7 +110,11 @@ main (int argc, char* argv[]) if (ifd == 0) cin.ignore (numeric_limits::max ()); else if (cin.peek () != istream::traits_type::eof ()) - (ifd == 1 ? cout : cerr) << cin.rdbuf (); + { + ostream& o (ifd == 1 ? cout : cerr); + o << cin.rdbuf (); + o.flush (); + } } else if (o == "-o") { @@ -74,13 +124,6 @@ main (int argc, char* argv[]) { cerr << v << endl; } - else if (o == "-s") - { - assert (status == 256); // Make sure is not set yet. - - status = toi (v); - assert (status >= 0 && status < 256); - } else if (o == "-f") { ofdstream os (v); @@ -90,9 +133,38 @@ main (int argc, char* argv[]) { try_mkdir_p (dir_path (v)); } + else if (o == "-t") + { + assert (aterm == '\0' && !status); // Make sure exit method is not set. + assert (v.size () == 1 && v.find_first_of ("amsz") != string::npos); + aterm = v[0]; + } + else if (o == "-s") + { + assert (!status && aterm == '\0'); // Make sure exit method is not set. + status = toi (v); + } else assert (false); } - return status == 256 ? 0 : status; + switch (aterm) + { + case 'a': abort (); break; + case 'm': + { + int* p (nullptr); + *p = 0; + break; + } + case 's': stack_overflow (true); break; + case 'z': + { + int z (0); + z /= z; + break; + } + } + + return status ? *status : 0; } diff --git a/tests/test/script/runner/status.test b/tests/test/script/runner/status.test index fc0edff..f12cd58 100644 --- a/tests/test/script/runner/status.test +++ b/tests/test/script/runner/status.test @@ -42,3 +42,18 @@ $b 2>>~%EOE% != 0 % info: stderr: test[/\\]1[/\\]stderr% Error EOE + +#\ +: segmentation-fault +: +: Can pop up dialog boxes on Windows or produce coredump on POSIX. Note that +: under Wine some extra info is printed to STDOUT. +: +$c <'$* -t m'; +$b 2>>~%EOE% != 0 +%wine: .+%? +%testscript:1: error: \.\.[/\\]\.\.[/\\]\.\.[/\\]driver(\.exe)? terminated abnormally% +% info: .+% +% info: stdout: test\\1\\stdout%? +EOE +#\ -- cgit v1.1