Skip to content

Commit a986020

Browse files
author
Daniel Kroening
authored
Merge pull request #181 from peterschrammel/fault-localization
basic fault localization
2 parents c4d98e4 + 06d9e51 commit a986020

File tree

9 files changed

+729
-131
lines changed

9 files changed

+729
-131
lines changed

src/cbmc/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
SRC = cbmc_main.cpp cbmc_parse_options.cpp bmc.cpp cbmc_dimacs.cpp \
22
cbmc_languages.cpp counterexample_beautification.cpp \
33
bv_cbmc.cpp symex_bmc.cpp show_vcc.cpp cbmc_solvers.cpp \
4-
xml_interface.cpp bmc_cover.cpp all_properties.cpp
4+
xml_interface.cpp bmc_cover.cpp all_properties.cpp \
5+
fault_localization.cpp
56

67
OBJ += ../ansi-c/ansi-c$(LIBEXT) \
78
../cpp/cpp$(LIBEXT) \

src/cbmc/all_properties.cpp

Lines changed: 40 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -6,109 +6,7 @@ Author: Daniel Kroening, [email protected]
66
77
\*******************************************************************/
88

9-
#include <iostream>
10-
11-
#include <util/time_stopping.h>
12-
#include <util/xml.h>
13-
#include <util/json.h>
14-
15-
#include <solvers/sat/satcheck.h>
16-
#include <solvers/prop/cover_goals.h>
17-
#include <solvers/prop/literal_expr.h>
18-
19-
#include <goto-symex/build_goto_trace.h>
20-
#include <goto-programs/xml_goto_trace.h>
21-
#include <goto-programs/json_goto_trace.h>
22-
23-
#include "bmc.h"
24-
#include "bv_cbmc.h"
25-
26-
/*******************************************************************\
27-
28-
Class: bmc_all_propertiest
29-
30-
Inputs:
31-
32-
Outputs:
33-
34-
Purpose:
35-
36-
\*******************************************************************/
37-
38-
class bmc_all_propertiest:
39-
public cover_goalst::observert,
40-
public messaget
41-
{
42-
public:
43-
bmc_all_propertiest(
44-
const goto_functionst &_goto_functions,
45-
prop_convt &_solver,
46-
bmct &_bmc):
47-
goto_functions(_goto_functions), solver(_solver), bmc(_bmc)
48-
{
49-
}
50-
51-
safety_checkert::resultt operator()();
52-
53-
virtual void goal_covered(const cover_goalst::goalt &);
54-
55-
struct goalt
56-
{
57-
// a property holds if all instances of it are true
58-
typedef std::vector<symex_target_equationt::SSA_stepst::iterator> instancest;
59-
instancest instances;
60-
std::string description;
61-
62-
// if failed, we compute a goto_trace for the first failing instance
63-
enum statust { UNKNOWN, FAILURE, SUCCESS, ERROR } status;
64-
goto_tracet goto_trace;
65-
66-
std::string status_string() const
67-
{
68-
switch(status)
69-
{
70-
case UNKNOWN: return "UNKNOWN";
71-
case FAILURE: return "FAILURE";
72-
case SUCCESS: return "SUCCESS";
73-
case ERROR: return "ERROR";
74-
}
75-
76-
// make some poor compilers happy
77-
assert(false);
78-
return "";
79-
}
80-
81-
explicit goalt(
82-
const goto_programt::instructiont &instruction):
83-
status(statust::UNKNOWN)
84-
{
85-
description=id2string(instruction.source_location.get_comment());
86-
}
87-
88-
goalt():status(statust::UNKNOWN)
89-
{
90-
}
91-
92-
exprt as_expr() const
93-
{
94-
std::vector<exprt> tmp;
95-
for(instancest::const_iterator
96-
it=instances.begin();
97-
it!=instances.end();
98-
it++)
99-
tmp.push_back(literal_exprt((*it)->cond_literal));
100-
return conjunction(tmp);
101-
}
102-
};
103-
104-
typedef std::map<irep_idt, goalt> goal_mapt;
105-
goal_mapt goal_map;
106-
107-
protected:
108-
const goto_functionst &goto_functions;
109-
prop_convt &solver;
110-
bmct &bmc;
111-
};
9+
#include "all_properties_class.h"
11210

