April 27, 2024, 09:41:25 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


unexpected out of stack Space

Started by TexasPete, November 11, 2010, 06:56:07 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

TexasPete

I was simply calling and editor sub routine with a gosub and recieved "out of Stack SPace" error message. I did not expect this because it was a simple gosub from the main handler routine. The Routine is called from the same handler for another routine and works fine. Any ideas?

Texas Pete

aurelCB

Give us some code...
You obviusly do something wrong...

sapero

November 12, 2010, 03:27:32 PM #2 Last Edit: November 12, 2010, 03:56:50 PM by sapero
sub sub1()
def y as string[128] ' 255 * 128 = 32640
return

sub sub2()
def x as string[128] ' 255 * 128 = 32640
sub1()
return


If you start in the second subroutine - sub2, the X variable takes 32640 bytes from the stack. This amount of memory is not released until you return from sub2.
Then you (sub2) are calling the first subroutine (sub1) which is allocating another 32640 bytes from the stack. Total stack used is the sum: 32640+32640+some small internal amount (at least 4 bytes).

The total size of stack memory is fixed. The memory is divided into allocated (commited) and reserved part. After you allocate stack memory over the commited range, the system will automatically (*) commit additional memory from the reserved portion, but the final size of commited memory will be never greater than than (1MB) - a fixed value, defined in your exe image.
* - this will happen only when you do a read or write to the first stack memory page out of current limit (there is a special guard page) - for example, when recursively calling a subroutine with small size of local variables you will access that guard page generating an recoverable exception handled by the system. Exception handler will commit additional stack memory, moving the guard page down. But if the size of variables is for example 8192+ bytes (two memory pages), you will skip over the guard page, so any read/write to stack variables, or when calling another subroutine: there will be no guard page exception, the stack will be not grown, and your program will terminate with access violation error, optionally converted to stack overflow.

So, when your subroutines allocate huge buffers, take care, be sure that the total size of all local variables is not greater than ~90% of the total stack memory, there must be a space for the operating system, for api functions and exceptions handler. When your program starts, you have already less than 100% of the total stack memory.
If you really need huge buffers, use NEW or ALLOCMEM to allocate memory as you need it, or if possible, define your huge variables as global variables (outside subroutines).
You never know how much free stack you have in a subroutine, with the exception when that subroutine is called only from another subroutine, and there is no callback in this chain.
Example: program start -> sub1 -> sub2 -> sub3 ...
Example with callback (unknown size of free stack): window handler -> case xxx -> sub1 -> sub2 ...

TexasPete

Great explanation . It may be one of the clues that I needed to find my bug.
I now have a better idea of what to look for.
Thanks
Texas Pete