How to check and set stack size limit for Qt applications?

Every process has a stack size limit. If a program’s stack uses up the memory specified by the maximum stack size, it will crash.

How to check the stack size limit of a program?

On Windows, you can use the tool dumpbin(c:\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\dumpbin.exe) to see the limit of the stack size.

dumpbin.exe /headers myapp.exe

You’ll find an entry “1E84800 size of stack reserve” in the dumped “OPTIONAL HEADER VALUES” section. That is the stack size(32,000,000 bytes) for the program. The default stack size is 0x100000(1M bytes).

On Linux, you can use the command:

ulimit -s

ulimit shows the maximum stack size in kbytes. On CentOS 7, the default stack size limit is 10240 KB.

How to change the default stack size limit?

If your program uses many local variables or deep recursive function calls, it may exceed the stack size limit. In this case, you need to increase the stack size for it.

To set a new stack size limit on Windows, you need to use the editbin tool(c:\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\editbin.exe).

editbin.exe /STACK:64000000 myapp.exe

After issuing the above command and checking the “size of stack reserve” field using dumpbin again, you will see the stack limit is modified to 3D09000(64,000,000 bytes) now.

Apart from using the editbin utility, you can also use QMAKE_LFLAGS macro in the .pro file of your project:

QMAKE_LFLAGS += /STACK:32000000

After running qmake, you will find a new option “/STACK:32000000″ is added to the LFLAGS variable in Makefile.Debug and Makefile.Release of your project. LFLAGS contains the linking flags when linking your program. The “/STACK” option will instruct the linker to change the “size of stack reserve” field in the generated exe file, just as editbin does. This linker option works for MSVC compiling kit. If you use Mingw kit, this post says you should write:

QMAKE_LFLAGS_WINDOWS += -Wl,--stack,32000000

But the QMAKE_LFLAGS_WINDOWS macro has no effect at all(no flag added to the Makefile, but the building was successful and the stack limit is set to the default one 0x200000,i.e.,2M bytes determined by Mingw). In fact, you should use

QMAKE_LFLAGS += -Wl,--stack,64000000

“-Wl” is the way to pass flags to linker in a Linux way though the “–stack” flag is not supported in Linux as talked below.

For Linux programs, there is no information field in the binary to the store the stack limit, which means you cannot pass an option to gcc to set the limit of stack size for the program. The maximum memory available for stack is determined  by system and set by the ulimit command.

ulimit -s 64000

The above command will change the stack size limit to 64000KB. Note that ulimit only sets an environment variable for the stack limit so only current bash and its child processes can use this altered stack size limit. You can also edit the file /etc/security/limits.conf to make the modification permanent so every time you login, your processes will use the new limit for stack.

Some guy says you can use

QMAKE_CXXFLAGS += -Wl,--stack,100000000

in the project file to change the limit, which is wrong. As I said, there is no flag called “–stack” for gcc linker on Linux. The confusion thing is that with the code above, you can run qmake and build your program without problem in Linux. This is because the QMAKE_CXXFLAGS will set the CXXFLAGS in Makefile generated by qmake, while the CXXFLAGS will be passed to gcc at the compiling stage “gcc -c …”. The -Wl option is totally ignored at the compiling stage by gcc. -Wl option is only used at the linking stage. So the QMAKE_CXXFLAGS has no¬† effect of setting the stack limit. If you use the QMAKE_LFAGS as follows.

QMAKE_LFAGS += -Wl,--stack,100000000

The flag “-Wl, –stack, 10000000″ will be added to the LFLAGS in Makefile and passed to gcc at linking stage: “gcc -o xxx -Wl,–stack,1000000….”. Gcc will complain “–stack” is an unrecognized option. The linker fag is only valid for MingW version of GCC. Here is a post saying you can use the tools like objdump, nm, readelf, etc. to check the the stack size limit information in the exe file. Unfortunately, I cannot find the said symbols in Linux. Actually, it refers to Mingw generated executables.

nm myapp.exe|findstr stack

0000000000001000 A __size_of_stack_commit__
0000000003d09000 A __size_of_stack_reserve__

So this mingw32 program reserves 3d09000(64,000,000) bytes of stack. Note that nm is a command shipped by mingw(c:\Qt\Qt5.12.1\Tools\mingw730_64\bin\nm.exe). Findstr is a command provided by Windows which functions like grep in Unix.

Here is a post providing default stack sizes on various platforms.

 

If you like my content, please consider buying me a coffee. Buy me a coffeeBuy me a coffee Thank you for your support!
Posted in

Leave a Reply