11311
/*******************************************************************\
11412
@@ -124,30 +22,23 @@ Function: bmc_all_propertiest::goal_covered
12422

12523
void bmc_all_propertiest::goal_covered(const cover_goalst::goalt &)
12624
{
127-
for(goal_mapt::iterator
128-
g_it=goal_map.begin();
129-
g_it!=goal_map.end();
130-
g_it++)
25+
for(auto &g : goal_map)
13126
{
132-
goalt &g=g_it->second;
133-
13427
// failed already?
135-
if(g.status==goalt::statust::FAILURE) continue;
28+
if(g.second.status==goalt::statust::FAILURE) continue;
13629

13730
// check whether failed
138-
for(goalt::instancest::const_iterator
139-
c_it=g.instances.begin();
140-
c_it!=g.instances.end();
141-
c_it++)
31+
for(auto &c : g.second.instances)
14232
{
143-
literalt cond=(*c_it)->cond_literal;
33+
literalt cond=c->cond_literal;
14434

14535
if(solver.l_get(cond).is_false())
14636
{
147-
g.status=goalt::statust::FAILURE;
148-
symex_target_equationt::SSA_stepst::iterator next=*c_it;
37+
g.second.status=goalt::statust::FAILURE;
38+
symex_target_equationt::SSA_stepst::iterator next=c;
14939
next++; // include the assertion
150-
build_goto_trace(bmc.equation, next, solver, bmc.ns, g.goto_trace);
40+
build_goto_trace(bmc.equation, next, solver, bmc.ns,
41+
g.second.goto_trace);
15142
break;
15243
}
15344
}
@@ -212,6 +103,8 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
212103
}
213104
}
214105

106+
do_before_solving();
107+
215108
cover_goalst cover_goals(solver);
216109

217110
cover_goals.set_message_handler(get_message_handler());
@@ -254,6 +147,35 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
254147
}
255148

256149
// report
150+
report(cover_goals);
151+
152+
if(error)
153+
return safety_checkert::ERROR;
154+
155+
bool safe=(cover_goals.number_covered()==0);
156+
157+
if(safe)
158+
bmc.report_success(); // legacy, might go away
159+
else
160+
bmc.report_failure(); // legacy, might go away
161+
162+
return safe?safety_checkert::SAFE:safety_checkert::UNSAFE;
163+
}
164+
165+
/*******************************************************************\
166+
167+
Function: bmc_all_propertiest::report()
168+
169+
Inputs:
170+
171+
Outputs:
172+
173+
Purpose:
174+
175+
\*******************************************************************/
176+
177+
void bmc_all_propertiest::report(const cover_goalst &cover_goals)
178+
{
257179
switch(bmc.ui)
258180
{
259181
case ui_message_handlert::PLAIN:
@@ -321,18 +243,6 @@ safety_checkert::resultt bmc_all_propertiest::operator()()
321243
break;
322244

323245
}
324-
325-
if(error)
326-
return safety_checkert::ERROR;
327-
328-
bool safe=(cover_goals.number_covered()==0);
329-
330-
if(safe)
331-
bmc.report_success(); // legacy, might go away
332-
else
333-
bmc.report_failure(); // legacy, might go away
334-
335-
return safe?safety_checkert::SAFE:safety_checkert::UNSAFE;
336246
}
337247

