Skip to content

Commit 0552131

Browse files
fixed a bug, zero initialize local variables
1 parent efb8144 commit 0552131

File tree

3 files changed

+93
-21
lines changed

3 files changed

+93
-21
lines changed

headers/wasm/concolic_driver.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
#include "concrete_rt.hpp"
55
#include "config.hpp"
6+
#include "output_report.hpp"
67
#include "profile.hpp"
78
#include "smt_solver.hpp"
89
#include "symbolic_rt.hpp"
910
#include "utils.hpp"
10-
#include "output_report.hpp"
1111
#include <cassert>
1212
#include <chrono>
1313
#include <functional>
@@ -103,13 +103,26 @@ inline void ConcolicDriver::main_exploration_loop() {
103103
try {
104104
GENSYM_INFO("Now execute the program with symbolic environment: ");
105105
GENSYM_INFO(SymEnv.to_string());
106-
{ node->reach_here(entrypoint); }
106+
if (REUSE_SNAPSHOT) {
107+
node->reach_here(entrypoint);
108+
} else {
109+
auto timer = ManagedTimer(TimeProfileKind::INSTR);
110+
ExploreTree.reset_cursor();
111+
reset_stacks();
112+
entrypoint();
113+
}
107114

108115
GENSYM_INFO("Execution finished successfully with symbolic environment:");
109116
GENSYM_INFO(SymEnv.to_string());
110117
} catch (std::runtime_error &e) {
111118
std::cout << "Caught runtime error: " << e.what() << std::endl;
112119
ExploreTree.fillFailedNode();
120+
121+
if (std::string(e.what()) == "Symbolic assertion failed") {
122+
GENSYM_INFO("Symbolic assertion failed, continuing to next path...");
123+
continue;
124+
}
125+
113126
GENSYM_INFO("Caught runtime error with symbolic environment:");
114127
GENSYM_INFO(SymEnv.to_string());
115128
switch (EXPLORE_MODE) {

headers/wasm/concrete_rt.hpp

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,75 +21,115 @@ struct Num {
2121
int32_t toInt() const { return static_cast<int32_t>(value); }
2222
uint32_t toUInt() const { return static_cast<uint32_t>(value); }
2323

24+
// debug printer: enabled only when -DDEBUG
25+
static inline void debug_print(const char *op, const Num &a, const Num &b,
26+
const Num &res) {
27+
#ifdef DEBUG_OP
28+
std::cout << "[Debug] " << op << ": lhs=" << static_cast<int32_t>(a.value)
29+
<< " rhs=" << static_cast<int32_t>(b.value)
30+
<< " -> res=" << static_cast<int32_t>(res.value) << std::endl;
31+
#endif
32+
}
33+
2434
// Helper to create a Wasm Boolean result (1 or 0 as Num)
25-
Num WasmBool(bool condition) const { return Num(condition ? 1 : 0); }
35+
Num WasmBool(bool condition) const {
36+
Num res(condition ? 1 : 0);
37+
debug_print("WasmBool", *this, *this, res);
38+
return res;
39+
}
2640
// TODO: support different bit width operations, for now we just assume all
2741
// oprands are i32
2842
// i32.eq (Equals): *this == other
2943
inline Num i32_eq(const Num &other) const {
30-
return WasmBool(this->toUInt() == other.toUInt());
44+
Num res = WasmBool(this->toUInt() == other.toUInt());
45+
debug_print("i32.eq", *this, other, res);
46+
return res;
3147
}
3248

3349
// i32.ne (Not Equals): *this != other
3450
inline Num i32_ne(const Num &other) const {
35-
return WasmBool(this->toUInt() != other.toUInt());
51+
Num res = WasmBool(this->toUInt() != other.toUInt());
52+
debug_print("i32.ne", *this, other, res);
53+
return res;
3654
}
3755

3856
// i32.lt_s (Signed Less Than): *this < other
3957
inline Num i32_lt_s(const Num &other) const {
40-
return WasmBool(this->toInt() < other.toInt());
58+
Num res = WasmBool(this->toInt() < other.toInt());
59+
debug_print("i32.lt_s", *this, other, res);
60+
return res;
4161
}
4262

4363
// i32.lt_u (Unsigned Less Than): *this < other (unsigned)
4464
inline Num i32_lt_u(const Num &other) const {
45-
return WasmBool(this->toUInt() < other.toUInt());
65+
Num res = WasmBool(this->toUInt() < other.toUInt());
66+
debug_print("i32.lt_u", *this, other, res);
67+
return res;
4668
}
4769

4870
// i32.le_s (Signed Less Than or Equal): *this <= other
4971
inline Num i32_le_s(const Num &other) const {
50-
return WasmBool(this->toInt() <= other.toInt());
72+
Num res = WasmBool(this->toInt() <= other.toInt());
73+
debug_print("i32.le_s", *this, other, res);
74+
return res;
5175
}
5276
// i32.le_u (Unsigned Less Than or Equal): *this <= other (unsigned)
5377
inline Num i32_le_u(const Num &other) const {
54-
return WasmBool(this->toUInt() <= other.toUInt());
78+
Num res = WasmBool(this->toUInt() <= other.toUInt());
79+
debug_print("i32.le_u", *this, other, res);
80+
return res;
5581
}
5682

5783
// i32.gt_s (Signed Greater Than): *this > other
5884
inline Num i32_gt_s(const Num &other) const {
59-
return WasmBool(this->toInt() > other.toInt());
85+
Num res = WasmBool(this->toInt() > other.toInt());
86+
debug_print("i32.gt_s", *this, other, res);
87+
return res;
6088
}
6189

6290
// i32.gt_u (Unsigned Greater Than): *this > other (unsigned)
6391
inline Num i32_gt_u(const Num &other) const {
64-
return WasmBool(this->toUInt() > other.toUInt());
92+
Num res = WasmBool(this->toUInt() > other.toUInt());
93+
debug_print("i32.gt_u", *this, other, res);
94+
return res;
6595
}
6696

6797
// i32.ge_s (Signed Greater Than or Equal): *this >= other
6898
inline Num i32_ge_s(const Num &other) const {
69-
return WasmBool(this->toInt() >= other.toInt());
99+
Num res = WasmBool(this->toInt() >= other.toInt());
100+
debug_print("i32.ge_s", *this, other, res);
101+
return res;
70102
}
71103

72104
// i32.ge_u (Unsigned Greater Than or Equal): *this >= other (unsigned)
73105
inline Num i32_ge_u(const Num &other) const {
74-
return WasmBool(this->toUInt() >= other.toUInt());
106+
Num res = WasmBool(this->toUInt() >= other.toUInt());
107+
debug_print("i32.ge_u", *this, other, res);
108+
return res;
75109
}
76110

77111
// i32.add (Wrapping addition)
78112
inline Num i32_add(const Num &other) const {
79113
uint32_t result_u = this->toUInt() + other.toUInt();
80-
return Num(static_cast<int32_t>(result_u));
114+
Num res(static_cast<int32_t>(result_u));
115+
debug_print("i32.add", *this, other, res);
116+
return res;
81117
}
82118

83119
// i32.sub (Wrapping subtraction)
84120
inline Num i32_sub(const Num &other) const {
85121
uint32_t result_u = this->toUInt() - other.toUInt();
86-
return Num(static_cast<int32_t>(result_u));
122+
Num res(static_cast<int32_t>(result_u));
123+
debug_print("i32.sub", *this, other, res);
124+
return res;
87125
}
88126

89127
// i32.mul (Wrapping multiplication)
90128
inline Num i32_mul(const Num &other) const {
91129
uint32_t result_u = this->toUInt() * other.toUInt();
92-
return Num(static_cast<int32_t>(result_u));
130+
Num res(static_cast<int32_t>(result_u));
131+
debug_print("i32.mul", *this, other, res);
132+
return res;
93133
}
94134

95135
// i32.div_s (Signed division with traps)
@@ -101,36 +141,46 @@ struct Num {
101141
throw std::runtime_error("i32.div_s: Division by zero");
102142
}
103143

104-
return Num(dividend / divisor);
144+
Num res(dividend / divisor);
145+
debug_print("i32.div_s", *this, other, res);
146+
return res;
105147
}
106148

107149
// i32.shl (Shift Left): *this << other (shift count masked by 31)
108150
inline Num i32_shl(const Num &other) const {
109151
uint32_t shift_amount = other.toUInt() & 0x1F;
110152
uint32_t result_u = toUInt() << shift_amount;
111-
return Num(static_cast<int32_t>(result_u));
153+
Num res(static_cast<int32_t>(result_u));
154+
debug_print("i32.shl", *this, other, res);
155+
return res;
112156
}
113157

114158
// i32.shr_s (Signed Shift Right): *this >> other (Arithmetic shift)
115159
inline Num i32_shr_s(const Num &other) const {
116160
// Wasm masks the shift amount by 31 (0x1F)
117161
uint32_t shift_amount = other.toUInt() & 0x1F;
118162
int32_t result_s = toInt() >> shift_amount;
119-
return Num(result_s);
163+
Num res(result_s);
164+
debug_print("i32.shr_s", *this, other, res);
165+
return res;
120166
}
121167

122168
// i32.shr_u (Unsigned Shift Right): *this >>> other (Logical shift)
123169
inline Num i32_shr_u(const Num &other) const {
124170
// Wasm masks the shift amount by 31 (0x1F)
125171
uint32_t shift_amount = other.toUInt() & 0x1F;
126172
uint32_t result_u = toUInt() >> shift_amount;
127-
return Num(static_cast<int32_t>(result_u));
173+
Num res(static_cast<int32_t>(result_u));
174+
debug_print("i32.shr_u", *this, other, res);
175+
return res;
128176
}
129177

130178
// i32.and (Bitwise AND)
131179
inline Num i32_and(const Num &other) const {
132180
uint32_t result_u = this->toUInt() & other.toUInt();
133-
return Num(static_cast<int32_t>(result_u));
181+
Num res(static_cast<int32_t>(result_u));
182+
debug_print("i32.and", *this, other, res);
183+
return res;
134184
}
135185
};
136186

@@ -272,6 +322,10 @@ class Frames_t {
272322
void pushFrame(std::int32_t size) {
273323
assert(size >= 0);
274324
count += size;
325+
// Zero-initialize the new stack frames.
326+
for (std::int32_t i = 0; i < size; ++i) {
327+
stack_ptr[count - 1 - i] = Num(0);
328+
}
275329
}
276330

277331
void reset() { count = 0; }

headers/wasm/symbolic_rt.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,12 @@ inline bool NodeBox::fillIfElseNode(SymVal cond, int id) {
777777
} else if (dynamic_cast<UnExploredNode *>(node.get())) {
778778
node = std::make_unique<IfElseNode>(cond, this, id);
779779
return true;
780+
} else if (dynamic_cast<NotToExploreNode *>(node.get()) != nullptr) {
781+
assert(false &&
782+
"Unexpected traversal: arrived at a node marked 'NotToExplore'.");
783+
return false;
780784
}
785+
781786
assert(
782787
dynamic_cast<IfElseNode *>(node.get()) != nullptr &&
783788
"Current node is not an Unexplored nor an IfElseNode, cannot fill it!");

0 commit comments

Comments
 (0)