From ec05fcf3d4b9612424f8bdcb1be45cb7b4595a0e Mon Sep 17 00:00:00 2001 From: leftibot Date: Thu, 30 Apr 2026 16:54:56 -0600 Subject: [PATCH] Address review: tighten max_call_depth on MSVC Debug Windows MSVC Debug builds crashed unit.recursion_depth_protection.chai with SEGFAULT before the depth check could fire. Windows defaults to a 1 MiB thread stack and Debug builds emit much larger per-frame native stack usage (no inlining, /RTC, buffer security checks), so 256 nested ChaiScript calls overflow the native stack long before the dispatcher reaches max_call_depth. Linux/macOS and MSVC Release pass at 256. Pick a tighter default (32) only for the MSVC + _DEBUG configuration that needs it, leaving every other build at the original 256, and shrink the count_down recursion in the regression test so the bounded path stays well below every platform's default. Requested by @lefticus in PR #700 review. Co-Authored-By: Claude Opus 4.7 (1M context) --- include/chaiscript/chaiscript_defines.hpp | 10 ++++++++++ unittests/recursion_depth_protection.chai | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index a5d8c6df..43866f64 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -79,9 +79,19 @@ static_assert(_MSC_FULL_VER >= 190024210, "Visual C++ 2015 Update 3 or later req // causes the dispatcher to throw chaiscript::exception::stack_overflow_error // instead of letting the native call stack overflow. Defining the macro on // the command line overrides the default. +// +// MSVC Debug builds emit very large per-frame native stack usage (no inlining, +// /RTC, buffer security checks) and Windows defaults to a 1 MiB thread stack, +// so the same ChaiScript depth that fits comfortably on Linux/macOS or in an +// MSVC Release build overflows the native stack before the depth check fires. +// We pick a tighter default in that configuration to keep the throw reachable. #ifndef CHAISCRIPT_MAX_CALL_DEPTH +#if defined(CHAISCRIPT_MSVC) && defined(_DEBUG) +#define CHAISCRIPT_MAX_CALL_DEPTH 32 +#else #define CHAISCRIPT_MAX_CALL_DEPTH 256 #endif +#endif #include #include diff --git a/unittests/recursion_depth_protection.chai b/unittests/recursion_depth_protection.chai index 082854ff..716edb9a 100644 --- a/unittests/recursion_depth_protection.chai +++ b/unittests/recursion_depth_protection.chai @@ -30,10 +30,12 @@ assert_true(caught) // distinguish it from an arbitrary script-level error. assert_true(find(message, "call stack") != -1) -// A bounded recursion that stays below the limit must keep working. +// A bounded recursion that stays well below the limit must keep working. +// Use a small depth so the test passes on every platform default - notably +// the MSVC Debug build where the native stack budget forces a tighter cap. def count_down(n) { if (n <= 0) { return 0 } return count_down(n - 1) + 1 } -assert_equal(50, count_down(50)) +assert_equal(10, count_down(10))