mirror of
https://github.com/Z3Prover/z3
synced 2025-06-27 08:28:44 +00:00
fix #1276 related crashes for re-sumption after cancellation
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bec60f763b
commit
05428314be
5 changed files with 31 additions and 11 deletions
|
@ -151,11 +151,7 @@ void maximize_ac_sharing::restore_entries(unsigned old_lim) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void maximize_ac_sharing::reset() {
|
void maximize_ac_sharing::reset() {
|
||||||
restore_entries(0);
|
|
||||||
m_entries.reset();
|
|
||||||
m_cache.reset();
|
m_cache.reset();
|
||||||
m_region.reset();
|
|
||||||
m_scopes.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void maximize_bv_sharing::init_core() {
|
void maximize_bv_sharing::init_core() {
|
||||||
|
|
|
@ -170,7 +170,7 @@ void asserted_formulas::get_assertions(ptr_vector<expr> & result) const {
|
||||||
|
|
||||||
void asserted_formulas::push_scope() {
|
void asserted_formulas::push_scope() {
|
||||||
SASSERT(inconsistent() || m_qhead == m_formulas.size() || m.canceled());
|
SASSERT(inconsistent() || m_qhead == m_formulas.size() || m.canceled());
|
||||||
TRACE("asserted_formulas_scopes", tout << "push:\n"; display(tout););
|
TRACE("asserted_formulas_scopes", tout << "before push: " << m_scopes.size() << "\n";);
|
||||||
m_scoped_substitution.push();
|
m_scoped_substitution.push();
|
||||||
m_scopes.push_back(scope());
|
m_scopes.push_back(scope());
|
||||||
scope & s = m_scopes.back();
|
scope & s = m_scopes.back();
|
||||||
|
@ -181,10 +181,11 @@ void asserted_formulas::push_scope() {
|
||||||
m_bv_sharing.push_scope();
|
m_bv_sharing.push_scope();
|
||||||
m_macro_manager.push_scope();
|
m_macro_manager.push_scope();
|
||||||
commit();
|
commit();
|
||||||
|
TRACE("asserted_formulas_scopes", tout << "after push: " << m_scopes.size() << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
void asserted_formulas::pop_scope(unsigned num_scopes) {
|
void asserted_formulas::pop_scope(unsigned num_scopes) {
|
||||||
TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << "\n"; display(tout););
|
TRACE("asserted_formulas_scopes", tout << "before pop " << num_scopes << " of " << m_scopes.size() << "\n";);
|
||||||
m_bv_sharing.pop_scope(num_scopes);
|
m_bv_sharing.pop_scope(num_scopes);
|
||||||
m_macro_manager.pop_scope(num_scopes);
|
m_macro_manager.pop_scope(num_scopes);
|
||||||
unsigned new_lvl = m_scopes.size() - num_scopes;
|
unsigned new_lvl = m_scopes.size() - num_scopes;
|
||||||
|
@ -196,7 +197,7 @@ void asserted_formulas::pop_scope(unsigned num_scopes) {
|
||||||
m_qhead = s.m_formulas_lim;
|
m_qhead = s.m_formulas_lim;
|
||||||
m_scopes.shrink(new_lvl);
|
m_scopes.shrink(new_lvl);
|
||||||
flush_cache();
|
flush_cache();
|
||||||
TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n"; display(tout););
|
TRACE("asserted_formulas_scopes", tout << "after pop " << num_scopes << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
void asserted_formulas::reset() {
|
void asserted_formulas::reset() {
|
||||||
|
|
|
@ -487,6 +487,7 @@ namespace smt {
|
||||||
*/
|
*/
|
||||||
void context::add_eq(enode * n1, enode * n2, eq_justification js) {
|
void context::add_eq(enode * n1, enode * n2, eq_justification js) {
|
||||||
unsigned old_trail_size = m_trail_stack.size();
|
unsigned old_trail_size = m_trail_stack.size();
|
||||||
|
scoped_suspend_rlimit _suspend_cancel(m_manager.limit());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TRACE("add_eq", tout << "assigning: #" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n";);
|
TRACE("add_eq", tout << "assigning: #" << n1->get_owner_id() << " = #" << n2->get_owner_id() << "\n";);
|
||||||
|
@ -541,10 +542,14 @@ namespace smt {
|
||||||
mark_as_relevant(r1);
|
mark_as_relevant(r1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "to trail\n";);
|
||||||
|
|
||||||
push_trail(add_eq_trail(r1, n1, r2->get_num_parents()));
|
push_trail(add_eq_trail(r1, n1, r2->get_num_parents()));
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "qmanager add_eq\n";);
|
||||||
m_qmanager->add_eq_eh(r1, r2);
|
m_qmanager->add_eq_eh(r1, r2);
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "merge theory_vars\n";);
|
||||||
merge_theory_vars(n2, n1, js);
|
merge_theory_vars(n2, n1, js);
|
||||||
|
|
||||||
// 'Proof' tree
|
// 'Proof' tree
|
||||||
|
@ -577,6 +582,7 @@ namespace smt {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "remove_parents_from_cg_table\n";);
|
||||||
remove_parents_from_cg_table(r1);
|
remove_parents_from_cg_table(r1);
|
||||||
|
|
||||||
enode * curr = r1;
|
enode * curr = r1;
|
||||||
|
@ -588,8 +594,10 @@ namespace smt {
|
||||||
|
|
||||||
SASSERT(r1->get_root() == r2);
|
SASSERT(r1->get_root() == r2);
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "reinsert_parents_into_cg_table\n";);
|
||||||
reinsert_parents_into_cg_table(r1, r2, n1, n2, js);
|
reinsert_parents_into_cg_table(r1, r2, n1, n2, js);
|
||||||
|
|
||||||
|
TRACE("add_eq", tout << "propagate_bool_enode_assignment\n";);
|
||||||
if (n2->is_bool())
|
if (n2->is_bool())
|
||||||
propagate_bool_enode_assignment(r1, r2, n1, n2);
|
propagate_bool_enode_assignment(r1, r2, n1, n2);
|
||||||
|
|
||||||
|
@ -604,6 +612,7 @@ namespace smt {
|
||||||
catch (...) {
|
catch (...) {
|
||||||
// Restore trail size since procedure was interrupted in the middle.
|
// Restore trail size since procedure was interrupted in the middle.
|
||||||
// If the add_eq_trail remains on the trail stack, then Z3 may crash when the destructor is invoked.
|
// If the add_eq_trail remains on the trail stack, then Z3 may crash when the destructor is invoked.
|
||||||
|
TRACE("add_eq", tout << "add_eq interrupted. This is unsafe " << m_manager.limit().get_cancel_flag() << "\n";);
|
||||||
m_trail_stack.shrink(old_trail_size);
|
m_trail_stack.shrink(old_trail_size);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +981,7 @@ namespace smt {
|
||||||
enode * parent = *it;
|
enode * parent = *it;
|
||||||
if (parent->is_cgc_enabled()) {
|
if (parent->is_cgc_enabled()) {
|
||||||
TRACE("add_eq_parents", tout << "removing: #" << parent->get_owner_id() << "\n";);
|
TRACE("add_eq_parents", tout << "removing: #" << parent->get_owner_id() << "\n";);
|
||||||
CTRACE("add_eq", !parent->is_cgr(),
|
CTRACE("add_eq", !parent->is_cgr() || !m_cg_table.contains_ptr(parent),
|
||||||
tout << "old num_parents: " << r2_num_parents << ", num_parents: " << r2->m_parents.size() << ", parent: #" <<
|
tout << "old num_parents: " << r2_num_parents << ", num_parents: " << r2->m_parents.size() << ", parent: #" <<
|
||||||
parent->get_owner_id() << ", parents: \n";
|
parent->get_owner_id() << ", parents: \n";
|
||||||
for (unsigned i = 0; i < r2->m_parents.size(); i++) {
|
for (unsigned i = 0; i < r2->m_parents.size(); i++) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ Revision History:
|
||||||
|
|
||||||
reslimit::reslimit():
|
reslimit::reslimit():
|
||||||
m_cancel(0),
|
m_cancel(0),
|
||||||
|
m_suspend(false),
|
||||||
m_count(0),
|
m_count(0),
|
||||||
m_limit(0) {
|
m_limit(0) {
|
||||||
}
|
}
|
||||||
|
@ -31,12 +32,12 @@ uint64 reslimit::count() const {
|
||||||
|
|
||||||
bool reslimit::inc() {
|
bool reslimit::inc() {
|
||||||
++m_count;
|
++m_count;
|
||||||
return m_cancel == 0 && (m_limit == 0 || m_count <= m_limit);
|
return (m_cancel == 0 && (m_limit == 0 || m_count <= m_limit)) || m_suspend;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reslimit::inc(unsigned offset) {
|
bool reslimit::inc(unsigned offset) {
|
||||||
m_count += offset;
|
m_count += offset;
|
||||||
return m_cancel == 0 && (m_limit == 0 || m_count <= m_limit);
|
return (m_cancel == 0 && (m_limit == 0 || m_count <= m_limit)) || m_suspend;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reslimit::push(unsigned delta_limit) {
|
void reslimit::push(unsigned delta_limit) {
|
||||||
|
|
|
@ -23,12 +23,14 @@ Revision History:
|
||||||
|
|
||||||
class reslimit {
|
class reslimit {
|
||||||
volatile unsigned m_cancel;
|
volatile unsigned m_cancel;
|
||||||
|
bool m_suspend;
|
||||||
uint64 m_count;
|
uint64 m_count;
|
||||||
uint64 m_limit;
|
uint64 m_limit;
|
||||||
svector<uint64> m_limits;
|
svector<uint64> m_limits;
|
||||||
ptr_vector<reslimit> m_children;
|
ptr_vector<reslimit> m_children;
|
||||||
|
|
||||||
void set_cancel(unsigned f);
|
void set_cancel(unsigned f);
|
||||||
|
friend class scoped_suspend_rlimit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
reslimit();
|
reslimit();
|
||||||
|
@ -42,7 +44,7 @@ public:
|
||||||
uint64 count() const;
|
uint64 count() const;
|
||||||
|
|
||||||
|
|
||||||
bool get_cancel_flag() const { return m_cancel > 0; }
|
bool get_cancel_flag() const { return m_cancel > 0 && !m_suspend; }
|
||||||
char const* get_cancel_msg() const;
|
char const* get_cancel_msg() const;
|
||||||
void cancel();
|
void cancel();
|
||||||
void reset_cancel();
|
void reset_cancel();
|
||||||
|
@ -61,6 +63,17 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class scoped_suspend_rlimit {
|
||||||
|
reslimit & m_limit;
|
||||||
|
public:
|
||||||
|
scoped_suspend_rlimit(reslimit& r): m_limit(r) {
|
||||||
|
r.m_suspend = true;
|
||||||
|
}
|
||||||
|
~scoped_suspend_rlimit() {
|
||||||
|
m_limit.m_suspend = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct scoped_limits {
|
struct scoped_limits {
|
||||||
reslimit& m_limit;
|
reslimit& m_limit;
|
||||||
unsigned m_sz;
|
unsigned m_sz;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue