jmp_2flow.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. # http://blog.csdn.net/win_lin/article/details/40948277
  3. # for all supports setjmp and longjmp:
  4. g++ -g -O0 -o jmp_2flow jmp_2flow.cpp
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <setjmp.h>
  9. jmp_buf context_thread_0;
  10. jmp_buf context_thread_1;
  11. void thread0_functions()
  12. {
  13. int ret = setjmp(context_thread_0);
  14. // when ret is 0, create thread,
  15. // when ret is not 0, longjmp to this thread.
  16. if (ret == 0) {
  17. return;
  18. }
  19. int age = 10000;
  20. const char* name = "winlin";
  21. printf("[thread0] age=%d, name=%s\n", age, name);
  22. if (!setjmp(context_thread_0)) {
  23. printf("[thread0] switch to thread1\n");
  24. longjmp(context_thread_1, 1);
  25. }
  26. // crash, for the stack is modified by thread1.
  27. // name = 0x2b67004009c8 <error: Cannot access memory at address 0x2b67004009c8>
  28. printf("[thread0] terminated, age=%d, name=%s\n", age, name);
  29. exit(0);
  30. }
  31. void thread1_functions()
  32. {
  33. int ret = setjmp(context_thread_1);
  34. // when ret is 0, create thread,
  35. // when ret is not 0, longjmp to this thread.
  36. if (ret == 0) {
  37. return;
  38. }
  39. int age = 11111;
  40. printf("[thread1] age=%d\n", age);
  41. if (!setjmp(context_thread_1)) {
  42. printf("[thread1] switch to thread0\n");
  43. longjmp(context_thread_0, 1);
  44. }
  45. printf("[thread1] terminated, age=%d\n", age);
  46. exit(0);
  47. }
  48. int main(int argc, char** argv)
  49. {
  50. thread0_functions();
  51. thread1_functions();
  52. // kickstart
  53. longjmp(context_thread_0, 1);
  54. return 0;
  55. }