Erangi

Hi all,

We're looking into creating a 64-bit version our application. The app uses a third party DLL that has a 64-bit version. One of the functions in the DLL uses recursion, and given a certain input it can get very deep. Playing around with it, I've noticed the stack size used on the deep recursion condition is twice the size in the 64-bit version, comparing to the 32-bit one.

I've written a small test program with an empty function that does nothing other than call itself a given number of times. Turned out the 32-bit version was able to recur more than twice before reaching a stack overflow. Measuring the stack usage before crashing confirmed this observation.

This is not a common situation, but it has in fact happened to me that a 64-bit version crashed were 32-bit ran just fine. The default stack size in VC8 is 1MB. Given that 64-bit versions use a lot more stack space, wouldn't it make sense to enlarge that default



Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

Bruno van Dooren

It would -because addresses and pointers are now 64 bit instead of 32-, though lack of stack space is usually only a problem with deep recursion.

If you design an algorithm like that, you always have to

a) be sure that you compile with enough stack space, or create threads with enough stack space for your algorithm

b) surround your recursive algorithm with __try __except so that you can safely catch the exception that indicates 'out of stack space' if that should happen

Increasing the default would mean that all threads would run with that default, which would be a bit overkill to solve a problem that is only a problem if you did not think about it in your design phase.

I know some people will disagree with me, but I think that recursion should be avoided in production level software.

In all but the simplest cases, it becomes very hard to maintain, very hard to prove that all possibilities lead to a known result, and very hard to transfer ownership to someone else.

On top of that, anything you can do recursively you can do in a loop, using something like std:Tongue Tiedtack to store the state variables. Loops are much easier to debug, maintain and prove for correctness, and you don't have to worry about the stack space problem.





Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

Erangi

Thanks, Bruno.

The problem in my case is that the recursion is in a third party dll. I can't change the algorithm, and the dll manufacturer cannot change the stack size of the executable or the threads that are used (the dll uses only calling threads).

If I take your suggestion and protect my calls into the dll with __try and __except, will calling _resetstkoflw() leave me in a stable state (including enough stack space to continue working) I assume any dynamic allocations inside the dll will leak, but this is something I'll have to talk with the manufacturer about.





Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

Bruno van Dooren

If you catch the exception and it is the correct one (out of stack space) you can continue as if nothing has happened, as long as you allow for the fact that the recursion id not run to completion.

Anything that happened while recursing will be as it was when the exception got triggered. i.e. heap mem will leak, handles will be open etc. How serious this is depends on what your algorithm is doing.

Does the DLL start it's own threads

If you are in control of the stack size, you can compile your app with a bigger default stack size or -if the algorithm runs in a thread that was created by you- you can create the thread with a larger stack. That should solve your problem I think.





Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

crescens2k

Truthfully, you should get the manufacturer to make the library 64bit friendly. But as far as I understand it, the actual thing which controls the stack size should be your executable. Have you tried setting your executable to up your stack size on the 64bit build




Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

Erangi

In order to make sure this was really the problem, I had created an executable with a larger stack size. In fact, this had solved the problem. I could make do with that solution, but there seems to be a common problem here: regarding the specific dll, all programmers who use it should be aware of this problem (I hope the manufacturer will indeed add a note to the documentation). And generally, any programmer who uses a lot of stack space should be aware of this problem - given that the default will indeed remain as it is now.

By the way, my application is actually a COM server, and I do not create any the threads directly. Would you happen to know if the threads created by COM use the default executable stack size





Re: Visual C++ General 64-bit apps need larger stacks than 32-bit

Bruno van Dooren

Erangi wrote:

In order to make sure this was really the problem, I had created an executable with a larger stack size. In fact, this had solved the problem. I could make do with that solution, but there seems to be a common problem here: regarding the specific dll, all programmers who use it should be aware of this problem (I hope the manufacturer will indeed add a note to the documentation). And generally, any programmer who uses a lot of stack space should be aware of this problem - given that the default will indeed remain as it is now.

All programmers who use it should be aware of it. If they know that a function is recursive, they should use __try __except as a safety net.

There is nothing the manufacturer can do about the problem because it is not his DLL that creates the stacks.

But he should document the required stack size, and the effects of having a stack overflow exception: which objects get leaked, how much memory leaks, side effects,...

Erangi wrote:

By the way, my application is actually a COM server, and I do not create any the threads directly. Would you happen to know if the threads created by COM use the default executable stack size

Is your COM server an exe file if yes, then it behaves like any other executable. i.e. any threads created inside that exe have the default stack size.

If your COM server is a DLL, then any threads get started in the context of the calling exe and get the stack size that is specified by the calling appliation.