Skip to content

Commit a354513

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#2510 from polgreen/hex_trace
represent numerical values in CBMC trace in hex
2 parents 3545be4 + a018652 commit a354513

File tree

6 files changed

+137
-44
lines changed

6 files changed

+137
-44
lines changed

regression/cbmc/hex_trace/main.c

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
int main()
2+
{
3+
int a;
4+
unsigned int b;
5+
a = 0;
6+
a = -100;
7+
a = 2147483647;
8+
b = a*2;
9+
a = -2147483647;
10+
__CPROVER_assert(0,"");
11+
12+
}

regression/cbmc/hex_trace/test.desc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--trace-hex --trace
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
a=0 \s*\(0x0\)
7+
b=0ul? \s*\(0x0\)
8+
a=-100 \s*\(0xFFFFFF9C\)
9+
a=2147483647 \s*\(0x7FFFFFFF\)
10+
b=4294967294ul? \s*\(0xFFFFFFFE\)
11+
a=-2147483647 \s*\(0x80000001\)
12+
^VERIFICATION FAILED$
13+
--
14+
^warning: ignoring

src/cbmc/all_properties.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ void bmc_all_propertiest::report(const cover_goalst &cover_goals)
175175
if(g.second.status==goalt::statust::FAILURE)
176176
{
177177
result() << "\n" << "Trace for " << g.first << ":" << "\n";
178-
show_goto_trace(result(), bmc.ns, g.second.goto_trace);
178+
show_goto_trace(
179+
result(), bmc.ns, g.second.goto_trace, bmc.trace_options());
179180
}
180181
}
181182
result() << eom;

src/cbmc/bmc.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void bmct::error_trace()
5555
{
5656
case ui_message_handlert::uit::PLAIN:
5757
result() << "Counterexample:" << eom;
58-
show_goto_trace(result(), ns, goto_trace);
58+
show_goto_trace(result(), ns, goto_trace, trace_options());
5959
result() << eom;
6060
break;
6161

src/goto-programs/goto_trace.cpp

+76-26
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,50 @@ void goto_trace_stept::output(
103103

104104
out << '\n';
105105
}
106+
/// Returns the numeric representation of an expression, based on
107+
/// options. The default is binary without a base-prefix. Setting
108+
/// options.hex_representation to be true outputs hex format. Setting
109+
/// options.base_prefix to be true appends either 0b or 0x to the number
110+
/// to indicate the base
111+
/// \param expr: expression to get numeric representation from
112+
/// \param options: configuration options
113+
/// \return a string with the numeric representation
114+
static std::string
115+
numeric_representation(const exprt &expr, const trace_optionst &options)
116+
{
117+
std::string result;
118+
std::string prefix;
119+
if(options.hex_representation)
120+
{
121+
mp_integer value_int =
122+
binary2integer(id2string(to_constant_expr(expr).get_value()), false);
123+
result = integer2string(value_int, 16);
124+
prefix = "0x";
125+
}
126+
else
127+
{
128+
prefix = "0b";
129+
result = expr.get_string(ID_value);
130+
}
106131

107-
std::string trace_value_binary(
132+
std::ostringstream oss;
133+
std::string::size_type i = 0;
134+
for(const auto c : result)
135+
{
136+
oss << c;
137+
if(++i % 8 == 0 && result.size() != i)
138+
oss << ' ';
139+
}
140+
if(options.base_prefix)
141+
return prefix + oss.str();
142+
else
143+
return oss.str();
144+
}
145+
146+
std::string trace_numeric_value(
108147
const exprt &expr,
109-
const namespacet &ns)
148+
const namespacet &ns,
149+
const trace_optionst &options)
110150
{
111151
const typet &type=ns.follow(expr.type());
112152

@@ -123,18 +163,8 @@ std::string trace_value_binary(
123163
type.id()==ID_c_enum ||
124164
type.id()==ID_c_enum_tag)
125165
{
126-
const std::string & str = expr.get_string(ID_value);
127-
128-
std::ostringstream oss;
129-
std::string::size_type i = 0;
130-
for(const auto c : str)
131-
{
132-
oss << c;
133-
if(++i % 8 == 0 && str.size() != i)
134-
oss << ' ';
135-
}
136-
137-
return oss.str();
166+
const std::string &str = numeric_representation(expr, options);
167+
return str;
138168
}
139169
else if(type.id()==ID_bool)
140170
{
@@ -157,7 +187,7 @@ std::string trace_value_binary(
157187
result="{ ";
158188
else
159189
result+=", ";
160-
result+=trace_value_binary(*it, ns);
190+
result+=trace_numeric_value(*it, ns, options);
161191
}
162192

163193
return result+" }";
@@ -170,15 +200,15 @@ std::string trace_value_binary(
170200
{
171201
if(it!=expr.operands().begin())
172202
result+=", ";
173-
result+=trace_value_binary(*it, ns);
203+
result+=trace_numeric_value(*it, ns, options);
174204
}
175205

176206
return result+" }";
177207
}
178208
else if(expr.id()==ID_union)
179209
{
180-
assert(expr.operands().size()==1);
181-
return trace_value_binary(expr.op0(), ns);
210+
PRECONDITION(expr.operands().size()==1);
211+
return trace_numeric_value(expr.op0(), ns, options);
182212
}
183213

184214
return "?";
@@ -189,7 +219,8 @@ void trace_value(
189219
const namespacet &ns,
190220
const ssa_exprt &lhs_object,
191221
const exprt &full_lhs,
192-
const exprt &value)
222+
const exprt &value,
223+
const trace_optionst &options)
193224
{
194225
irep_idt identifier;
195226

@@ -205,7 +236,7 @@ void trace_value(
205236
value_string=from_expr(ns, identifier, value);
206237

207238
// the binary representation
208-
value_string+=" ("+trace_value_binary(value, ns)+")";
239+
value_string += " (" + trace_numeric_value(value, ns, options) + ")";
209240
}
210241

211242
out << " "
@@ -247,7 +278,8 @@ bool is_index_member_symbol(const exprt &src)
247278
void show_goto_trace(
248279
std::ostream &out,
249280
const namespacet &ns,
250-
const goto_tracet &goto_trace)
281+
const goto_tracet &goto_trace,
282+
const trace_optionst &options)
251283
{
252284
unsigned prev_step_nr=0;
253285
bool first_step=true;
@@ -315,10 +347,20 @@ void show_goto_trace(
315347
// see if the full lhs is something clean
316348
if(is_index_member_symbol(step.full_lhs))
317349
trace_value(
318-
out, ns, step.lhs_object, step.full_lhs, step.full_lhs_value);
350+
out,
351+
ns,
352+
step.lhs_object,
353+
step.full_lhs,
354+
step.full_lhs_value,
355+
options);
319356
else
320357
trace_value(
321-
out, ns, step.lhs_object, step.lhs_object, step.lhs_object_value);
358+
out,
359+
ns,
360+
step.lhs_object,
361+
step.lhs_object,
362+
step.lhs_object_value,
363+
options);
322364
}
323365
break;
324366

@@ -330,7 +372,8 @@ void show_goto_trace(
330372
show_state_header(out, step, step.pc->source_location, step.step_nr);
331373
}
332374

333-
trace_value(out, ns, step.lhs_object, step.full_lhs, step.full_lhs_value);
375+
trace_value(
376+
out, ns, step.lhs_object, step.full_lhs, step.full_lhs_value, options);
334377
break;
335378

336379
case goto_trace_stept::typet::OUTPUT:
@@ -356,7 +399,7 @@ void show_goto_trace(
356399
out << " " << from_expr(ns, step.pc->function, *l_it);
357400

358401
// the binary representation
359-
out << " (" << trace_value_binary(*l_it, ns) << ")";
402+
out << " (" << trace_numeric_value(*l_it, ns, options) << ")";
360403
}
361404

362405
out << "\n";
@@ -377,7 +420,7 @@ void show_goto_trace(
377420
out << " " << from_expr(ns, step.pc->function, *l_it);
378421

379422
// the binary representation
380-
out << " (" << trace_value_binary(*l_it, ns) << ")";
423+
out << " (" << trace_numeric_value(*l_it, ns, options) << ")";
381424
}
382425

383426
out << "\n";
@@ -401,5 +444,12 @@ void show_goto_trace(
401444
}
402445
}
403446

