-Problematic stack size settings

The behaviour described in the bug report is either by design, or would be far too complex/time-consuming to be changed

Moderators: Hacker, petermad, Stefan2, white

Post Reply
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

-Problematic stack size settings

Post by *MarcinW »

Steps to reproduce - tested with TC 8.51a 32-bit, reproducible only under Windows XP or Windows 2003 Server.
1) Open "Properties" window for Totalcmd.exe (Alt+Enter in Explorer).
2) Go to "Compatibility" tab.
3) Check "Run this program in compatibility mode for:" option and select "Windows 95" or "Windows 98 / "Windows ME".
4) Launch TC - it will start and immediately terminate silently.


Fix:
Totalcmd.exe: change $M Delphi directive from {$M $4000,$80000} to {$M $10000,$80000} - you may also increase the second parameter.
Totalcmd64.exe: change $M Delphi directive from {$M $1000 $1000000} to {$M $10000 $1000000}.


Explanation:
Each EXE file has (in its PE header) information about stack requirements: minimum and maximum stack size (for DLLs these values are ignored, because settings of EXE file that created the process are used). In Delphi, $M directive sets these values.

During the application startup, operating system allocates memory amount for the stack as requested by the "minimum size" value. Below this memory, OS places a memory page with PAGE_GUARD attribute set, and below this page OS creates a reserved address space (not allocated initially). Total size of these three areas is equal to "maximum size" value (rounded up to a 64kB boundary if needed). When application needs more and more stack, it touches the guard page eventually. This raises an EXCEPTION_GUARD_PAGE exception, but OS handles this exception internally and silently - it allocates an additional memory page in the previously reserved space and also recreates the guard page at the end of allocated memory space. This can be repeated until reserved address space is fully allocated - the stack can't grow anymore and the operating system raises a stack overflow exception.

For example, under Windows XP, when minimum stack size is 0x4000 and maximum stack size is 0x80000, the stack looks initially like this:

Code: Select all

BaseAddress: 000BC000  RegionSize: 00004000  State: COMMIT    Protect: 00000004  <- allocated stack area
BaseAddress: 000BB000  RegionSize: 00001000  State: COMMIT    Protect: 00000104  <- guard page
BaseAddress: 00040000  RegionSize: 0007B000  State: RESERVE                      <- reserved area
After some stack usage, it may look like this:

Code: Select all

BaseAddress: 0009A000  RegionSize: 00016000  State: COMMIT    Protect: 00000004  <- allocated stack area
BaseAddress: 00099000  RegionSize: 00001000  State: COMMIT    Protect: 00000104  <- guard page
BaseAddress: 00030000  RegionSize: 00069000  State: RESERVE                      <- reserved area
After handling a stack overflow exception, stack structure is damaged - there is no guard page anymore, and touching a reserved area will raise an access violation exception - but due to lack of the stack there will be no possibility to handle this exception by the application and application will be terminated:

Code: Select all

BaseAddress: 00031000  RegionSize: 0007F000  State: COMMIT    Protect: 00000004  <- allocated stack area
BaseAddress: 00030000  RegionSize: 00001000  State: RESERVE
Under Win9x family, stack is constructed in a bit other manner, but general rules are same.

To handle the stack properly, compilers don't allocate stack area in pieces larger than 0x1000 bytes at once - this guarantees that the guard page will be touched and not jumped over. When some function uses local variables larger than 0x1000 bytes, compiler allocates stack in 0x1000-byte pieces in a loop:

Code: Select all

SomeFunction:
    push  eax
stack_alloc_loop:
    mov   eax,$00000150 ; we are allocating local variables of total size 0x150 * 0x1000
    add   esp,$FFFFF004 ; same as: sub esp,$00000FFC
    push  eax           ; touch the stack (potentially a guard page)
    dec   eax
    jnz   stack_alloc_loop


So, where the problem is? Well, Windows operating systems have bugs in stack handling - sometimes guard page is not created. This varies between Win9x and WinNT family, and in most cases happens only when the defined minimum stack size is almost equal or equal to the maximum stack size. In this case, when the stack is near overflow, a stack overflow exception can't be raised properly and application terminates immediately. To avoid all potential problems, always allocate stack in this way:

minimum size = x * 0x10000
maximum size = y * 0x10000
where: y > x

For example:
{$M $00050000,$00050000} - this will cause problems under Win9x
{$M $0003F000,$00040000} - this will cause problems under WinNT
{$M $00500000,$00500000} - this will cause problems under Win9x and WinNT
{$M $00010000,$00220000} - this will not cause any problems


In TC case, when compatibility mode with Win9x is on, the stack looks initially like this:

Code: Select all

BaseAddress: 000B0000  RegionSize: 00010000  State: COMMIT    Protect: 00000004
BaseAddress: 00040000  RegionSize: 00070000  State: RESERVE
There is no guard page here - in fact, stack is already damaged. After using first 0x10000 bytes of stack, it won't be enlarged - TC will raise an access violation exception, but due to lack of the stack there will be no possibility to handle this exception by TC and TC will be terminated.


Summary:
First parameter of the $M directive (minimum stack size) should be set to $10000 in both x32 and x64 versions. This will not increase memory usage, because even now TC allocates more than $10000 bytes of stack before even shows any window. I don't know if there are problems with invalid stack structure in x64 applications, but it's better to be on the safe side.

Besides, the second $M parameter (maximum stack size) in x32 version could also be increased. It is currently only $80000 = 512kB of memory - it could be set for example to $200000 = 2MB. This memory won't be allocated without a real need - just 1.5MB of an additional address space will be reserved. This would allow TC plugins to use more stack without raising a stack overflow exception by TC. In x64 version, the maximum stack size is already set to $1000000 = 16MB - but there is a lot of address space in x64 mode, so such a large reserved address space isn't any problem. We should also remember, that stack usage in x64 mode is larger - each stack element (PUSH and POP instructions) occupies 8 bytes, not 4 bytes as in x32 mode.


Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50547
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

Why should I change this? Did you ever encounter a problem with the stack size? I haven't received a single report where this was a problem...
Author of Total Commander
https://www.ghisler.com
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Re: Problematic stack size settings

Post by *milo1012 »

MarcinW wrote:Each EXE file has (in its PE header) information about stack requirements: minimum and maximum stack size
No, this is not minimum stack size but the Commit size, i.e. how much of physical memory to allocate at a time (one page).
See e.g. here, here and here.

The $M Compiler Directive just speaks of Minimum because this is what you have at program start and the stack can grow of course, but only one Commit size at a time.
MarcinW wrote:Windows operating systems have bugs in stack handling
Citation? Source? (reliable)

Anyway, I think every decent programmer knows that you should avoid large data structures on Stack, but use the Heap instead.
I never had any problems with stack overflow, even with ~30 plugins loaded all the time, where each uses some amount of stack.

I agree that 0x80000 is a bit "off standard", most compilers will use 1 MiB (0x100000) or even more, but like I said, no problems so far.
The Commit 0x4000 is already quite high (but standard for Delphi compilers AFAIK),
most compilers use 0x1000, so I don't see a reason to change it to an even higher value.

That example of Win9x compat. mode is quite artificial and I don't think should count as a valid scenario.
I have a few other programs which also won't run when I force that mode, so what did you expect will happen if you force such things?

And to quote this article where asking about stack size:
If you have to ask, you're probably doing something wrong.
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

Thanks for your reply. I'm afraid that you misunderstood the documentation, which is - I must admit - very unclear.

To be very clear: it is NOT true (at least on x32 platforms) that the stack grows in "Commit size" amounts - it grows in 4kB amounts (0x1000 bytes - one memory page). Windows allocates initially "Commit size" bytes and expands this area in 4kB amounts when needed.


