error_signals.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "error_signals.h"
  2. #include <stdio.h>
  3. error_signals *error_thread_list;
  4. pid_t error_signals::GetThreadID()
  5. {
  6. pid_t tid = syscall(SYS_gettid);
  7. return tid;
  8. }
  9. error_signals *error_signals::GetThread(pid_t thread_id)
  10. {
  11. error_signals *loop = error_thread_list;
  12. while (loop != nullptr)
  13. {
  14. if ((loop->in_use) && (loop->thread_id == thread_id))
  15. {
  16. break;
  17. }
  18. loop = loop->next;
  19. }
  20. return loop;
  21. }
  22. void error_signals::DeleteThreads()
  23. {
  24. error_signals *item;
  25. while (error_thread_list != nullptr)
  26. {
  27. item = error_thread_list;
  28. error_thread_list = item->next;
  29. delete item;
  30. }
  31. return;
  32. }
  33. error_signals *error_signals::AddThread(pid_t thread_id)
  34. {
  35. error_signals *loop = error_thread_list;
  36. while (loop != nullptr)
  37. {
  38. if ((!loop->in_use) || (loop->thread_id == thread_id))
  39. {
  40. break;
  41. }
  42. loop = loop->next;
  43. }
  44. if (loop == nullptr)
  45. {
  46. loop = new error_signals;
  47. if (loop != nullptr)
  48. {
  49. loop->in_use = true;
  50. loop->thread_id = thread_id;
  51. loop->next = error_thread_list;
  52. error_thread_list = loop;
  53. }
  54. }
  55. return loop;
  56. }
  57. void error_signals::ReleaseThread(pid_t thread_id)
  58. {
  59. error_signals *loop = error_thread_list;
  60. while (loop != nullptr)
  61. {
  62. if (loop->thread_id == thread_id)
  63. {
  64. loop->in_use = false;
  65. break;
  66. }
  67. loop = loop->next;
  68. }
  69. return;
  70. }
  71. void error_signals::Handler(int signum)
  72. {
  73. pid_t tid = error_signals::GetThreadID();
  74. error_signals *error_thread = error_signals::GetThread(tid);
  75. if (error_thread != nullptr)
  76. {
  77. error_thread->SaveLineNumbers();
  78. longjmp(error_thread->position,signum);
  79. }
  80. return;
  81. }
  82. void error_signals::SaveLineNumbers()
  83. {
  84. // Save line numbers before the stack is trashed by longjmp.
  85. int loop;
  86. int max;
  87. int *lineNumber;
  88. max = LineNumberStack;
  89. if (max >0)
  90. {
  91. if (max > CALL_STACK_SIZE+1)
  92. {
  93. max = CALL_STACK_SIZE+1;
  94. }
  95. for(loop=0;loop<max;loop++)
  96. {
  97. lineNumber = LineNumbers[loop];
  98. if (lineNumber == nullptr) {
  99. SavedLineNumbers[loop] = 0;
  100. } else {
  101. SavedLineNumbers[loop] = *lineNumber;
  102. }
  103. }
  104. }
  105. return;
  106. }
  107. void error_signals::AddHandlers()
  108. {
  109. /*struct sigaction sa;
  110. sa.sa_handler = error_signals::Handler;
  111. sigemptyset(&sa.sa_mask);
  112. sa.sa_flags = SA_RESTART;// Restart functions if interrupted by handler
  113. if (sigaction(SIGFPE, &sa, NULL) == -1)
  114. {
  115. break;
  116. // Handle error
  117. //printf("Error calling signaction.\n");
  118. }*/
  119. // If you add additional signal handlers here, be sure to add them to error_signals::RemoveHandlers and StackTrace::DisplayErrorMessage.
  120. signal (SIGFPE, error_signals::Handler); // division by 0
  121. signal (SIGILL, error_signals::Handler); // illegal instruction
  122. signal (SIGSEGV, error_signals::Handler); // bad memory read/write
  123. signal (SIGBUS, error_signals::Handler); // access misalligned memory or non-existent memory
  124. signal (SIGTERM, error_signals::Handler); // Terminate signal from linux kill -SIGTERM <pid>
  125. signal (SIGTSTP, error_signals::Handler); // Terminate signal from keyboard CTRL Z.
  126. signal (SIGINT, error_signals::Handler); // Terminate signal from keyboard CTRL C.
  127. return;
  128. }
  129. void error_signals::RemoveHandlers()
  130. {
  131. // Make sure the signals don't point to some function that might not exist in the future. (dll unloads).
  132. signal (SIGFPE, SIG_DFL); // division by 0
  133. signal (SIGILL, SIG_DFL); // illegal instruction
  134. signal (SIGSEGV, SIG_DFL); // bad memory read/write
  135. signal (SIGBUS, SIG_DFL); // access misalligned memory or non-existent memory
  136. signal (SIGTERM, SIG_DFL); // Terminate signal from linux kill -SIGTERM <pid>
  137. signal (SIGTSTP, SIG_DFL); // Terminate signal from keyboard CTRL Z.
  138. signal (SIGINT, SIG_DFL); // Terminate signal from keyboard CTRL C.
  139. return;
  140. }
  141. StackTrace *error_signals:: GetStackTrace()
  142. {
  143. SaveLineNumbers();
  144. return this;
  145. }
  146. //webpage_list[] = { "foo", "bar",0 };