diff --git a/src/Debug.cc b/src/Debug.cc index e0f6ca33f5..130783bbd7 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -20,6 +20,7 @@ using namespace std; #include "Stmt.h" #include "Frame.h" #include "Func.h" +#include "IntrusivePtr.h" #include "Scope.h" #include "PolicyFile.h" #include "Desc.h" @@ -968,7 +969,10 @@ Val* dbg_eval_expr(const char* expr) const BroFunc* func = frame->GetFunction(); if ( func ) + { + Ref(func->GetScope()); push_existing_scope(func->GetScope()); + } // ### Possibly push a debugger-local scope? diff --git a/src/Scope.cc b/src/Scope.cc index 1d919ea2c9..99332f7b8d 100644 --- a/src/Scope.cc +++ b/src/Scope.cc @@ -5,6 +5,7 @@ #include "Scope.h" #include "Desc.h" #include "ID.h" +#include "IntrusivePtr.h" #include "Val.h" #include "Reporter.h" #include "module_util.h" @@ -204,21 +205,17 @@ void push_scope(ID* id, attr_list* attrs) scopes.push_back(top_scope); } -Scope* pop_scope() +IntrusivePtr pop_scope() { if ( scopes.empty() ) reporter->InternalError("scope underflow"); scopes.pop_back(); Scope* old_top = top_scope; - // Don't delete the scope; keep it around for later name resolution - // in the debugger. - // ### SERIOUS MEMORY LEAK!? - // delete top_scope; top_scope = scopes.empty() ? nullptr : scopes.back(); - return old_top; + return {AdoptRef{}, old_top}; } Scope* current_scope() diff --git a/src/Scope.h b/src/Scope.h index 942d38ae1c..83772e1b9f 100644 --- a/src/Scope.h +++ b/src/Scope.h @@ -10,6 +10,7 @@ #include "BroList.h" #include "TraverseTypes.h" +template class IntrusivePtr; class ID; class BroType; class ListVal; @@ -89,7 +90,7 @@ extern void push_scope(ID* id, attr_list* attrs); extern void push_existing_scope(Scope* scope); // Returns the one popped off; it's not deleted. -extern Scope* pop_scope(); +extern IntrusivePtr pop_scope(); extern Scope* current_scope(); extern Scope* global_scope(); diff --git a/src/Var.cc b/src/Var.cc index 1088a67dad..56e00432e6 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -8,6 +8,7 @@ #include "Val.h" #include "Expr.h" #include "Func.h" +#include "IntrusivePtr.h" #include "Stmt.h" #include "Scope.h" #include "Reporter.h" @@ -468,7 +469,7 @@ TraversalCode OuterIDBindingFinder::PostExpr(const Expr* expr) void end_func(IntrusivePtr body) { - auto ingredients = std::make_unique(pop_scope(), body.release()); + auto ingredients = std::make_unique(pop_scope().release(), body.release()); if ( streq(ingredients->id->Name(), "anonymous-function") ) { diff --git a/src/parse.y b/src/parse.y index 47dc9ed2d7..37e47429a4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -82,6 +82,7 @@ #include "Desc.h" #include "Expr.h" #include "Func.h" +#include "IntrusivePtr.h" #include "Stmt.h" #include "Val.h" #include "Var.h" @@ -1250,7 +1251,7 @@ anonymous_function: // Gather the ingredients for a BroFunc from the current scope auto ingredients = std::make_unique(current_scope(), $5); - id_list outer_ids = gather_outer_ids(pop_scope(), $5); + id_list outer_ids = gather_outer_ids(pop_scope().get(), $5); $$ = new LambdaExpr(std::move(ingredients), std::move(outer_ids)); }