Fixing EXCEPTION 0XC0000092 floating-point stack error
This error pops up when your code messes up the FPU stack — too many pushes, not enough pops. Here's the fix.
When does this error show up?
You're running a program — maybe an old game, a scientific calculator, or a custom C++ or Delphi app — and it crashes with the message "EXCEPTION (0XC0000092) - Floating-point stack check." It usually happens right after a math operation or when the program tries to switch between floating-point and integer code. I've seen it most often in legacy applications compiled with older Borland tools or in hand-written assembly code.
What's really going on?
The x87 FPU (floating-point unit) has its own stack, eight registers deep. Each time you do an FPU operation like FADD or FMUL, you push results onto that stack. If you push more than eight items without popping them, or if you pop when the stack's empty, the FPU throws this exception. The CPU detects the imbalance and raises 0xC0000092.
The real trigger is almost always a mismatch between the number of FPU pushes and pops. Maybe you're calling a function that uses the FPU but forgets to clean up afterward. Or you're using inline assembly that leaves extra values on the stack. The compiler itself can also miscompile floating-point code if optimization levels are too aggressive.
Step-by-step fix
Step 1: Identify the crashing function
First, you need to find exactly where the error occurs. If you've got the source code, compile with debug symbols enabled. Run the program in a debugger like Visual Studio, WinDbg, or gdb. When it crashes, look at the call stack. The last function that did any floating-point math is your prime suspect.
Expected outcome: You'll see a function name in the call stack, something like CalculateInterest or DrawPolygon. Write that down.
Step 2: Check FPU stack at function entry and exit
Open the crashing function and look at the assembly code. In Visual Studio, you can view the disassembly window. Look for FINIT, FLD, FSTP, FADD, FMUL, and FCOMP instructions. Count the FLD instructions (pushes) and the FSTP instructions (pops). The counts must match.
Expected outcome: You'll probably see more FLDs than FSTPs. Example: three FLDs but only two FSTPs. That missing pop is the bug.
Step 3: Fix the imbalance
Add FSTP ST(0) or FFREE ST(0) to remove unused values from the FPU stack. If you're using C or C++, you can also use the _fpreset() function to reset the FPU state, but that's a sledgehammer — only use it if the code is too complex to fix by hand. In Delphi, call Set8087CW(Default8087CW) to reset the control word.
Don't skip this: Some compilers have a "fast" floating-point model that skips stack checks. Turning it off can mask the bug but not fix it. The real fix is matching every push with a pop.
Expected outcome: After adding the pop, the function should no longer crash during testing.
Step 4: Recompile and test
Rebuild your program with debug symbols still on. Test the specific scenario that used to crash. If the error is gone, you've fixed it.
Expected outcome: The program runs without the floating-point stack check exception.
What if it still fails?
You fixed the function you identified, but the error comes back elsewhere. That means there's another spot with the same problem. Run the debugger again and look at the new call stack. It's common for one program to have multiple FPU stack bugs, especially if it's old or written by multiple people.
Also check third-party libraries or DLLs you're calling. Some old math libraries don't clean up their FPU state. If you can't modify them, wrap the calls in a function that saves and restores the FPU state using _controlfp( _CW_DEFAULT, 0xFFFF ) in C or the SaveFPUState / RestoreFPUState functions in Delphi.
One more thing: if you're using inline assembly, double-check that all your __asm { ... } blocks leave the FPU stack exactly as they found it. This is a common oversight even for experienced developers.
Was this solution helpful?