milo1012 wrote:
MarcinW wrote:Each EXE file has (in its PE header) information about stack requirements: minimum and maximum stack size
No, this is not minimum stack size but the Commit size, i.e. how much of physical memory to allocate at a time (one page).
See e.g. here, here and here.

The $M Compiler Directive just speaks of Minimum because this is what you have at program start and the stack can grow of course, but only one Commit size at a time.
As I said, it is not true. My explanations are in italic:

Here we can read: In Windows WindowsRT it specifies the amount of physical memory to allocate at a time [of application loading]. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space [because a larger stack area is already allocated at startup, so OS doesn't have to handle many stack guard page exceptions], but increases the memory requirements and possibly the startup time. For ARM, x86 and x64 machines, the default commit value is 4 KB [this means that the stack has 4kB of memory commited initially, not that it is enlarged in 4kB amounts - which is however, for 4kB, the same].

Here we can read: SizeOfStackReserve - The number of bytes to reserve for the stack. Only the memory specified by the SizeOfStackCommit member is committed at load time [!!!]; the rest is made available one page [= 4kB] at a time until this reserve size is reached.

Here I can't find any information about increasing stack in amounts other than 4kB...

Because you have no reason to believe me, I prepared a Demo 1 - see below. This demo has minimum stack size ("Commit size") equal to 0x10000 and - after some iterations - it shows that this area is increased in 0x1000-byte amounts (not 0x10000-byte amounts).


milo1012 wrote:
MarcinW wrote:Windows operating systems have bugs in stack handling
Citation? Source? (reliable)
My own tests. I performed in-depth analysis of this topic and I even wrote an exception handler that can repair the stack after a stack overflow exception (by recreating a guard page). See Demo 2 below - you can compare demo EXE files and see that they differ only in minimum and maximum stack size in PE header - but due to these differences, some of EXEs can survive a stack overflow exception, and some can't (because of lack of a stack guard page).


milo1012 wrote:Anyway, I think every decent programmer knows that you should avoid large data structures on Stack, but use the Heap instead.
You are right.


milo1012 wrote:I never had any problems with stack overflow, even with ~30 plugins loaded all the time, where each uses some amount of stack.
It's very probable. However, there is a chance that you had such problems, but they weren't reported as stack overflow exceptions - see my next post below.


milo1012 wrote:I agree that 0x80000 is a bit "off standard", most compilers will use 1 MiB (0x100000) or even more, but like I said, no problems so far.
The Commit 0x4000 is already quite high (but standard for Delphi compilers AFAIK),
most compilers use 0x1000, so I don't see a reason to change it to an even higher value.
I can see three reasons:
- this will solve a problem described in my first post,
- this will not increase memory usage, because TC needs more than 0x10000 bytes of stack, so this memory will be allocated earlier (at startup) or later (at runtime),
- commiting one larger memory block is faster than handling several stack guard page exceptions and allocating several separate pages of memory.


milo1012 wrote:That example of Win9x compat. mode is quite artificial and I don't think should count as a valid scenario.
Yes, it is a bit artificial, but it just shows a symptom of a more general problem with invalid stack structure.


milo1012 wrote:I have a few other programs which also won't run when I force that mode, so what did you expect will happen if you force such things?
This may be exactly same problem: SizeOfStackCommit value in PE header, that is lower than 0x10000. Try to edit this value in PE header - editing this in Totalcmd.exe solves the problem that I described (but TC displays a virus alert and terminates). To edit, you may use CFF Explorer from Explorer Suite.


milo1012 wrote:And to quote this article where asking about stack size:
If you have to ask, you're probably doing something wrong.
We are not doing anything wrong. Microsoft implemented stack handling in a buggy way, and we must work around this.



Regards!


Demo 1 and Demo 2 - tested with Windows 98 SE and Windows XP SP3.

Code: Select all

MIME-Version: 1.0
Content-Type: application/octet-stream; name="Demo.7z"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Demo.7z"

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
IRYutQAA
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

ghisler(Author) wrote:Why should I change this?
Changing the minimum stack size will fix the problem that I described.

Increasing the maximum stack size it's just a suggestion. Delphi default value is 1MB - and Windows NT family always reserves 1MB, even if we declare a lower value. But TC may use many recursive function calls when exploring a directory tree, so I think that 2MB is a reasonable value. Assuming 260-char path limit, there are 128-level recurrences possible. For 2MB stack size, this gives about 16kB of available stack per one nested function call - this allows to declare a local buffer for 8192 unicode chars. Increasing the maximum stack size will not consume any additional memory - unless really needed. This will just reserve an additional address space for the stack.

ghisler(Author) wrote:Did you ever encounter a problem with the stack size? I haven't received a single report where this was a problem...
When a stack overflow exception is raised, there are only last 0x1000 bytes of stack that can be used to handle this exception. So the exception handler is not allowed to use more than 0x1000 bytes of stack. But TC uses more than 0x1000 bytes of stack when handling exceptions, so it cannot handle a stack overflow exception properly (I created a plugin that raises a stack overflow to check this) - the operating system kills TC silently or with a message like this:

Code: Select all

--------------------------------
TOTALCMD.EXE - Application Error
--------------------------------
The exception unknown software exception (0x0eedfade) occurred in the application at location 0x793fbcb1.
--------------------------------
OK   Cancel
--------------------------------
So you'll never get a bug report saying that a stack overflow happened - you'll get reports saying that TC disappeared unexpectedly or with an error message like above.


Regards
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50547
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

When a stack overflow exception is raised, there are only last 0x1000 bytes of stack that can be used to handle this exception.
Where did you find this? I didn't know that there is such a limit. Therefore the better option would be to reduce the stack usage of the exception handler, e.g. by using static data blocks or allocated data.
Author of Total Commander
https://www.ghisler.com
User avatar
milo1012
Power Member
Power Member
Posts: 1158
Joined: 2012-02-02, 19:23 UTC

Post by *milo1012 »

MarcinW wrote:I'm afraid that you misunderstood the documentation
No, it's indeed quite clear, but we have a little "clash of terms".
You spoke of minimum stack size while you meant the Commit size, which every documentation about that concept means and uses.
MarcinW wrote:it is NOT true (at least on x32 platforms) that the stack grows in "Commit size" amounts
I said "how much of physical memory to allocate at a time (one page)".
Of course we can only grow/get one memory page at a time, but several after another until the program's need is satisfied.
Yes, I shouldn't have called it Commit when I meant page.
The whole thing is subject to interpretation, but it's true that Commit just means the init size,
although I highly doubt that that you will always get a guarantee for that size, especially when it comes to things like Wine/ReactOS
and the documentation also says so: "commit is subject to interpretation by the operating system"

BTW, TC already uses a decent amount of background threading, especially when it comes to plugins,
where the thread gets it's own stack space on startup. ("Thread Stack Size")
Just use tools like VMMap to see that Stack overflow is really the least thing to worry about.
And that is where things might get ugly, because every created thread uses that values laid out in the main EXE file, unless you specify it on creation.
So changing that Commit value will affect all Threads and therefore more than you probably want.
MarcinW wrote:you have no reason to believe me
I never doubted you, but the relevance of it, since you post this as actual bug report.
MarcinW wrote:We are not doing anything wrong. Microsoft implemented stack handling in a buggy way
You still miss an official reference for that, it's just your opinion from observation.
MarcinW wrote:My own tests. I performed in-depth analysis of this topic and I even wrote an exception handler that can repair the stack after a stack overflow exception
I can also do my own tests and argue with my results and real-life-scenarios where such things are completely off the subject.
If you're looking for troublesome behavior you will probably always find some.
Did you post your observations or code on some other sites besides here?
MarcinW wrote:Try to edit this value in PE header
I don't have to because I can easily simulate such things in my own program and some recursive functions.
MarcinW wrote:but TC displays a virus alert and terminates
Yes, because of internal integrity check routines.
MarcinW wrote:Assuming 260-char path limit
This limit is not necessarily valid any more since TC uses up to 1024 since 7.50 due to Unicode functions supporting more than MAX_PATH.
MarcinW wrote:When a stack overflow exception is raised, there are only last 0x1000 bytes of stack that can be used to handle this exception.
You can check it and still start a new thread or use a BG thread to handle the exception with all necessary reports.
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

@milo1012: OK, so we were talking about same things, but using different terms. Because we agree now how stack works, I consider this part of discussion as closed.

milo1012 wrote:I highly doubt that that you will always get a guarantee for that size
If stack settings are enormously high, OS will fail to launch an application. Otherwise we are guaranteed to get what we want.

milo1012 wrote:especially when it comes to things like Wine/ReactOS
These systems are going to be fully compatible with Windows, so I don't think we should be afraid of that.

milo1012 wrote:although I highly doubt that that you will always get a guarantee for that size, especially when it comes to things like Wine/ReactOS
and the documentation also says so: "commit is subject to interpretation by the operating system"
This probably means that OS may commit a memory block larger than asked - but never smaller.

milo1012 wrote:BTW, TC already uses a decent amount of background threading, especially when it comes to plugins,
where the thread gets it's own stack space on startup. ("Thread Stack Size")
Just use tools like VMMap to see that Stack overflow is really the least thing to worry about.
And that is where things might get ugly, because every created thread uses that values laid out in the main EXE file, unless you specify it on creation.
So changing that Commit value will affect all Threads and therefore more than you probably want.
You made an important notice. As you wrote, threads use stack settings of the main EXE by default. This means, that they may also suffer from stack handling problems. So, as for me, it's just another reason for changing minimum stack size (commit size) to 0x10000.

milo1012 wrote:
MarcinW wrote:you have no reason to believe me
I never doubted you, but the relevance of it, since you post this as actual bug report.
Well, to be thorough, the bug is inside Microsoft's application compatibility layer (invalid stack handling), not in the TC - TC only suffers from this bug. However, this problem may be easily worked around by changing minimum stack size to 0x10000 in TC.

milo1012 wrote:
MarcinW wrote:We are not doing anything wrong. Microsoft implemented stack handling in a buggy way
You still miss an official reference for that, it's just your opinion from observation.
Yes, I confirm that it's just my opinion from observations. I have no other reliable information sources, because Microsoft haven't currently documented stack internals in any official way (or I'm not aware of it).

I fact, from time to time I must use my own observations instead of the official documentation, because it is incomplete or just wrong. This is probably because programmers write the code, and non-programmers write the documentation. For example, I reported wrong values of returned error codes for SHGetFolderPath and SHGetFolderPathAndSubDir functions in MSDN - like ERROR_FILE_NOT_FOUND instead of HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) etc. And I waited several months for a correction. What's worse, they removed "Send comment about this topic to Microsoft" option from MSDN pages...

milo1012 wrote:I can also do my own tests and argue with my results and real-life-scenarios where such things are completely off the subject. If you're looking for troublesome behavior you will probably always find some.
Well, I discovered stack handling problems not because I have too much free time, but because my application running in a factory used to disappear from time to time unexpectedly. So stack handling problems are not off the subject for me.

milo1012 wrote:Did you post your observations or code on some other sites besides here?
Yes, I send my bug reports to Microsoft.

milo1012 wrote:
MarcinW wrote:Assuming 260-char path limit
This limit is not necessarily valid any more since TC uses up to 1024 since 7.50 due to Unicode functions supporting more than MAX_PATH.
Yes, I know that (but I'm sure that the path limit is 32767 chars, not 1024 chars), but I gave a more common example. For 1024 chars it's even worse: you can have about 512-level recurrences possible, so for the current maximum stack value (0.5MB) this is only about 1024 bytes of stack per iteration. So it's another reason to increase the maximum stack size.

milo1012 wrote:
MarcinW wrote:When a stack overflow exception is raised, there are only last 0x1000 bytes of stack that can be used to handle this exception.
You can check it and still start a new thread or use a BG thread to handle the exception with all necessary reports.
Well, I'm aware that an exception can be handled in a context of another thread - this technique is used for example in Delphi when thread object calls some function in a context of the main thread (Delphi 5, Classes.pas: ThreadWndProc and TThread.Synchronize). But this is problematic, because exception context is connected with thread that raised an exception, not with a new thread that you launched to handle this exception.


Regards
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

@ghisler(Author): My initial bug report evolved into three separate topics, so let's make a summary.


1) Minimum stack size (in Delphi set by the first parameter of the $M directive or by the $MINSTACKSIZE directive)

For values below 0x10000, there may be some problems, that I described in my first post - not because TC has bugs, but because Windows may handle the stack improperly (= Windows has bugs). These problems are visible when TC is launched in a Win9x compatibility mode - only under Windows XP and Windows 2003 Server (under Windows Vista there is no problem).

As a workaround, I recommend to change minimum stack size from 0x4000 to 0x10000:
- drawback: secondary threads, created by plugins, may require less stack than 0x10000, so this will be a small waste of commited memory (assuming that we have 20 threads using no more than 0x4000 bytes of stack, we will lost less than 1MB of memory),
- benefit 1: TC will be able to start successfully regardless of compatibility settings and Windows version,
- benefit 2: this will ensure that TC will always get a chance to handle potential stack overflow exceptions,
- benefit 3: TC will start slightly faster (however the user will not see any difference).


2) Maximum stack size (in Delphi set by the second parameter of the $M directive or by the $MAXSTACKSIZE directive)

There is no problem with the current 0x80000 value, I only suggested to increase this value:
- drawback: more address space (but not memory) will be reserved,
- benefit: TC will be able to handle plugins that need more stack - especially for long paths.

Additional note: Windows NT family always uses at least 1MB as a maximum stack size, even if we declare a lower value - so currently TC declares 0.5MB, but receives 1MB. Mistake, it should be: Windows NT family always uses at least 256kB as a maximum stack size, even if we declare a lower value.


3) Current implementation of exception handler in TC (its ability to handle stack overflow exceptions)

I created a new topic in the suggestions forum for this discussion here.


Regards
Last edited by MarcinW on 2014-06-03, 22:13 UTC, edited 1 time in total.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 50547
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Post by *ghisler(Author) »

1) Since people have to set Win9x compatibility mode themselves, there should be no problem with TC stops working then - they would know that this last change caused the problem. I do not want to increase the minimum just because this is used for all threads (and TC uses quite a few threads).
2) The downside is that plugin writers may use a lot of stack and test only with the latest TC, so the plugin would then fail with older TC versions.
3) I agree, thanks for the suggestion! I wonder how you found this function, it's very useful but I never heared about it...
Author of Total Commander
https://www.ghisler.com
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

2) OK. So it would be better to change the current maximum stack size to 0x100000 (1MB). Currently TC gets 1MB under WinNT (WinNT always gives at least 1MB) and 0.5MB under Win9x, so a plugin writer may test his plugin under WinNT and doesn't notice that there will be a problem under Win9x. Mistake - Windows NT family always uses at least 256kB as a maximum stack size, even if we declare a lower value - so this doesn't affect TC in any way, because TC requests 0.5MB.

3) Well, most probably I reviewed a "Process and Thread Functions" section in MSDN, just to see what was added in new Windows versions... It really seems that almost nobody knows about this function.
User avatar
MarcinW
Power Member
Power Member
Posts: 852
Joined: 2012-01-23, 15:58 UTC
Location: Poland

Post by *MarcinW »

I found MSDN articles, that answer some questions asked here:

Thread Stack Size

_resetstkoflw
Post Reply