EStackOverflow
Delphi Programming Language
Severity: CriticalWhat Does This Error Mean?
EStackOverflow means your program used up all the memory on the call stack. The most common cause is a function that calls itself directly or indirectly in an infinite loop — called infinite recursion. Each function call uses a small amount of stack space. When thousands of calls stack up without returning, the stack is exhausted.
Affected Models
- All Delphi versions
- RAD Studio
Common Causes
- A recursive function without a proper base case, causing it to call itself forever
- Two event handlers calling each other in a loop — for example, an OnChange event that modifies a value, which triggers OnChange again
- A property setter that calls itself — setting a property triggers the setter, which sets the property again
- Allocating a very large local variable on the stack (large arrays or records as local variables)
- Indirect recursion — function A calls B, B calls C, C calls A, forming a cycle
How to Fix It
-
Run the program in the debugger. When EStackOverflow fires, look at the call stack. If you see the same function name repeated hundreds of times, that function is recursing infinitely.
The call stack window shows the chain of function calls. Infinite recursion makes it look like a list of identical names.
-
Add a base case to recursive functions. Every recursive function must have a condition that stops the recursion and returns without calling itself again.
Example: if N <= 0 then Exit; — without this check, the function keeps calling itself forever.
-
For event handler loops (like OnChange firing itself), use a boolean guard flag: declare a private FUpdating field, set it to True at the start of the handler, and check it at the start to exit immediately if already updating.
Example: if FUpdating then Exit; FUpdating := True; try ... finally FUpdating := False; end;
-
Avoid allocating large arrays or records as local variables inside functions. Large local variables take stack space. Use dynamic allocation (New(), GetMem(), or object constructors) for large data.
A function's stack frame is typically a few hundred bytes. A 1 MB local array immediately uses 1 MB of stack space.
-
If deep recursion is unavoidable (like processing deep tree structures), rewrite the algorithm to use a manual stack (a TStack or TList used as LIFO) with a loop instead of recursive function calls.
This moves the 'stack' from the CPU stack to the heap, where there is much more space available.
When to Call a Professional
EStackOverflow is always fixable. The most common fix is to find and break the recursion cycle. For event handler loops, use a boolean guard flag to prevent re-entry. For recursion, ensure the base case is always reachable.
Frequently Asked Questions
How much stack space does a Delphi application have?
By default, a Delphi application has 1 MB of stack space per thread. You can increase this in Project → Options → Linker → Stack size, or using the {$MINSTACKSIZE} and {$MAXSTACKSIZE} directives. However, increasing the stack size is a workaround — fixing the infinite recursion is always the correct solution.
Why does EStackOverflow crash harder than other exceptions?
Handling an exception also requires some stack space. If the stack is completely exhausted, there may not be enough space left to even run the exception handler. This is why EStackOverflow can sometimes cause an unrecoverable crash rather than a catchable exception.
What is the OnChange event loop bug and how common is it?
It is very common in Delphi UI code. Suppose a TEdit's OnChange handler updates another control's value. If that update triggers the same OnChange again, you get infinite recursion. The boolean guard flag (FUpdating) is the standard Delphi solution — set it before making changes and check it at the start of every event handler that might re-enter.