tags:

views:

995

answers:

6

What is stack unwinding? Searched through but couldn't find enlightening answer! Thanks in advance.

+1  A: 

I don't know if you read this yet, but Wikipedia's article on the call stack has a decent explanation.

John Weldon
Just read! Thanks.
Rajendra Kumar Uppal
+3  A: 

Stack unwinding is a mostly C++ concept, dealing with how stack-allocated objects are destroyed when its scope is exited (either normally, or through an exception).

Say you have this fragment of code:

void hw() {
    string hello("Hello, ");
    string world("world!\n");
    cout << hello << world;
} // at this point, "world" is destroyed, followed by "hello"
Chris Jester-Young
Does this apply to any block? I mean if there is only {// some local objects}
Rajendra Kumar Uppal
@Rajendra: Yes, an anonymous block defines an area of scope, so it counts too.
Michael Myers
+10  A: 

In a general sense, a stack "unwind" is pretty much synonymous with the end of a function call and the subsequent popping of the stack.

However, specifically in the case of C++, stack unwinding has to do with how C++ calls the destructors for the objects allocated since the started of any code block. Objects that were created within the block are deallocated in reverse order of their allocation.

jrista
There is nothing special about `try` blocks. Stack objects allocated in _any_ block (whether `try` or not) is subject to unwinding when the block exits.
Chris Jester-Young
Oh, my bad. Any block. :P
jrista
Thanks for fixing. +1
Chris Jester-Young
Its been a while since I have done much C++ coding. I had to dig that answer out of the rusty depths. ;P
jrista
@jrista: don't worry. Everyone has "their bad" occasionally.
bitc
+7  A: 
Nikolai N Fetissov
That was really enlightening! So I get this: if my process is crashed unexpectedly during leaving ANY block at which time stack was being popped then it might happen that the code after exception handler code, is not going to be executed at all, and it may cause memory leaks, heap corruption etc.
Rajendra Kumar Uppal
Hmm, crash is a little bit different, though related, animal (signals, core dumps, etc.) What I'm talking about are C++ tools/facilities to safely manage resources in the presence of exceptions/errors, that *might* lead to a crash if not handled.
Nikolai N Fetissov
If the program "crashes" (i.e. *terminates* due to an error), then any memory leakage or heap corruption is irrelevant since the memory is released at termination.
Tyler McHenry
Exactly. Thanks. I'm just being a bit dyslexic today.
Nikolai N Fetissov
if ( x )Where x is defined?
Lalit
@Lalit: 'x' was meant to be "some condition".
Nikolai N Fetissov
+2  A: 

All this relates to C++:

Definition: As you create objects statically (on the stack as opposed to allocating them in the heap memory) and perform function calls, they are "stacked up".

When a scope (anything delimited by { and }) is exited (by using return XXX;, reaching the end of the scope or throwing an exception) everything within that scope is destroyed (destructors are called for everything). This process of destroying local objects and calling destructors is called stack unwinding. (Exiting a code block using goto will not unwind the stack which is one of the reasons you should never use goto in C++).

You have the following issues related to stack unwinding:

  1. avoiding memory leaks (anything dynamically allocated that is not managed by a local object and cleaned up in the destructor will be leaked) - see RAII referred to by Nikolai, and the documentation for boost::scoped_ptr or this example of using boost::mutex::scoped_lock.

  2. program consistency: the C++ specifications state that you should never throw an exception before any existing exception has been handled. This means that the stack unwinding process should never throw an exception (either use only code guaranteed not to throw in destructors, or surround everything in destructors with try { and } catch(...) {}).

If any destructor throws an exception during stack unwinding you end up in the land of undefined behavior which could cause your program to treminate unexpectedly (most common behavior) or the universe to end (theoretically possible but has not been observed in practice yet).

utnapistim
On the contrary. While gotos should not be abused, they do cause stack unwinding in MSVC (not in GCC, so it's probably an extension). setjmp and longjmp do this in a cross platform way, with somewhat less flexibility.
Patrick Niedzielski
A: 

When an exception is thrown and control passes from a try block to a handler, the C++ run time calls destructors for all automatic objects constructed since the beginning of the try block. This process is called stack unwinding. The automatic objects are destroyed in reverse order of their construction. (Automatic objects are local objects that have been declared auto or register, or not declared static or extern. An automatic object x is deleted whenever the program exits the block in which x is declared.)

If an exception is thrown during construction of an object consisting of subobjects or array elements, destructors are only called for those subobjects or array elements successfully constructed before the exception was thrown. A destructor for a local static object will only be called if the object was successfully constructed.

MK