Skip to content

Improved invariants #1063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ install:

script:
- if [ -e bin/gcc ] ; then export PATH=$PWD/bin:$PATH ; fi ;
COMMAND="env UBSAN_OPTIONS=print_stacktrace=1 make -C regression test" &&
COMMAND="env UBSAN_OPTIONS=print_stacktrace=1 make -C regression test CXX=\"$COMPILER\" CXXFLAGS=\"-Wall -Werror -pedantic -O2 -g $EXTRA_CXXFLAGS\"" &&
eval ${PRE_COMMAND} ${COMMAND}
- COMMAND="make -C unit CXX=\"$COMPILER\" CXXFLAGS=\"-Wall -Werror -pedantic -O2 -g $EXTRA_CXXFLAGS\" -j2" &&
eval ${PRE_COMMAND} ${COMMAND}
Expand Down
1 change: 1 addition & 0 deletions regression/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ DIRS = ansi-c \
goto-instrument \
goto-instrument-typedef \
goto-diff \
invariants \
test-script \
# Empty last line

Expand Down
4 changes: 0 additions & 4 deletions regression/cbmc/invariant-failure/main.c

This file was deleted.

1 change: 1 addition & 0 deletions regression/invariants/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
driver
32 changes: 32 additions & 0 deletions regression/invariants/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
default: tests.log

SRC = driver.cpp

INCLUDES = -I ../../src

OBJ += ../../src/util/util$(LIBEXT)

include ../../src/config.inc
include ../../src/common

test: driver$(EXEEXT)
@if ! ../test.pl -c ../driver ; then \
../failed-tests-printer.pl ; \
exit 1 ; \
fi

tests.log: ../test.pl driver$(EXEEXT)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know - but I don't think the test.pl is required in the dependency list?

@if ! ../test.pl -c ../driver ; then \
../failed-tests-printer.pl ; \
exit 1 ; \
fi

show:
@for dir in *; do \
if [ -d "$$dir" ]; then \
vim -o "$$dir/*.c" "$$dir/*.out"; \
fi; \
done;

driver$(EXEEXT): $(OBJ)
$(LINKBIN)
88 changes: 88 additions & 0 deletions regression/invariants/driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************************\

Module: Invariant violation testing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should really go into /unit.

Copy link
Contributor

@thk123 thk123 Jun 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not - it isn't a unit test since it the test involves reading from stderr. Therefore the test must be outside the executable.

In fact I believe this is one of the main problems with the use of abort() rather than throw - it makes it impossible to unit test functions that should fail.

To go back to @martin-cs's case for abort so no one can accidentally write a catch(...) and continue. I think it is more likely someone modifies the original function to skip over the invariant for some route even though it should still be true happen. A unit test that verifies the function still fails on incorrect input would catch that, but would be impossible to write without throw.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I forgot that all the compile switches have gone now.


Author: Chris Smowton, [email protected]

\*******************************************************************/

/// \file
/// Invariant violation testing

#include <string>
#include <sstream>
#include <util/invariant.h>

/// An example of structured invariants-- this contains fields to
/// describe the error to a catcher, and also produces a human-readable
/// message containing all the information for use by the current aborting
/// invariant implementation and/or any generic error catcher in the future.
class structured_error_testt: public invariant_failedt
{
std::string pretty_print(int code, const std::string &desc)
{
std::ostringstream ret;
ret << "Error code: " << code
<< "\nDescription: " << desc;
return ret.str();
}

public:
const int error_code;
const std::string description;

structured_error_testt(
const std::string &file,
const std::string &function,
int line,
const std::string &backtrace,
int code,
const std::string &_description):
invariant_failedt(
file,
function,
line,
backtrace,
pretty_print(code, _description)),
error_code(code),
description(_description)
{
}
};

/// Causes an invariant failure dependent on first argument value.
/// One ignored argument is accepted to conform with the test.pl script,
/// which would be the input source file for other cbmc driver programs.
/// Returns 1 on unexpected arguments.
int main(int argc, char** argv)
{
if(argc!=3)
return 1;
std::string arg=argv[1];
if(arg=="structured")
INVARIANT_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="string")
INVARIANT(false, "Test invariant failure");
else if(arg=="precondition-structured")
PRECONDITION_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="precondition-string")
PRECONDITION(false);
else if(arg=="postcondition-structured")
POSTCONDITION_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="postcondition-string")
POSTCONDITION(false);
else if(arg=="check-return-structured")
CHECK_RETURN_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="check-return-string")
CHECK_RETURN(false);
else if(arg=="unreachable-structured")
UNREACHABLE_STRUCTURED(structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="unreachable-string")
UNREACHABLE;
else if(arg=="data-invariant-structured")
DATA_INVARIANT_STRUCTURED(false, structured_error_testt, 1, "Structured error"); // NOLINT
else if(arg=="data-invariant-string")
DATA_INVARIANT(false, "Test invariant failure");
else
return 1;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
CORE
main.c
--test-invariant-failure
dummy_parameter.c
string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Test invariant failure
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
Expand Down
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure10/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
unreachable-structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
12 changes: 12 additions & 0 deletions regression/invariants/invariant-failure11/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
dummy_parameter.c
data-invariant-string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Test invariant failure
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure12/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
data-invariant-structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure2/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
12 changes: 12 additions & 0 deletions regression/invariants/invariant-failure3/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
dummy_parameter.c
precondition-string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Precondition
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure4/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
precondition-structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
12 changes: 12 additions & 0 deletions regression/invariants/invariant-failure5/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
dummy_parameter.c
postcondition-string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Postcondition
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure6/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
postcondition-structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
12 changes: 12 additions & 0 deletions regression/invariants/invariant-failure7/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
dummy_parameter.c
check-return-string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Check return value
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
13 changes: 13 additions & 0 deletions regression/invariants/invariant-failure8/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
dummy_parameter.c
check-return-structured
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Invariant check failed
Error code: 1
Description: Structured error
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
12 changes: 12 additions & 0 deletions regression/invariants/invariant-failure9/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
dummy_parameter.c
unreachable-string
^EXIT=(0|127|134|137)$
^SIGNAL=0$
--- begin invariant violation report ---
Unreachable
Invariant check failed
^(Backtrace)|(Backtraces not supported)$
--
^warning: ignoring
^VERIFICATION SUCCESSFUL$
21 changes: 0 additions & 21 deletions src/cbmc/cbmc_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,6 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
exit(1); // should contemplate EX_USAGE from sysexits.h
}

// Test only; do not use for input validation
if(cmdline.isset("test-invariant-failure"))
{
// Have to catch this as the default handling of uncaught exceptions
// on windows appears to be silent termination.
try
{
INVARIANT(0, "Test invariant failure");
}
catch (const invariant_failedt &e)
{
std::cerr << e.what();
exit(0); // should contemplate EX_OK from sysexits.h
}
catch (...)
{
error() << "Unexpected exception type\n";
}
exit(1);
}

if(cmdline.isset("program-only"))
options.set_option("program-only", true);

Expand Down
1 change: 0 additions & 1 deletion src/cbmc/cbmc_parse_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class optionst;
"(java-cp-include-files):" \
"(localize-faults)(localize-faults-method):" \
"(lazy-methods)" \
"(test-invariant-failure)" \
"(fixedbv)(floatbv)(all-claims)(all-properties)" // legacy, and will eventually disappear // NOLINT(whitespace/line_length)

class cbmc_parse_optionst:
Expand Down
Loading