From 9e97e1f4bc0cff2d579286581206c6b90bfa6dd4 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Sep 2025 17:52:48 -0700 Subject: [PATCH 1/4] Wrap handling of g_frame_stack in checks for DEBUG --- src/Func.cc | 6 ++++++ src/zeek-setup.cc | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/Func.cc b/src/Func.cc index e6047df71e..ac64d64d28 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -339,7 +339,9 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const { f->SetTriggerAssoc(parent->GetTriggerAssoc()); } +#if DEBUG g_frame_stack.push_back(f.get()); // used for backtracing +#endif const CallExpr* call_expr = parent ? parent->GetCall() : nullptr; call_stack.emplace_back(CallInfo{call_expr, this, *args}); @@ -391,7 +393,9 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const { catch ( InterpreterException& e ) { // Already reported, but now determine whether to unwind further. if ( Flavor() == FUNC_FLAVOR_FUNCTION ) { +#if DEBUG g_frame_stack.pop_back(); +#endif call_stack.pop_back(); // Result not set b/c exception was thrown throw; @@ -448,7 +452,9 @@ ValPtr ScriptFunc::Invoke(zeek::Args* args, Frame* parent) const { g_trace_state.LogTrace("Function return: %s\n", d.Description()); } +#if DEBUG g_frame_stack.pop_back(); +#endif return result; } diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index 070aad5308..119e8b1e70 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -1105,7 +1105,9 @@ SetupResult setup(int argc, char** argv, Options* zopts) { auto [body, scope] = get_global_stmts(); StmtFlowType flow; Frame f(scope->Length(), nullptr, nullptr); +#ifdef DEBUG g_frame_stack.push_back(&f); +#endif try { body->Exec(&f, flow); @@ -1113,7 +1115,9 @@ SetupResult setup(int argc, char** argv, Options* zopts) { reporter->FatalError("failed to execute script statements at top-level scope"); } +#ifdef DEBUG g_frame_stack.pop_back(); +#endif } clear_script_analysis(); From f7bcc63ea8132a1d5d9613fb9c1757e26fd48c96 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Sep 2025 17:53:57 -0700 Subject: [PATCH 2/4] Disable script tracing on non-debug builds --- src/Debug.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Debug.h b/src/Debug.h index 3d256ca4a8..7748beb1e5 100644 --- a/src/Debug.h +++ b/src/Debug.h @@ -60,7 +60,13 @@ public: // Returns previous filename. FILE* SetTraceFile(const char* trace_filename); - bool DoTrace() const { return dbgtrace; } + bool DoTrace() const { +#if DEBUG + return dbgtrace; +#else + return false; +#endif + } void TraceOn(); void TraceOff(); From fcd94157e1804117f9322b2147adbcda9d5c9a96 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Sep 2025 17:55:32 -0700 Subject: [PATCH 3/4] Return an error if script tracing/debugger arguments are passed to non-debug builds --- src/Options.cc | 20 +++++++++++++++++-- testing/btest/spicy/file-analyzer-nested.zeek | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Options.cc b/src/Options.cc index ef771cc984..40b291f3d6 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -445,7 +445,15 @@ Options parse_cmdline(int argc, char** argv) { case 'a': rval.parse_only = true; break; case 'b': rval.bare_mode = true; break; case 'c': rval.unprocessed_output_file = optarg; break; - case 'd': rval.debug_scripts = true; break; + case 'd': +#if DEBUG + rval.debug_scripts = true; + break; +#else + fprintf(stderr, "ERROR: Debugger is disabled in non-debug builds\n"); + exit(1); + break; +#endif case 'e': rval.script_code_to_exec = optarg; break; case 'f': rval.pcap_filter = optarg; break; case 'h': rval.print_usage = true; break; @@ -489,7 +497,15 @@ Options parse_cmdline(int argc, char** argv) { rval.pcap_file = optarg; break; case 's': rval.signature_files.emplace_back(optarg); break; - case 't': rval.debug_script_tracing_file = optarg; break; + case 't': +#ifdef DEBUG + rval.debug_script_tracing_file = optarg; + break; +#else + fprintf(stderr, "ERROR: Script tracing is disabled in non-debug builds\n"); + exit(1); + break; +#endif case 'u': ++rval.analysis_options.usage_issues; break; case 'v': rval.print_version = true; break; case 'V': rval.print_build_info = true; break; diff --git a/testing/btest/spicy/file-analyzer-nested.zeek b/testing/btest/spicy/file-analyzer-nested.zeek index 98dccbe7f0..35931a312c 100644 --- a/testing/btest/spicy/file-analyzer-nested.zeek +++ b/testing/btest/spicy/file-analyzer-nested.zeek @@ -1,4 +1,5 @@ # @TEST-REQUIRES: have-spicy +# @TEST-REQUIRES: test "$($BUILD/zeek-config --build_type)" = "debug" # # @TEST-EXEC: spicyz -d -o text.hlto text.spicy ./text.evt # @TEST-EXEC: zeek -r ${TRACES}/http/post.trace text.hlto %INPUT Spicy::enable_print=T | sort -k 3 >output From e7aad5e3e056fd3a962bb12fca814734d99e0719 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 25 Sep 2025 18:35:21 -0700 Subject: [PATCH 4/4] Disable Stmt hooks for the built-in debugger if not a debug build --- src/Stmt.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Stmt.cc b/src/Stmt.cc index 9efda21df1..08a88deee0 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -147,6 +147,7 @@ const AssertStmt* Stmt::AsAssertStmt() const { } bool Stmt::SetLocationInfo(const Location* start, const Location* end) { +#if DEBUG if ( ! Obj::SetLocationInfo(start, end) ) return false; @@ -177,6 +178,9 @@ bool Stmt::SetLocationInfo(const Location* start, const Location* end) { } return true; +#else + return Obj::SetLocationInfo(start, end); +#endif } bool Stmt::IsPure() const { return false; } @@ -436,13 +440,17 @@ ValPtr IfStmt::DoExec(Frame* f, Val* v, StmtFlowType& flow) { f->SetNextStmt(do_stmt); +#if DEBUG if ( ! pre_execute_stmt(do_stmt, f) ) { // ### Abort or something } +#endif auto result = do_stmt->Exec(f, flow); +#if DEBUG if ( ! post_execute_stmt(do_stmt, f, result.get(), &flow) ) { // ### Abort or something } +#endif return result; } @@ -1409,13 +1417,17 @@ ValPtr StmtList::Exec(Frame* f, StmtFlowType& flow) { f->SetNextStmt(stmt); +#if DEBUG if ( ! pre_execute_stmt(stmt, f) ) { // ### Abort or something } +#endif auto result = stmt->Exec(f, flow); +#if DEBUG if ( ! post_execute_stmt(stmt, f, result.get(), &flow) ) { // ### Abort or something } +#endif if ( flow != FLOW_NEXT || result || f->HasDelayed() ) return result;