views:

59

answers:

3

Hi, When I throw in a method A, it causes buffer overrun but when I return, it runs fine. I thought throw moves execution to the caller method so the address it goes to should be the same as return address, but i am obviuosly wrong. Is there a way to see what address throw goes to in Visual Studio debugger?

Thank you

Berkus: does this mean that stack of upper caller method is corrupted? So for example,

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

Then, it is possible that Method C's return address is ok but Method B's return address is corrupted, causing buffer overrun? What I am seeing is that if there is no throw, my application runs fine, so I think Method A,B and C all have valid return addresses.

+2  A: 

Throw will unwind the stack, until it reaches the function with catch in it. The return address does not matter, as throw can go up several levels of stack frames if necessary.

Berkus
A: 

In C++, if you have no try/catch block then this:

Method A calls 
   Method B calls 
      Method C. Method C throws an exception 

will terminate the application. You must have a try/catch block in your code if want to avoid termination.

anon
I should have been more clear. There is a try block enclosing call to Method B and catch following the try block. The problem is with buffer overrun and how it affect exception handling links.
@user How do you know you have a buffer overrun? And please post some real C++ code in your question.
anon
A: 

Exactly how return addresses and thrown exceptions interact is left to the details of how your particular compiler implements exception handling. To say anything about it with much certainty, someone here would have to be familiar with those internal details.

It's certainly conceivable that a buffer overrun could corrupt data that is only used by the exception handling (thus causing a throw to fail) while leaving the return address intact (thus allowing a normal return to succeed). But again, that depends on how your compiler is making use of the stack. (On a different compiler you might get totally different symptoms). It's also possible that the corruption has caused other problems that you simply haven't noticed yet. Or that such corruption will cause problems in the future after the next time you change your code. If the stack (or other memory that C++ depends on) becomes corrupted, then just about anything could happen.

Wither some educated guess-work or knowledge of the compiler details, I'm sure someone could eventually answer the specific questions about return addresses and how throwing works. However, I really think these are the wrong questions to be asking.

If you actually know you have a buffer overrun, then there's no point in trying to answer these questions. Just fix the overrun.

If you only suspect you have an overrun or are trying to track down how it's happening, then try stepping through your code in the debugger and watch for changes to memory outside the bounds of your variables. Or perhaps, alter your function to always throw and then start commenting out suspicious parts of your process one by one. Once the throw starts working again, you can then take a closer look at the code you last commented since the problem is most likely there. If these suggestions don't help, then I think the real question to ask here is "How do I track down memory corruption that only affects throwing an exception?".

TheUndeadFish