01-dump-extra-siginfo.patch 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. commit 1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef
  2. author: prettyboy
  3. date: 2020-05-28T12:04:46+03:00
  4. revision: 6879742
  5. Dump extra siginfo if term signal is received
  6. issue:DEVTOOLSSUPPORT-1110
  7. REVIEW: 1279268
  8. --- contrib/deprecated/python/faulthandler/faulthandler.c (b4ffd42d61e5a2398623b2c73b681b72896da86b)
  9. +++ contrib/deprecated/python/faulthandler/faulthandler.c (1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef)
  10. @@ -43,6 +43,8 @@
  11. /* defined in traceback.c */
  12. extern Py_ssize_t _Py_write_noraise(int fd, const char *buf, size_t count);
  13. +extern void dump_decimal(int fd, int value);
  14. +extern void reverse_string(char *text, const size_t len);
  15. /* cast size_t to int because write() takes an int on Windows
  16. (anyway, the length is smaller than 30 characters) */
  17. @@ -378,6 +380,81 @@ faulthandler_fatal_error(int signum)
  18. raise(signum);
  19. }
  20. +static size_t
  21. +uitoa(size_t val, char* ss) {
  22. + char* start = ss;
  23. + size_t len = 0;
  24. + do {
  25. + *ss = '0' + (val % 10);
  26. + val /= 10;
  27. + ss++; len++;
  28. + } while (val);
  29. + reverse_string(start, len);
  30. + return len;
  31. +}
  32. +
  33. +static void
  34. +read_proc_exe(pid_t pid, char* buff, size_t len) {
  35. + char pathname[32] = {0};
  36. + strcpy(pathname, "/proc/");
  37. + size_t pos = uitoa(pid, &pathname[6]) + 6;
  38. + strcpy(&pathname[pos], "/exe");
  39. +
  40. + ssize_t l = readlink(pathname, buff, len);
  41. + if (l > 0) {
  42. + // readlink() does not append a null byte to buf
  43. + buff[l] = '\0';
  44. + } else {
  45. + strncpy(buff, "unknown_program", len);
  46. + }
  47. +}
  48. +
  49. +static void
  50. +faulthandler_fatal_error_siginfo(int signum, siginfo_t* siginfo, void* ctx)
  51. +{
  52. + const int fd = fatal_error.fd;
  53. + int save_errno = errno;
  54. +
  55. + if (!fatal_error.enabled)
  56. + return;
  57. +
  58. + PUTS(fd, "\n*** Signal {si_signo=");
  59. + dump_decimal(fd, siginfo->si_signo);
  60. +
  61. + PUTS(fd, ", si_code=");
  62. + dump_decimal(fd, siginfo->si_code);
  63. + switch (siginfo->si_code) {
  64. + case SEGV_ACCERR: PUTS(fd, " SEGV_ACCERR"); break;
  65. + case SEGV_MAPERR: PUTS(fd, " SEGV_MAPERR"); break;
  66. + case SI_KERNEL: PUTS(fd, " SI_KERNEL"); break;
  67. + case SI_TIMER: PUTS(fd, " SI_TIMER"); break;
  68. + case SI_TKILL: PUTS(fd, " SI_TKILL"); break;
  69. + case SI_USER: PUTS(fd, " SI_USER"); break;
  70. + }
  71. +
  72. + if (siginfo->si_pid > 0) {
  73. + PUTS(fd, ", si_pid=");
  74. + dump_decimal(fd, siginfo->si_pid);
  75. + PUTS(fd, " ");
  76. + char buffer[PATH_MAX] = {0};
  77. + read_proc_exe(siginfo->si_pid, &buffer[0], PATH_MAX - 1);
  78. + PUTS(fd, &buffer[0]);
  79. + }
  80. +
  81. + PUTS(fd, ", si_uid=");
  82. + dump_decimal(fd, siginfo->si_uid);
  83. +
  84. + PUTS(fd, "} received by proc {pid=");
  85. + dump_decimal(fd, getpid());
  86. + PUTS(fd, ", uid=");
  87. + dump_decimal(fd, getuid());
  88. + PUTS(fd, "} ***\n");
  89. +
  90. + faulthandler_fatal_error(signum);
  91. +
  92. + errno = save_errno;
  93. +}
  94. +
  95. #ifdef MS_WINDOWS
  96. extern void _Py_dump_hexadecimal(int fd, unsigned long value, size_t bytes);
  97. @@ -489,11 +566,17 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
  98. for (i=0; i < faulthandler_nsignals; i++) {
  99. handler = &faulthandler_handlers[i];
  100. #ifdef HAVE_SIGACTION
  101. + action.sa_flags = 0;
  102. +#ifdef USE_SIGINFO
  103. + action.sa_handler = faulthandler_fatal_error_siginfo;
  104. + action.sa_flags |= SA_SIGINFO;
  105. +#else
  106. action.sa_handler = faulthandler_fatal_error;
  107. +#endif
  108. sigemptyset(&action.sa_mask);
  109. /* Do not prevent the signal from being received from within
  110. its own signal handler */
  111. - action.sa_flags = SA_NODEFER;
  112. + action.sa_flags |= SA_NODEFER;
  113. #ifdef HAVE_SIGALTSTACK
  114. if (stack.ss_sp != NULL) {
  115. /* Call the signal handler on an alternate signal stack
  116. --- contrib/deprecated/python/faulthandler/traceback.c (b4ffd42d61e5a2398623b2c73b681b72896da86b)
  117. +++ contrib/deprecated/python/faulthandler/traceback.c (1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef)
  118. @@ -45,7 +45,7 @@ _Py_write_noraise(int fd, const char *buf, size_t count)
  119. This function is signal safe. */
  120. -static void
  121. +void
  122. reverse_string(char *text, const size_t len)
  123. {
  124. char tmp;
  125. @@ -59,17 +59,17 @@ reverse_string(char *text, const size_t len)
  126. }
  127. }
  128. -/* Format an integer in range [0; 999999] to decimal,
  129. +/* Format an integer in range [0; 999999999] to decimal,
  130. and write it into the file fd.
  131. This function is signal safe. */
  132. -static void
  133. +void
  134. dump_decimal(int fd, int value)
  135. {
  136. - char buffer[7];
  137. + char buffer[10];
  138. int len;
  139. - if (value < 0 || 999999 < value)
  140. + if (value < 0 || 999999999 < value)
  141. return;
  142. len = 0;
  143. do {