Root > Reference > All Functions > _resetstkoflw

Function _resetstkoflw

Previous pageReturn to chapter overviewNext page   

Recovers from stack overflow.

 

Unit

ELowLevel

 

Syntax

 

Code (Delphi)

function _resetstkoflw: Boolean;

 

Return value

True if the function succeeds, False if it fails.

 

Remarks

The _resetstkoflw function recovers from a stack overflow condition, allowing a program to continue instead of failing with a fatal exception error. If the _resetstkoflw function isn't called, there are no guard pages after the previous exception. The next time that there's a stack overflow, there are no exceptions at all and the process terminates without warning.

 

If a thread in an application causes an EStackOverflow exception, the thread has left its stack in a damaged state. This is in contrast to other exceptions such as EAccessViolation or EDivByZero, where the stack isn't damaged. The stack is set to an arbitrarily small value when the program is first loaded. The stack then grows on demand to meet the needs of the thread. This is implemented by placing a page with PAGE_GUARD access at the end of the current stack. For more information, see Creating Guard Pages.

 

When the code causes the stack pointer to point to an address on this page, an exception occurs and the system does the following three things:   Removes the PAGE_GUARD protection on the guard page so that the thread can read and write data to the memory.  Allocates a new guard page that is located one page below the last one.  Reruns the instruction that raised the exception.  In this way, the system can increase the size of the stack for the thread automatically. Each thread in a process has a maximum stack size. The stack size is set at compile time by the "Project" -≤ "Options" -≤ "Linking" -≤ "Maximum Stack Size", or by the {$MAXSTACKSIZE number} statement in the source code file of the project.

 

When this maximum stack size is exceeded, the system does the following three things:   Removes the PAGE_GUARD protection on the guard page, as previously described.  Tries to allocate a new guard page below the last one. However, this fails because the maximum stack size has been exceeded.  Raises an exception so that the thread can handle it in the exception block.  At that point, the stack no longer has a guard page. The next time that the program grows the stack all the way to the end, where there should be a guard page, the program writes beyond the end of the stack and causes an access violation.

 

Call _resetstkoflw to restore the guard page whenever recovery is done after a stack overflow exception. This function can be called from inside the main body of an except block or outside except block. However, there are some restrictions on when it should be used. _resetstkoflw shouldn't be called from:   An except block.  A finally block.  Any type of exception hook or filter function.  At these points, the stack isn't yet sufficiently unwound.

 

It isn't safe to call _resetstkoflw in an except block. In this case, the stack space isn't freed and the stack pointer isn't reset until outside the except block. This function shouldn't be called until the stack space is freed and the stack pointer has been reset. Therefore, it should be called only after exiting the except block. As little stack space as possible should be used in the except block.

 

There are situations where _resetstkoflw can fail even if used in a correct location. If, even after unwinding the stack, there's still not enough stack space left to execute _resetstkoflw without writing into the last page of the stack, _resetstkoflw fails to reset the last page of the stack as the guard page and returns False, indicating failure. Safe usage of this function should include checking the return value instead of assuming that the stack is safe to use.

 

Examples

The following example shows the recommended usage of the _resetstkoflw function.

Code (Delphi)

program Project1;

 

{$APPTYPE CONSOLE}

 

uses

SysUtils, ELowLevel;

 

procedure Recursive(const ARecurse: Boolean);

var

// Allocate this buffer on stack

// to exhaust stack faster

Buffer: array[0..1999] of Byte;

begin

// Dummy usage to avoid it to be deleted by smart compiler

Buffer[0] := 0;

if ARecurse then

Recursive(ARecurse or (Buffer[0] <> 0));

end;

 

procedure Work;

var

X: Integer;

ac: Integer;

NeedReset: Boolean;

Recurse: Boolean;

Result: Boolean;

begin

Recurse := True;

 

 // Params:

 // 0 - do not call _resetstkoflw, behave as default application,

 // the fatal access violation will cause application to terminate

 // 1 - do not call _resetstkoflw, exit after stack overflow

 // 2 - call _resetstkoflw and retry

 

ac := StrToIntDef(ParamStr(1), 1);

if ac < 0 then

ac := 0;

Result := (ac = 0);

 

for X := 0 to 9 do

begin

Writeln('Loop ', X + 1);

 

NeedReset := False;

try

Recursive(Recurse);

except

on EStackOverflow do

begin

 // Use minimal stack space here.

 // Do not call _resetstkoflw here, because

 // at this point, the stack isn't yet unwound.

 // Instead, signal that the _resetstkoflw is to be executed.

 NeedReset := True;

end;

end;

 

// Here, it is safe to reset the stack

if NeedReset and (ac >= 2) then

Result := _resetstkoflw;

 

// Terminate if _resetstkoflw failed

if not Result then

begin

ExitCode := 3;

Exit;

end;

end;

 

ExitCode := 0;

end;

 

begin

try

Work;

except

on E: Exception do

Writeln(E.ClassName, ': ', E.Message);

end;

end.

 

 

Sample output with no program arguments:

Code

Loop 1

 

 

Sample output with argument '1':

Code

Loop 1

 

 

Sample output with argument '2':

Code

Loop 1

Loop 2

Loop 3

Loop 4

Loop 5

Loop 6

Loop 7

Loop 8

Loop 9

Loop 10

 

 

See also




Send feedback... Build date: 2026-03-31
Last edited: 2026-03-31
PRIVACY STATEMENT
The documentation team uses the feedback submitted to improve the EurekaLog documentation. We do not use your e-mail address for any other purpose. We will remove your e-mail address from our system after the issue you are reporting has been resolved. While we are working to resolve this issue, we may send you an e-mail message to request more information about your feedback. After the issues have been addressed, we may send you an email message to let you know that your feedback has been addressed.


Permanent link to this article: https://www.eurekalog.com/help/eurekalog/topic_function_ELowLevel__resetstkoflw