main.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "main.h"
  2. #include "Debug.h"
  3. #include "error_signals.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. int main( int argc, char *argv[] )
  7. {
  8. // Start of error handling.
  9. // This is error handling to display the stack trace of a GPF error.
  10. // This code has to be done at the beginning of each thread.
  11. error_signals::AddHandlers();
  12. pid_t tid = error_signals::GetThreadID();
  13. error_signals *error_thread = error_signals::GetThread(tid);
  14. if (error_thread == nullptr)
  15. {
  16. error_thread = error_signals::AddThread(tid);
  17. }
  18. volatile int val = 0;
  19. if (error_thread != nullptr)
  20. {
  21. error_thread->LineNumberStack = 0;
  22. val = setjmp(error_thread->position);
  23. }
  24. if (val != 0)
  25. {
  26. // This code runs if there's an error.
  27. error_thread->DisplayErrorMessage(val); // Display a stack trace like C#.
  28. error_signals::RemoveHandlers();
  29. return val;
  30. }
  31. // End of error handling.
  32. DEBUG_FUNCTION
  33. Function1();
  34. DEBUG_LINE
  35. error_thread->ReleaseThread(tid); // Error thread cleanup.
  36. return 0;
  37. }
  38. int Function1()
  39. {
  40. DEBUG_FUNCTION
  41. printf("This is Function1. It calls function2.\n");
  42. DEBUG_LINE
  43. Function2();
  44. }
  45. int Function2()
  46. {
  47. DEBUG_FUNCTION
  48. printf("This is function2. It calls function3.\n");
  49. DEBUG_LINE
  50. Function3();
  51. }
  52. int Function3()
  53. {
  54. DEBUG_FUNCTION
  55. const int BufferSize = 1000;
  56. char input[BufferSize];
  57. int value;
  58. int inverse;
  59. const int Divisor = 100;
  60. DEBUG_LINE
  61. printf("This is function3.\n");
  62. printf("This is a simple program to demonstrate catching a program crash and displaying where the error happened.\n");
  63. printf("When a program crashes, there's nothing that can be done. It's gonna crash.\n");
  64. printf("But it is possible to catch the error as a signal and display the error location/stack trace.");
  65. printf("Enter a number and I'll output %d divided by that number.\n",Divisor);
  66. printf("Press ENTER to quit. Enter 0 to cause a program crash.\n");
  67. printf("Pressing CTRL Z or CTRL C also cause it to crash.\n");
  68. printf("You can also kill it from another terminal on the same computer with\nkillall \"ShowErrorsInC++\"\n");
  69. printf("Negative numbers throw an error that is then caught with try/catch.\n");
  70. DEBUG_LINE
  71. while(true) {
  72. DEBUG_LINE
  73. try
  74. {
  75. DEBUG_LINE
  76. printf("Enter a number: ");
  77. DEBUG_LINE
  78. *input = 0;
  79. DEBUG_LINE
  80. fgets(input,BufferSize,stdin);
  81. DEBUG_LINE
  82. if (input[0] <= 13) {
  83. printf("Have a nice day.\n");
  84. break;
  85. }
  86. DEBUG_LINE
  87. value = atoi(input);
  88. DEBUG_LINE
  89. if (value < 0) {
  90. throw "Negative numbers are not allowed.";
  91. }
  92. DEBUG_LINE
  93. inverse = Divisor / value;
  94. DEBUG_LINE
  95. printf("%d divided by %d = %d.\n",Divisor,value,inverse);
  96. } catch(const char *error) {
  97. printf("%s\n",error);
  98. } catch(...)
  99. {
  100. // Notice how a division by zero error isn't caught by this catch in Linux.
  101. printf("There was an error.");
  102. }
  103. }
  104. DEBUG_LINE
  105. }