OK, I couldn't resist. I've attached an inner-function test program which weakly confirms my theory. If you run it with no arguments, the inner function works. If you run it with arguments, this causes the stack to be reused and that seems to include the "thunk" I mentioned. The result is a jump into nowhere, followed by SIGSEGV or SIGILL (oddly I've seen both). If it fails in the outer-function-return case, I'll bet it fails with ucontext trickery too. http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html http://stackoverflow.com/questions/2929281/are-nested-functions-a-bad-thing-in-gcc
#include <stdio.h> typedef void print_fn (void); print_fn *my_print_fn; void outer (void) { int outer_val = 0x5678; void inner (void) { printf("in inner function, result = 0x%x\n",outer_val); } printf("in outer function\n"); inner(); my_print_fn = &inner; } void rewrite_stack (void) { char junk[1024] = {0,}; printf("rewriting stack\n"); } int main (int argc, char **argv) { outer(); if (argc > 1) { rewrite_stack(); } (*my_print_fn)(); return 0; }