0

Possible Duplicate:
How do I prevent and/or handle a StackOverflowException? (C#)
C# catch a stack overflow exception

I have a fairly complex application written in C# (using .NET 2.0). The program processes a large number of files in a heavily recursive way and at some clients it runs into a stack overflow exception. The program is very complex and we haven't been able to even reproduce the problem - not even at our clients where it happened.

The obvious solution is to fix the code that causes the stack overflow but that doesn't seem very likely - our code base is well over 2 million lines of code that creates a large recursive data structure in memory. It's not likely that we'll just stumble upon the problem part. (Not in the short term, anyway.)

However, our program also backs up files and makes changes to the ones being processed and in case of exceptions, it restores everything into the original state. When a stack overflow exception happens, the process just terminates and this restore functionality doesn't have a chance to run because stack overflow cannot be caught.

So my question is: is there a way to catch a stack overflow exception in .NET 2.0. I can't host the CLR and the exception is a true stack overflow, not thrown by our code. Being able to do this would at least give me the ability to revert changes made before the program terminates.

Edit: Please note, I'm well aware of what a stack overflow exception is and how serious it is. I'm not looking for advice in finding one - this situation happens rarely. What I'm trying to do is restore client data in an environment with limited disk space when it happens. If my program dies after the restore operation, I'm ok with that.

Community
  • 1
  • 1
xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • Can you post an example of the code that you are currently using in question..perhaps there is just a simple logic error or Memory Leak issue you are experiencing – MethodMan Oct 01 '12 at 21:05
  • What would you plan on doing once you have caught a SO exception? How would you recover from it? – Ed S. Oct 01 '12 at 21:06
  • @DJKRAZEno, there's no specific code. We're talking about a large application with 250+ components. I'm not looking to find the stack overflow - I'm looking for a way to catch it and react to it. – xxbbcc Oct 01 '12 at 21:07
  • @DanJ It's most definitely _not_ a duplicate. I did research and found no solution. – xxbbcc Oct 01 '12 at 21:07
  • 1
    It sounds like you are in desperate need of logging. I'm guessing you have some try-catch block which is absorbing the error preventing you from finding it. If you have a stack overflow exception you can't really ignore it or correct it mid code, stack overflow generally means you used up so much space that you can't do anything, it's a bug you HAVE to fix rather than work around. – Benjamin Danger Johnson Oct 01 '12 at 21:09
  • @BenjaminDangerJohnson I know what a stack overflow is. We also have very detailed logs but as I said, our process is deeply recursive. The logs we have sometimes log the same activity 10,000+ times before we run into a stack overflow. It's not possible to track the issue that way. What I need is the ability to catch the exception somehow, revert changes and then terminate. – xxbbcc Oct 01 '12 at 21:12
  • @xxbbcc that question was answered with a "no" - do you expect a different answer by asking the same question again? – D Stanley Oct 01 '12 at 21:12
  • instead of recursion, have you thought about using a for loop? Less memory is consumed since your program doesn't need to save methods on the stack. Depending on how your recursion works this can fix errors. The Fibonacci example comes to mind. – Benjamin Danger Johnson Oct 01 '12 at 21:13
  • 1
    The second answer to this SO question may be helpful: http://stackoverflow.com/questions/107735/stackoverflowexception-in-net – hatchet - done with SOverflow Oct 01 '12 at 21:14
  • @DStanley I'm looking for any solution that may work out. I'm aware of the CLR rules concerning stack overflows - I'm looking for ideas to work around them. – xxbbcc Oct 01 '12 at 21:15
  • I highly suggest humoring a for loop rather than a recursive method if possible – Benjamin Danger Johnson Oct 01 '12 at 21:16
  • @BenjaminDangerJohnson I agree with you but the nature of our processing involves walking highly interconnected graphs and it simply requires recursion. – xxbbcc Oct 01 '12 at 21:16
  • @hatchet Thanks, this looks useful. If you put it in as an answer and it works out, I'll vote for you. – xxbbcc Oct 01 '12 at 21:20
  • @EdS. If I can catch an SO, I'd restore client data and then let the program die. – xxbbcc Oct 01 '12 at 21:21
  • 1
    Better would be upvoting the original answer, maybe add a comment to that answer confirming it worked, and close this question as a duplicate of that question. – hatchet - done with SOverflow Oct 01 '12 at 21:21
  • can you give us a basic example of your code then? Just drop all the processing that happens in the function and give us the methods that are called and show the recursive calls. Maybe we can sort them out a bit to reduce some function calls. – Benjamin Danger Johnson Oct 01 '12 at 21:22
  • @BenjaminDangerJohnson Lol, if I could do that, I would've fixed the SO long time ago. That's exactly the reason I'm not trying to fix it. Something in client data triggers this problem but it only happens very rarely. I would actually ignore it but _when_ it happens, it looks terribly bad because client data files are left corrupted. We can manually restore them (we have backups) but it looks bad. – xxbbcc Oct 01 '12 at 21:28
  • You could write a wrapper application that would back up the files, call the real application, and if it failed (based on exit code, the output files themselves, whatever), restore the files from backup. Not the most elegant, but it'd work. – David Yaw Oct 01 '12 at 21:38

2 Answers2

0

It sounds like you're saying, I have a process that modifies files and it should restore the files if an error occurs but it is not doing that.

If that is the same, why not use temporary files, and if the operation completes write over the sources files with the temporary files. If any uncaught exception occurs, you have untouched (write-wise) original files.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • The reason we don't do that is because sometimes the files we have to deal with are large and backing them all up would likely use up all disk space. (Not always, just every once in a while - we're talking about different clients and different file sets.) We back up files that we modify and in case of a problem, we try to revert all changes to the files. – xxbbcc Oct 01 '12 at 21:10
  • That is interesting, because from a programming point of view, programming to fix the problem will (99.998% of the time) be more expensive then more drive space. – Erik Philips Oct 01 '12 at 21:11
  • Our process frequently runs inside virtual machines with limited disk space - this is the reason why we have to be careful. – xxbbcc Oct 01 '12 at 21:12
  • 1
    Under those circumstances I would write the application to check for disk space, if not enough use a shared mapped drive (I believe not currently in your solution), if the mapped drive does not have enough room (total) throw an exception, otherwise sleep until there is enough space (say some other VM is using the space temporarily). – Erik Philips Oct 01 '12 at 21:15
0

I do not recommend this, but you can set the stack size at compile tile using the /F Compiler Switch. The default is 1MB. Although this is not a good way to "fix" your code, it will prevent those nasty Stack Overflow messages.

Icemanind
  • 47,519
  • 50
  • 171
  • 296
  • I don't think that'd would work Our code runs into genuine stack overflows - no matter how much stack we allocate, it'd eventually run out. The right fix would be to find the cause but as I said, the code is big and very complex so for the time being, I'd like to deal with the more immediate problem first. – xxbbcc Oct 01 '12 at 21:29
  • That link to the /F compiler switch is for the C/C++ compiler. I can't find a compiler option for C#, but if it's a thread you create, you can specify it in the Thread constructor http://msdn.microsoft.com/en-us/library/5cykbwz4.aspx. – David Yaw Oct 01 '12 at 21:40
  • @DavidYaw -- you are right. That is for C++. In C#, like you said, you can set a stack size in the Thread constructor. – Icemanind Oct 01 '12 at 22:39