447+
void show_goto_trace(
448+
std::ostream &out,
449+
const namespacet &ns,
450+
const goto_tracet &goto_trace)
451+
{
452+
show_goto_trace(out, ns, goto_trace, trace_optionst::default_options);
453+
}
404454

405455
const trace_optionst trace_optionst::default_options = trace_optionst();

src/goto-programs/goto_trace.h

+32-16
Original file line numberDiff line numberDiff line change
@@ -195,45 +195,61 @@ class goto_tracet
195195
}
196196
};
197197

198-
void show_goto_trace(
199-
std::ostream &out,
200-
const namespacet &,
201-
const goto_tracet &);
202-
203-
void trace_value(
204-
std::ostream &out,
205-
const namespacet &,
206-
const ssa_exprt &lhs_object,
207-
const exprt &full_lhs,
208-
const exprt &value);
209-
210-
211198
struct trace_optionst
212199
{
213200
bool json_full_lhs;
201+
bool hex_representation;
202+
bool base_prefix;
214203

215204
static const trace_optionst default_options;
216205

217206
explicit trace_optionst(const optionst &options)
218207
{
219208
json_full_lhs = options.get_bool_option("trace-json-extended");
209+
hex_representation = options.get_bool_option("trace-hex");
210+
base_prefix = hex_representation;
220211
};
221212

222213
private:
223214
trace_optionst()
224215
{
225216
json_full_lhs = false;
217+
hex_representation = false;
218+
base_prefix = false;
226219
};
227220
};
228221

229-
#define OPT_GOTO_TRACE "(trace-json-extended)"
222+
void show_goto_trace(
223+
std::ostream &out,
224+
const namespacet &,
225+
const goto_tracet &);
226+
227+
void show_goto_trace(
228+
std::ostream &out,
229+
const namespacet &,
230+
const goto_tracet &,
231+
const trace_optionst &);
232+
233+
void trace_value(
234+
std::ostream &out,
235+
const namespacet &,
236+
const ssa_exprt &lhs_object,
237+
const exprt &full_lhs,
238+
const exprt &value);
239+
240+
241+
#define OPT_GOTO_TRACE "(trace-json-extended)" \
242+
"(trace-hex)"
230243

231244
#define HELP_GOTO_TRACE \
232-
" --trace-json-extended add rawLhs property to trace\n"
245+
" --trace-json-extended add rawLhs property to trace\n" \
246+
" --trace-hex represent plain trace values in hex\n"
233247

234248
#define PARSE_OPTIONS_GOTO_TRACE(cmdline, options) \
235249
if(cmdline.isset("trace-json-extended")) \
236-
options.set_option("trace-json-extended", true);
250+
options.set_option("trace-json-extended", true); \
251+
if(cmdline.isset("trace-hex")) \
252+
options.set_option("trace-hex", true);
237253

238254

239255
#endif // CPROVER_GOTO_PROGRAMS_GOTO_TRACE_H

0 commit comments

Comments
 (0)