From 8f6d6b5c9bbc9754874b926c0a6f475017b7a9e5 Mon Sep 17 00:00:00 2001 From: Josselin Date: Tue, 19 Nov 2019 11:43:51 +0100 Subject: [PATCH 1/2] Add --only-alive-testcases flag to generate only testcase for alive states Similar behavior for m.finalize(only_alive_states=True) --- manticore/__main__.py | 6 ++++++ manticore/ethereum/cli.py | 2 +- manticore/ethereum/manticore.py | 7 +++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/manticore/__main__.py b/manticore/__main__.py index 3e39ea3fe..a8b042f10 100644 --- a/manticore/__main__.py +++ b/manticore/__main__.py @@ -220,6 +220,12 @@ def positive(value): help="Do not generate testcases for discovered states when analysis finishes", ) + eth_flags.add_argument( + "--only-alive-testcases", + action="store_true", + help="Do not generate testcases for invalid/throwing states when analysis finishes", + ) + config_flags = parser.add_argument_group("Constants") config.add_config_vars_to_argparse(config_flags) diff --git a/manticore/ethereum/cli.py b/manticore/ethereum/cli.py index 1550f3ea6..0cdfdae22 100644 --- a/manticore/ethereum/cli.py +++ b/manticore/ethereum/cli.py @@ -112,7 +112,7 @@ def ethereum_main(args, logger): ) if not args.no_testcases: - m.finalize() + m.finalize(only_alive_states=args.only_alive_testcases) else: m.kill() diff --git a/manticore/ethereum/manticore.py b/manticore/ethereum/manticore.py index 8ed985d4a..a4ff419f5 100644 --- a/manticore/ethereum/manticore.py +++ b/manticore/ethereum/manticore.py @@ -1601,7 +1601,7 @@ def _emit_trace_file(filestream, trace): filestream.write(ln) @ManticoreBase.at_not_running - def finalize(self, procs=None): + def finalize(self, procs=None, only_alive_states=False): """ Terminate and generate testcases for all currently alive states (contract states that cleanly executed to a STOP or RETURN in the last symbolic @@ -1618,8 +1618,11 @@ def finalize(self, procs=None): def finalizer(state_id): st = self._load(state_id) if self.fix_unsound_symbolication(st): - logger.debug("Generating testcase for state_id %d", state_id) last_tx = st.platform.last_transaction + # Do not generate killed state if only_alive_states is True + if only_alive_states and last_tx.result in {"REVERT", "THROW", "TXERROR"}: + return + logger.debug("Generating testcase for state_id %d", state_id) message = last_tx.result if last_tx else "NO STATE RESULT (?)" self.generate_testcase(st, message=message) From ca44a6b3fa5613f61dceb54a4b06c5e9232cd548 Mon Sep 17 00:00:00 2001 From: Josselin Date: Wed, 20 Nov 2019 09:32:23 +0100 Subject: [PATCH 2/2] Finalize: Add docstring --- manticore/ethereum/manticore.py | 1 + 1 file changed, 1 insertion(+) diff --git a/manticore/ethereum/manticore.py b/manticore/ethereum/manticore.py index a4ff419f5..755128880 100644 --- a/manticore/ethereum/manticore.py +++ b/manticore/ethereum/manticore.py @@ -1608,6 +1608,7 @@ def finalize(self, procs=None, only_alive_states=False): transaction). :param procs: force the number of local processes to use in the reporting + :param bool only_alive_states: if True, killed states (revert/throw/txerror) do not generate testscases generation. Uses global configuration constant by default """ if procs is None: