STATUS_STACK_OVERFLOW_READ (0XC0000228) Fix: Stack Overflow Code Required
This BSOD means a thread tried to read beyond the stack's guard page. The fix is usually adjusting the stack size in your code or linker settings.
Quick Answer
Set /STACK:reserve,commit in your linker flags or increase the thread's stack size via CreateThread(NULL, stack_size, ...). The reserve value must be at least 1 MB, commit at least 64 KB. For deep recursion, rewrite iteratively or increase the stack to 4 MB+.
What's Actually Happening Here
The error STATUS_STACK_OVERFLOW_READ (0XC0000228) is a Windows bug check that fires when a thread's stack pointer crosses the guard page boundary. Every thread gets a reserved stack region, and the last 4 KB page is marked as a guard page. When the CPU tries to read from this page—say, because a function call pushed too many locals or recursion went too deep—the memory manager catches it and raises this exception. The system expects your exception handler to deal with it, but if you don't have one, or if the handler itself overflows, you get the BSOD.
I've seen this most often in: 1) C/C++ programs with heavy recursion (e.g., quicksort on 100k+ elements), 2) Win32 apps that spawn threads with default stack size (1 MB) and then allocate huge stack buffers, and 3) driver code where the stack is limited to 12 KB. In user mode, the fix is almost always a linker or thread creation tweak. In kernel mode, you're probably out of luck—rewrite the algorithm.
Fix Steps
- Identify the culprit thread — Open the crash dump in WinDbg and run
!analyze -v. Look forDEFAULT_BUCKET_ID: STACK_OVERFLOW. The output shows the thread's stack trace and the exact instruction that hit the guard page. If you don't have a dump, reproduce the crash under a debugger and note the stack depth. - Check your recursion depth — If you're using recursion, add a counter. In C/C++:
Run the code with a breakpoint on the exit. If it hits, you're recursing beyond your stack's capacity. Switch to an iterative solution (e.g., use astatic int depth = 0; if (++depth > 10000) { printf("Too deep\n"); exit(1); }std::stack). - Increase the thread's stack size at creation — If you create threads manually, pass a larger stack to
CreateThread:
That's 4 MB. Default is 1 MB. For the main thread, change the linker setting.HANDLE hThread = CreateThread(NULL, 4 * 1024 * 1024, ThreadFunc, NULL, 0, &tid); - Change linker stack reserve and commit — In Visual Studio, go to Project Properties → Linker → System → Stack Reserve Size. Set it to
4194304(4 MB). Stack Commit Size to65536(64 KB). Alternatively, add this to your source:#pragma comment(linker, "/STACK:4194304,65536") - Rebuild and test — Clean rebuild the project. Run the same scenario that caused the crash. If it still BSODs, the stack growth exceeded your new reserve. Bump it to 8 MB.
Alternative Fixes
If the linker trick didn't work:
- Use
_chstkprobes — Some compilers omit stack probes in release builds. Force them with/Gsflag in MSVC. This doesn't fix the overflow but makes it crash earlier, which is better than a random BSOD later. - Switch to a fiber or coroutine — Fibers let you allocate a custom stack per fiber. See
ConvertThreadToFiberandCreateFiber. This is extreme but works if you have thousands of threads each needing a big stack. - Use structured exception handling — Wrap the risky code in a
__try/__exceptblock. But note: if you handleEXCEPTION_STACK_OVERFLOW, you must restore the guard page yourself viaVirtualProtect, otherwise the next overflow immediately crashes. Microsoft's recommended pattern:__try { recursive_func(); } __except(GetExceptionCode() == EXCEPTION_STACK_OVERFLOW ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { // Reset guard page, then exit or retry }
Prevention Tip
Never rely on the default 1 MB stack for production code that does anything nontrivial. Set your linker stack reserve to at least 2 MB per thread you expect to have deep call chains. For recursive algorithms, always benchmark the maximum depth under realistic load. Better yet, avoid unbounded recursion entirely—replace it with an explicit stack data structure. That gives you control over memory and avoids the BSOD entirely.
Was this solution helpful?