mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
Fix memory leak of serialized IDs when compiled with --enable-debug.
When using --enable-debug, values keep track of the last identifier to which they were bound by storing a ref'd ID pointer. This could lead to some circular dependencies in which an ID is never reclaimed because the Val is bound to the ID and the ID is bound to the Val, with both holding references to each other. There might be more cases where this feature of --enable-debug caused a leak, but it showed up in particular when running the core.leaks.remote unit test due to the internal SendID("peer_description") call during the handshake between remote processes. Other tests showed the send_id() BIF leaked more generally. Tracking the ID last bound to a Val through just the identifier string instead of a ref'd ID pointer fixes the leak.
This commit is contained in:
parent
4da209d3b1
commit
a6f7fd9c87
3 changed files with 10 additions and 13 deletions
|
@ -2897,11 +2897,6 @@ void RemoteSerializer::GotID(ID* id, Val* val)
|
||||||
(desc && *desc) ? desc : "not set"),
|
(desc && *desc) ? desc : "not set"),
|
||||||
current_peer);
|
current_peer);
|
||||||
|
|
||||||
#ifdef USE_PERFTOOLS_DEBUG
|
|
||||||
// May still be cached, but we don't care.
|
|
||||||
heap_checker->IgnoreObject(id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Unref(id);
|
Unref(id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ Val::~Val()
|
||||||
|
|
||||||
Unref(type);
|
Unref(type);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Unref(bound_id);
|
delete [] bound_id;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
src/Val.h
16
src/Val.h
|
@ -347,13 +347,15 @@ public:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// For debugging, we keep a reference to the global ID to which a
|
// For debugging, we keep a reference to the global ID to which a
|
||||||
// value has been bound *last*.
|
// value has been bound *last*.
|
||||||
ID* GetID() const { return bound_id; }
|
ID* GetID() const
|
||||||
|
{
|
||||||
|
return bound_id ? global_scope()->Lookup(bound_id) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void SetID(ID* id)
|
void SetID(ID* id)
|
||||||
{
|
{
|
||||||
if ( bound_id )
|
delete [] bound_id;
|
||||||
::Unref(bound_id);
|
bound_id = id ? copy_string(id->Name()) : 0;
|
||||||
bound_id = id;
|
|
||||||
::Ref(bound_id);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -401,8 +403,8 @@ protected:
|
||||||
RecordVal* attribs;
|
RecordVal* attribs;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// For debugging, we keep the ID to which a Val is bound.
|
// For debugging, we keep the name of the ID to which a Val is bound.
|
||||||
ID* bound_id;
|
const char* bound_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue