mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
GH-1328: Improve behavior of Dictionary iterator invalidation
Previously, an assertion was triggered in debug builds upon any attempt to insert or remove a Dictionary entry while any iteration of that Dictionary is underway and also even in cases where Dictionary membership was not actually modified (and thus invalidates a loop). Now, it emits run-time warnings regardless of build-type and only when insert/remove operations truly change the Dictionary membership. In the context of a Zeek script causing an invalidation, the warning message also now helps pinpoint the exact expression that causes it.
This commit is contained in:
parent
9d8bab692c
commit
8f98b068c8
7 changed files with 287 additions and 35 deletions
39
src/Expr.cc
39
src/Expr.cc
|
@ -2619,7 +2619,17 @@ void IndexExpr::Add(Frame* f)
|
|||
if ( ! v2 )
|
||||
return;
|
||||
|
||||
v1->AsTableVal()->Assign(std::move(v2), nullptr);
|
||||
bool iterators_invalidated = false;
|
||||
v1->AsTableVal()->Assign(std::move(v2), nullptr, true, &iterators_invalidated);
|
||||
|
||||
if ( iterators_invalidated )
|
||||
{
|
||||
ODesc d;
|
||||
Describe(&d);
|
||||
reporter->PushLocation(GetLocationInfo());
|
||||
reporter->Warning("possible loop/iterator invalidation caused by expression: %s", d.Description());
|
||||
reporter->PopLocation();
|
||||
}
|
||||
}
|
||||
|
||||
void IndexExpr::Delete(Frame* f)
|
||||
|
@ -2637,7 +2647,17 @@ void IndexExpr::Delete(Frame* f)
|
|||
if ( ! v2 )
|
||||
return;
|
||||
|
||||
v1->AsTableVal()->Remove(*v2);
|
||||
bool iterators_invalidated = false;
|
||||
v1->AsTableVal()->Remove(*v2, true, &iterators_invalidated);
|
||||
|
||||
if ( iterators_invalidated )
|
||||
{
|
||||
ODesc d;
|
||||
Describe(&d);
|
||||
reporter->PushLocation(GetLocationInfo());
|
||||
reporter->Warning("possible loop/iterator invalidation caused by expression: %s", d.Description());
|
||||
reporter->PopLocation();
|
||||
}
|
||||
}
|
||||
|
||||
ExprPtr IndexExpr::MakeLvalue()
|
||||
|
@ -2858,7 +2878,10 @@ void IndexExpr::Assign(Frame* f, ValPtr v)
|
|||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
if ( ! v1->AsTableVal()->Assign(std::move(v2), std::move(v)) )
|
||||
{
|
||||
bool iterators_invalidated = false;
|
||||
|
||||
if ( ! v1->AsTableVal()->Assign(std::move(v2), std::move(v), true, &iterators_invalidated) )
|
||||
{
|
||||
v = std::move(v_extra);
|
||||
|
||||
|
@ -2876,6 +2899,16 @@ void IndexExpr::Assign(Frame* f, ValPtr v)
|
|||
else
|
||||
RuntimeErrorWithCallStack("assignment failed with null value");
|
||||
}
|
||||
|
||||
if ( iterators_invalidated )
|
||||
{
|
||||
ODesc d;
|
||||
Describe(&d);
|
||||
reporter->PushLocation(GetLocationInfo());
|
||||
reporter->Warning("possible loop/iterator invalidation caused by expression: %s", d.Description());
|
||||
reporter->PopLocation();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_STRING:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue