Skip to content
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

improve user experience with the full recovery mode #102

Closed
wants to merge 4 commits into from
Closed
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
7 changes: 7 additions & 0 deletions sl/glconf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ void handleNoErrorRecovery(const string &name, const string &value)
data.errorRecoveryMode = /* no_error_recovery */ 0;
}

void handleFullErrorRecovery(const string &name, const string &value)
{
assumeNoValue(name, value);
data.errorRecoveryMode = /* full_error_recovery */ 2;
}

void handleVerifierErrorIsError(const string &name, const string &value)
{
assumeNoValue(name, value);
Expand Down Expand Up @@ -244,6 +250,7 @@ ConfigStringParser::ConfigStringParser()
tbl_["error_label"] = handleErrorLabel;
tbl_["exit_leaks"] = handleExitLeaks;
tbl_["forbid_heap_replace"] = handleForbidHeapReplace;
tbl_["full_error_recovery"] = handleFullErrorRecovery;
tbl_["int_arithmetic_limit"] = handleIntArithmeticLimit;
tbl_["join_on_loop_edges_only"] = handleJoinOnLoopEdgesOnly;
tbl_["memleak_is_error"] = handleMemLeakIsError;
Expand Down
2 changes: 1 addition & 1 deletion sl/symexec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ void SymExecEngine::execCondInsn()
}

const EValueOrigin origin = sh.valOrigin(val);
if (VO_DEREF_FAILED == origin) {
if (GlConf::data.errorRecoveryMode < 2 && VO_DEREF_FAILED == origin) {
// error should have been already emitted
CL_DEBUG_MSG(lw_, "ignored VO_DEREF_FAILED");
return;
Expand Down
3 changes: 2 additions & 1 deletion sl/symjoin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,8 @@ EValueOrigin joinOrigin(const EValueOrigin vo1, const EValueOrigin vo2)
// use any
return vo2;

if (VO_DEREF_FAILED == vo1 || VO_DEREF_FAILED == vo2)
if (GlConf::data.errorRecoveryMode < 2
&& (VO_DEREF_FAILED == vo1 || VO_DEREF_FAILED == vo2))
// keep the error recovery as cheap as possible
return VO_DEREF_FAILED;

Expand Down
44 changes: 31 additions & 13 deletions sl/symproc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,8 @@ void SymExecCore::execFree(
// fall through!

case VT_UNKNOWN:
if (VO_DEREF_FAILED == sh_.valOrigin(val))
if (GlConf::data.errorRecoveryMode < 2
&& VO_DEREF_FAILED == sh_.valOrigin(val))
return;

CL_ERROR_MSG(lw_, "invalid " << fnc);
Expand Down Expand Up @@ -1472,17 +1473,34 @@ void SymExecCore::execStackRestore()
}
}

bool lhsFromOperand(FldHandle *pLhs, SymProc &proc, const struct cl_operand &op)
bool SymProc::lhsFromOperand(FldHandle *pLhs, const struct cl_operand &op)
{
if (seekRefAccessor(op.accessor))
CL_BREAK_IF("lhs not an l-value");

*pLhs = proc.fldByOperand(op);
if (FLD_DEREF_FAILED == pLhs->fieldId())
return false;
*pLhs = this->fldByOperand(op);
if (FLD_DEREF_FAILED != pLhs->fieldId()) {
// propagate the field returned by fldByOperand()
CL_BREAK_IF(!pLhs->isValidHandle());
return true;
}

CL_BREAK_IF(!pLhs->isValidHandle());
return true;
if (2 <= GlConf::data.errorRecoveryMode) {
// if the dereference failed due to out of range (or unknown) offset,
// try to resolve the allocated object and invalidate its contents in
// order to detect more errors in one run with full error recovery
const TObjId obj = this->objByVar(op);
if (sh_.isValid(obj)) {
const UniformBlock ub = {
/* off */ 0,
/* size */ sh_.objSize(obj).hi,
/* tplValue */ sh_.valCreate(VT_UNKNOWN, VO_UNKNOWN)
};
sh_.writeUniformBlock(obj, ub);
}
}

return false;
}

void SymExecCore::execStackAlloc(
Expand All @@ -1491,7 +1509,7 @@ void SymExecCore::execStackAlloc(
{
// resolve lhs
FldHandle lhs;
if (CL_OPERAND_VOID != opLhs.code && !lhsFromOperand(&lhs, *this, opLhs))
if (CL_OPERAND_VOID != opLhs.code && !this->lhsFromOperand(&lhs, opLhs))
// error alredy emitted
return;

Expand All @@ -1502,7 +1520,7 @@ void SymExecCore::execStackAlloc(
return;
}

// now create an annonymous stack object
// now create an anonymous stack object
const CallInst callInst(this->bt_);
const TObjId obj = sh_.stackAlloc(size, callInst);

Expand Down Expand Up @@ -1531,8 +1549,8 @@ void SymExecCore::execHeapAlloc(
// resolve lhs
FldHandle lhs;
const struct cl_operand &opLhs = insn.operands[/* dst */ 0];
if (CL_OPERAND_VOID != opLhs.code && !lhsFromOperand(&lhs, *this, opLhs))
// error alredy emitted
if (CL_OPERAND_VOID != opLhs.code && !this->lhsFromOperand(&lhs, opLhs))
// error already emitted
return;

if (ep_.oomSimulation || /* malloc(0) may return NULL */ !size.hi) {
Expand Down Expand Up @@ -1649,7 +1667,7 @@ void SymExecCore::execHeapRealloc(
// resolve lhs
FldHandle lhs;
const struct cl_operand &opLhs = insn.operands[/* dst */ 0];
if (CL_OPERAND_VOID != opLhs.code && !lhsFromOperand(&lhs, *this, opLhs))
if (CL_OPERAND_VOID != opLhs.code && !this->lhsFromOperand(&lhs, opLhs))
// error alredy emitted
return;

Expand Down Expand Up @@ -2841,7 +2859,7 @@ void SymExecCore::execOp(const CodeStorage::Insn &insn)
// resolve lhs
FldHandle lhs;
const struct cl_operand &dst = insn.operands[/* dst */ 0];
if (!lhsFromOperand(&lhs, *this, dst))
if (!this->lhsFromOperand(&lhs, dst))
// error alredy emitted
return;

Expand Down
7 changes: 5 additions & 2 deletions sl/symproc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,13 @@ class SymProc {
}

public:
/// obtain a heap object corresponding to the given operand
/// obtain a field corresponding to the given operand
FldHandle fldByOperand(const struct cl_operand &op);

/// obtain a heap value corresponding to the given operand
/// obtain a left-hand-side field corresponding to the given operand
bool lhsFromOperand(FldHandle *pLhs, const struct cl_operand &op);

/// obtain a SymHeap value corresponding to the given operand
TValId valFromOperand(const struct cl_operand &op);

/// resolve Fnc uid from the given operand, return true on success
Expand Down
Loading