views:

663

answers:

1

We have discovered that one of our auto generated assemblies is throwing a StackOverflowException on new(). This class has (bear with me please) 400+ simple properties that are initialised (most by default(string) etc) in a constructor.

We notice that its fine on 64 bits but on 32 bits it goes bang!

We need to test if it's reasonable for our use case to create a larger default stack to give us breathing room while we reengineer the code generator.

We would esp. interested in solutions that involve app.config if possible. But I'm a realist so anything would be good.

Re reasons for the the stack over flow. We've narrowed the error down the constructor in question. My first impressions were also of the type of infinite recursion. However we've reproduced the error using a 3 line console app that :

  • creates an empty instance of class.
  • calls a non static method (Clone) on the class who first job is to create and empty instance ready pass the properties into.

It goes bang as it hits the second constructor.

now debugging through with the .net source code we see that the the stack overflow is in the Guid.NewGuid() which is passed as the second parameter to the constructor. The actual line of code is the call to the native CoCreateGuid() call.

So while it could be a bug in CoCreateGuid(), we want to eliminate our code from the problem. My first thought is to increase the size of the stack massively and see if this error reoccurs. Then, since I think we can control all use cases, is replace the constructor with object initialisation - think this can relieve the pressure on the stack.

Nb. We can stop the error from happening by removing just on int property from the class.

+2  A: 

You can use editbin to change the stack size for the executable. You can't do this in app.config as far as I'm aware.

Another option (also mentioned on that page) is to create a new thread with the "right" stack size. The page mentions the pros and cons of this approach.

I'd be surprised if just setting 400 properties in a constructor was the cause of the problem though... that's going to be one big stack frame - but unless you've got several big stack frames on the stack, I would expect it to be okay. The other possibility is that you've got endless recursion somewhere :)

EDIT: An alternative suggestion...

Presumably you have a lot of local variables in this constructor? (Otherwise it shouldn't take up any more stack than any other call.) Is it possible to split the constructor into multiple methods, setting (say) 20 fields per method? That will be tricky if the fields are read-only, admittedly.

If you could give us an idea of what the constructor looks like, that would help a lot. You might also want to use ildasm to see what it claims the stack size will be for that constructor.

Just to check, this is a class rather than a struct, right?

Jon Skeet
Thank you for the quick answer. I've answered your queries in the question
Preet Sangha
Thanks for the additional info. Deffo a class, not a struct. I am going to investigate the multiple initialisation methods this morning.
Preet Sangha
thank you jon. editbin is working for us for now - while we reengineer the the generation.
Preet Sangha