Created
December 7, 2012 23:16
-
-
Save xxuejie/4237412 to your computer and use it in GitHub Desktop.
c++ exception also does not restore local variables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ clang++ setjmp-cpp-test.cc | |
$ ./a.out | |
setjmp normal execution path, level: 0, prev_jmp: -1 | |
setjmp normal execution path, level: 1, prev_jmp: 0 | |
level is 2, perform longjmp! | |
setjmp exception execution path, level: 1, prev_jmp: 0 | |
prev_jmp is not empty, continue with longjmp! | |
setjmp exception execution path, level: 0, prev_jmp: -1 | |
Exiting setjmp function, level: 0, prev_jmp: -1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ em++ -s EXCEPTION_DEBUG=0 setjmp-cpp-test.cc | |
$ node a.out.js | |
setjmp normal execution path, level: 0, prev_jmp: -1 | |
setjmp normal execution path, level: 1, prev_jmp: 0 | |
level is 2, perform longjmp! | |
setjmp exception execution path, level: 1, prev_jmp: 0 | |
prev_jmp is not empty, continue with longjmp! | |
/Users/rafael/develop/tmp/a.out.js:2585 | |
throw HEAP32[((_llvm_eh_exception.buf)>>2)]; | |
^ | |
0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
static int current_exception_id = 0; | |
typedef struct { | |
int jmp; | |
} jmp_state; | |
void setjmp_func(jmp_state* s, int level) { | |
int prev_jmp = s->jmp; | |
int c_jmp; | |
if (level == 2) { | |
printf("level is 2, perform longjmp!\n"); | |
throw 1; | |
} | |
c_jmp = current_exception_id++; | |
try { | |
printf("setjmp normal execution path, level: %d, prev_jmp: %d\n", level, prev_jmp); | |
s->jmp = c_jmp; | |
setjmp_func(s, level + 1); | |
} catch (int catched_eid) { | |
if (catched_eid == c_jmp) { | |
printf("setjmp exception execution path, level: %d, prev_jmp: %d\n", level, prev_jmp); | |
if (prev_jmp != -1) { | |
printf("prev_jmp is not empty, continue with longjmp!\n"); | |
s->jmp = prev_jmp; | |
throw s->jmp; | |
} | |
} else { | |
throw; | |
} | |
} | |
printf("Exiting setjmp function, level: %d, prev_jmp: %d\n", level, prev_jmp); | |
} | |
int main(int argc, char *argv[]) { | |
jmp_state s; | |
s.jmp = -1; | |
setjmp_func(&s, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment