Click here to Skip to main content
15,885,998 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have complex mutual and direct recursive code, that cannot be rolled out into loops. It is part of a code interpreter.
The parameter for the main function is a string - which as I understand stack use in .net, is on the heap.
When I run a dummy recursive routine, I can get 1000+ nested calls without crashing.
When I add the actual body (1000+ lines), it can merely recurse about 35 times.

Default App pool: v4.0

What I have tried:

I moved all local variables in the function into a class, and access them now by creating a "local object" containing all the int/double/strings

I can simulate this with the dummy function, by adding lots of local variables. Its recurse limit comes down. Then I move them into an object, and it goes max again.

But the mutual recursion does not even budge if I move the locals into an object.

Any ideas? Pointers?
Posted
Updated 11-May-21 23:04pm
v2

You can enlarge the stack space, but I suspect that's just a "stopgap" solution - if you aren't limiting the recursion, then you will - eventually - exhaust that as well.

Pointers are unlikely to help: a pointer is the same size as a reference, so that won't improve matters.

35 times in production sounds unlikely - unless two things are happening together:
1) You are passing value types as parameters
2) You are running as a web based app, where the stack space is significantly smaller than a desktop app would be (it defaults to 1MB, which is only 128K references / return addresses but that can be changed: Advanced configuration | Microsoft Docs[^])

I'd suspect from what you say you have done that it's data related: I'd be adding logging to find out exactly what happens with the "real data" that doesn't with the "dummy data" - does it contain a "data loop" that you weren't aware of?
 
Share this answer
 
Comments
Harry Marx 12-May-21 3:26am    
Good suggestion... the log does not show any issue with recursion - it does only call as expected.
But you mention loops... does: for each s as string in split(...)
eats up stack space? I wonder...
OriginalGriff 12-May-21 4:14am    
No, code loops (for, foreach, while, do) won't increase stack usage - they only create local variables which occupy a fixed amount of stack allocated when the method is entered.

IF you are eating stack space without showing excessive recursion, then you need to look deeper - is there indirect recursion happening with methods your method calls that isn't showing up on your logs? Are you passing large value types ae parameters (structs are copied in their entirety when passed remember, unlike classes where only a copy of the reference is copied). Big structs can use significant amounts of space!

Sorry to sound vague, but without seeing your code ...

You can "cheat" and find out how much stack has been used by monitoring the address of a local variable:
       static void Main(string[] args)
            {
            unsafe
                {
                Console.WriteLine(new IntPtr(GetStackLevel()));
                }
            foo();
            bar();
            }
        static void foo()
            {
            unsafe
                {
                Console.WriteLine(new IntPtr(GetStackLevel()));
                }
            }
        static void bar()
            {
            foo();
            unsafe
                {
                Console.WriteLine(new IntPtr(GetStackLevel()));
                }
            }
        unsafe static char* GetStackLevel()
            {
            char a;
            return &a;
            }
        }
Remember you'll need the build option "allow unsafe code" enabled!
That could help you get an idea how much stack is being used at any one point.
Harry Marx 12-May-21 6:27am    
Note Im using ASP... not C#. Anyway, what I also noted was the mere inclusion/commenting out of unused code affects the number of recursive calls I can make.
My conclusion is that the available stack is less if you have more code....
OriginalGriff 12-May-21 6:56am    
ASP.NET is a web delivery mechanism that runs either C# or VB in the codebehind.
It's not a language, but a framework which can use a number of languages within a "web site paradigm".

If you are using VB, then obviously I'm sorry for your loss, but it makes no difference since they are interchangeable once compiled to IL. :laugh:

VB can't use unsafe code or pointers at all - but it can call C# assemblies that do. So create a new C# Class library that uses unsafe code / pointers and that returns the stack pointer as a string: then you can call it from VB as if it was written in that language.
Maybe you can use one of these debugging-tools[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900