338248
/*******************************************************************\

src/cbmc/all_properties_class.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*******************************************************************\
2+
3+
Module: Symbolic Execution of ANSI-C
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include <iostream>
10+
11+
#include <util/time_stopping.h>
12+
#include <util/xml.h>
13+
#include <util/json.h>
14+
15+
#include <solvers/sat/satcheck.h>
16+
#include <solvers/prop/cover_goals.h>
17+
#include <solvers/prop/literal_expr.h>
18+
19+
#include <goto-symex/build_goto_trace.h>
20+
#include <goto-programs/xml_goto_trace.h>
21+
#include <goto-programs/json_goto_trace.h>
22+
23+
#include "bmc.h"
24+
#include "bv_cbmc.h"
25+
26+
/*******************************************************************\
27+
28+
Class: bmc_all_propertiest
29+
30+
Inputs:
31+
32+
Outputs:
33+
34+
Purpose:
35+
36+
\*******************************************************************/
37+
38+
class bmc_all_propertiest:
39+
public cover_goalst::observert,
40+
public messaget
41+
{
42+
public:
43+
bmc_all_propertiest(
44+
const goto_functionst &_goto_functions,
45+
prop_convt &_solver,
46+
bmct &_bmc):
47+
goto_functions(_goto_functions), solver(_solver), bmc(_bmc)
48+
{
49+
}
50+
51+
safety_checkert::resultt operator()();
52+
53+
virtual void goal_covered(const cover_goalst::goalt &);
54+
55+
struct goalt
56+
{
57+
// a property holds if all instances of it are true
58+
typedef std::vector<symex_target_equationt::SSA_stepst::iterator> instancest;
59+
instancest instances;
60+
std::string description;
61+
62+
// if failed, we compute a goto_trace for the first failing instance
63+
enum statust { UNKNOWN, FAILURE, SUCCESS, ERROR } status;
64+
goto_tracet goto_trace;
65+
66+
std::string status_string() const
67+
{
68+
switch(status)
69+
{
70+
case UNKNOWN: return "UNKNOWN";
71+
case FAILURE: return "FAILURE";
72+
case SUCCESS: return "SUCCESS";
73+
case ERROR: return "ERROR";
74+
}
75+
76+
// make some poor compilers happy
77+
assert(false);
78+
return "";
79+
}
80+
81+
explicit goalt(
82+
const goto_programt::instructiont &instruction):
83+
status(statust::UNKNOWN)
84+
{
85+
description=id2string(instruction.source_location.get_comment());
86+
}
87+
88+
goalt():status(statust::UNKNOWN)
89+
{
90+
}
91+
92+
exprt as_expr() const
93+
{
94+
std::vector<exprt> tmp;
95+
for(instancest::const_iterator
96+
it=instances.begin();
97+
it!=instances.end();
98+
it++)
99+
tmp.push_back(literal_exprt((*it)->cond_literal));
100+
return conjunction(tmp);
101+
}
102+
};
103+
104+
typedef std::map<irep_idt, goalt> goal_mapt;
105+
goal_mapt goal_map;
106+
107+
protected:
108+
const goto_functionst &goto_functions;
109+
prop_convt &solver;
110+
bmct &bmc;
111+
112+
virtual void report(const cover_goalst &cover_goals);
113+
virtual void do_before_solving() {}
114+
};
115+

src/cbmc/bmc.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Author: Daniel Kroening, [email protected]
3535
#include <goto-symex/memory_model_pso.h>
3636

3737
#include "counterexample_beautification.h"
38+
#include "fault_localization.h"
3839
#include "bmc.h"
3940

4041
/*******************************************************************\
@@ -512,6 +513,13 @@ safety_checkert::resultt bmct::run(
512513
safety_checkert::ERROR:safety_checkert::SAFE;
513514
}
514515

516+
if(options.get_option("localize-faults")!="")
517+
{
518+
fault_localizationt fault_localization(
519+
goto_functions, *this, options);
520+
return fault_localization();
521+
}
522+
515523
// any properties to check at all?
516524
if(!options.get_bool_option("program-only") &&
517525
symex.remaining_vccs==0)

src/cbmc/bmc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class bmct:public safety_checkert
108108

109109
friend class bmc_all_propertiest;
110110
friend class bmc_covert;
111+
friend class fault_localizationt;
111112
};
112113

113114
#endif

src/cbmc/cbmc_parse_options.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options)
191191
cmdline.isset("property"))
192192
options.set_option("trace", true);
193193

194+
if(cmdline.isset("localize-faults"))
195+
options.set_option("localize-faults", true);
196+
if(cmdline.isset("localize-faults-method"))
197+
options.set_option("localize-faults-method",
198+
cmdline.get_value("localize-faults-method"));
199+
194200
if(cmdline.isset("unwind"))
195201
options.set_option("unwind", cmdline.get_value("unwind"));
196202

@@ -1158,6 +1164,7 @@ void cbmc_parse_optionst::help()
11581164
"Backend options:\n"
11591165
" --dimacs generate CNF in DIMACS format\n"
11601166
" --beautify beautify the counterexample (greedy heuristic)\n"
1167+
" --localize-faults localize faults (experimental)\n"
11611168
" --smt1 use default SMT1 solver (obsolete)\n"
11621169
" --smt2 use default SMT2 solver (Z3)\n"
11631170
" --boolector use Boolector\n"

src/cbmc/cbmc_parse_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class optionst;
5353
"(string-abstraction)(no-arch)(arch):" \
5454
"(round-to-nearest)(round-to-plus-inf)(round-to-minus-inf)(round-to-zero)" \
5555
"(graphml-cex):" \
56+
"(localize-faults)(localize-faults-method):" \
5657
"(floatbv)(all-claims)(all-properties)(decide)" // legacy, and will eventually disappear
5758

5859
class cbmc_parse_optionst:

0 commit comments

Comments
 (0)