From a4cddfbacd50d71ef104b6606755db9755307777 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 7 Oct 2025 21:44:40 -0700 Subject: [PATCH] Add versions of IfStmt and StmtList for use in debugger --- src/Stmt.cc | 57 +++++++++++++++++++++++++++++++++++++++-------------- src/Stmt.h | 19 +++++++++++++++++- src/parse.y | 21 +++++++++++++++++--- 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/src/Stmt.cc b/src/Stmt.cc index 9efda21df1..4585190066 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -436,15 +436,7 @@ ValPtr IfStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) { f->SetNextStmt(do_stmt); - if ( ! pre_execute_stmt(do_stmt, f) ) { // ### Abort or something - } - - auto result = do_stmt->Exec(f, flow); - - if ( ! post_execute_stmt(do_stmt, f, result.get(), &flow) ) { // ### Abort or something - } - - return result; + return do_stmt->Exec(f, flow); } bool IfStmt::IsPure() const { return e->IsPure() && s1->IsPure() && s2->IsPure(); } @@ -488,6 +480,23 @@ TraversalCode IfStmt::Traverse(TraversalCallback* cb) const { HANDLE_TC_STMT_POST(tc); } +ValPtr DebugIfStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) { + // Treat 0 as false, but don't require 1 for true. + Stmt* do_stmt = v->IsZero() ? s2.get() : s1.get(); + + f->SetNextStmt(do_stmt); + + if ( ! pre_execute_stmt(do_stmt, f) ) { // ### Abort or something + } + + auto result = do_stmt->Exec(f, flow); + + if ( ! post_execute_stmt(do_stmt, f, result.get(), &flow) ) { // ### Abort or something + } + + return result; +} + static StmtTag get_last_stmt_tag(const Stmt* stmt) { if ( ! stmt ) return STMT_NULL; @@ -1409,14 +1418,8 @@ ValPtr StmtList::Exec(Frame* f, StmtFlowType& flow) { f->SetNextStmt(stmt); - if ( ! pre_execute_stmt(stmt, f) ) { // ### Abort or something - } - auto result = stmt->Exec(f, flow); - if ( ! post_execute_stmt(stmt, f, result.get(), &flow) ) { // ### Abort or something - } - if ( flow != FLOW_NEXT || result || f->HasDelayed() ) return result; } @@ -1469,6 +1472,30 @@ TraversalCode StmtList::Traverse(TraversalCallback* cb) const { HANDLE_TC_STMT_POST(tc); } +ValPtr DebugStmtList::Exec(Frame* f, StmtFlowType& flow) { + RegisterAccess(); + flow = FLOW_NEXT; + + for ( const auto& stmt_ptr : stmts ) { + auto stmt = stmt_ptr.get(); + + f->SetNextStmt(stmt); + + if ( ! pre_execute_stmt(stmt, f) ) { // ### Abort or something + } + + auto result = stmt->Exec(f, flow); + + if ( ! post_execute_stmt(stmt, f, result.get(), &flow) ) { // ### Abort or something + } + + if ( flow != FLOW_NEXT || result || f->HasDelayed() ) + return result; + } + + return nullptr; +} + InitStmt::InitStmt(std::vector arg_inits) : Stmt(STMT_INIT) { inits = std::move(arg_inits); diff --git a/src/Stmt.h b/src/Stmt.h index 1e16803328..16b3488e75 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -102,7 +102,7 @@ protected: ExprPtr e; }; -class IfStmt final : public ExprStmt { +class IfStmt : public ExprStmt { public: IfStmt(ExprPtr test, StmtPtr s1, StmtPtr s2); ~IfStmt() override; @@ -135,6 +135,15 @@ protected: StmtPtr s2; }; +class DebugIfStmt final : public IfStmt { +public: + DebugIfStmt(ExprPtr test, StmtPtr s1, StmtPtr s2) : IfStmt(test, s1, s2) {} + ~DebugIfStmt() override = default; + +protected: + ValPtr DoExec(Frame* f, Val* v, StmtFlowType& flow) override; +}; + class Case final : public Obj { public: Case(ListExprPtr c, IDPList* types, StmtPtr arg_s); @@ -452,6 +461,14 @@ protected: void ResetStmts(std::vector new_stmts) { stmts = std::move(new_stmts); } }; +class DebugStmtList : public StmtList { +public: + DebugStmtList() = default; + ~DebugStmtList() override = default; + + ValPtr Exec(Frame* f, StmtFlowType& flow) override; +}; + class InitStmt final : public Stmt { public: explicit InitStmt(std::vector arg_inits); diff --git a/src/parse.y b/src/parse.y index be4ad5c1d4..e2afae078c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -163,6 +163,10 @@ static int func_hdr_cond_epoch = 0; EnumType* cur_enum_type = nullptr; static ID* cur_decl_type_id = nullptr; +namespace zeek::detail { +extern bool g_policy_debug; +} + static void parse_new_enum(void) { // Starting a new enum definition. assert(cur_enum_type == nullptr); @@ -1843,7 +1847,10 @@ stmt: { reject_directive($5); set_location(@1, @4); - $$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, make_intrusive()); + if ( g_policy_debug ) + $$ = new DebugIfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, make_intrusive()); + else + $$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, make_intrusive()); script_coverage_mgr.AddStmt($$); } @@ -1852,7 +1859,10 @@ stmt: reject_directive($5); reject_directive($7); set_location(@1, @4); - $$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, {AdoptRef{}, $7}); + if ( g_policy_debug ) + $$ = new DebugIfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, {AdoptRef{}, $7}); + else + $$ = new IfStmt({AdoptRef{}, $3}, {AdoptRef{}, $5}, {AdoptRef{}, $7}); script_coverage_mgr.AddStmt($$); } @@ -1976,7 +1986,12 @@ stmt_list: $1->UpdateLocationEndInfo(@2); } | - { $$ = new StmtList(); } + { + if ( g_policy_debug ) + $$ = new DebugStmtList(); + else + $$ = new StmtList(); + } ; event: