aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/deprecated/python/faulthandler/patches/01-dump-extra-siginfo.patch
blob: 2737175531a4418807b9e0ceb29fef20b424420b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
commit 1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef
author: prettyboy
date: 2020-05-28T12:04:46+03:00
revision: 6879742

    Dump extra siginfo if term signal is received
    
    issue:DEVTOOLSSUPPORT-1110
    
    REVIEW: 1279268

--- contrib/deprecated/python/faulthandler/faulthandler.c	(b4ffd42d61e5a2398623b2c73b681b72896da86b)
+++ contrib/deprecated/python/faulthandler/faulthandler.c	(1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef)
@@ -43,6 +43,8 @@
 
 /* defined in traceback.c */
 extern Py_ssize_t _Py_write_noraise(int fd, const char *buf, size_t count);
+extern void dump_decimal(int fd, int value);
+extern void reverse_string(char *text, const size_t len);
 
 /* cast size_t to int because write() takes an int on Windows
    (anyway, the length is smaller than 30 characters) */
@@ -378,6 +380,81 @@ faulthandler_fatal_error(int signum)
     raise(signum);
 }
 
+static size_t
+uitoa(size_t val, char* ss) {
+    char* start = ss;
+    size_t len = 0;
+    do {
+        *ss = '0' + (val % 10);
+        val /= 10;
+        ss++; len++;
+    } while (val);
+    reverse_string(start, len);
+    return len;
+}
+
+static void
+read_proc_exe(pid_t pid, char* buff, size_t len) {
+    char pathname[32] = {0};
+    strcpy(pathname, "/proc/");
+    size_t pos = uitoa(pid, &pathname[6]) + 6;
+    strcpy(&pathname[pos], "/exe");
+
+    ssize_t l = readlink(pathname, buff, len);
+    if (l > 0) {
+        // readlink() does not append a null byte to buf
+        buff[l] = '\0';
+    } else {
+        strncpy(buff, "unknown_program", len);
+    }
+}
+
+static void
+faulthandler_fatal_error_siginfo(int signum, siginfo_t* siginfo, void* ctx)
+{
+    const int fd = fatal_error.fd;
+    int save_errno = errno;
+
+    if (!fatal_error.enabled)
+        return;
+
+    PUTS(fd, "\n*** Signal {si_signo=");
+    dump_decimal(fd, siginfo->si_signo);
+
+    PUTS(fd, ", si_code=");
+    dump_decimal(fd, siginfo->si_code);
+    switch (siginfo->si_code) {
+    case SEGV_ACCERR: PUTS(fd, " SEGV_ACCERR"); break;
+    case SEGV_MAPERR: PUTS(fd, " SEGV_MAPERR"); break;
+    case SI_KERNEL: PUTS(fd, " SI_KERNEL"); break;
+    case SI_TIMER: PUTS(fd, " SI_TIMER"); break;
+    case SI_TKILL: PUTS(fd, " SI_TKILL"); break;
+    case SI_USER: PUTS(fd, " SI_USER"); break;
+    }
+
+    if (siginfo->si_pid > 0) {
+        PUTS(fd, ", si_pid=");
+        dump_decimal(fd, siginfo->si_pid);
+        PUTS(fd, " ");
+        char buffer[PATH_MAX] = {0};
+        read_proc_exe(siginfo->si_pid, &buffer[0], PATH_MAX - 1);
+        PUTS(fd, &buffer[0]);
+    }
+
+    PUTS(fd, ", si_uid=");
+    dump_decimal(fd, siginfo->si_uid);
+
+    PUTS(fd, "} received by proc {pid=");
+    dump_decimal(fd, getpid());
+    PUTS(fd, ", uid=");
+    dump_decimal(fd, getuid());
+    PUTS(fd, "} ***\n");
+
+    faulthandler_fatal_error(signum);
+
+    errno = save_errno;
+}
+
 #ifdef MS_WINDOWS
 extern void _Py_dump_hexadecimal(int fd, unsigned long value, size_t bytes);
 
@@ -489,11 +566,17 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
         for (i=0; i < faulthandler_nsignals; i++) {
             handler = &faulthandler_handlers[i];
 #ifdef HAVE_SIGACTION
+            action.sa_flags = 0;
+#ifdef USE_SIGINFO
+            action.sa_handler = faulthandler_fatal_error_siginfo;
+            action.sa_flags |= SA_SIGINFO;
+#else
             action.sa_handler = faulthandler_fatal_error;
+#endif
             sigemptyset(&action.sa_mask);
             /* Do not prevent the signal from being received from within
                its own signal handler */
-            action.sa_flags = SA_NODEFER;
+            action.sa_flags |= SA_NODEFER;
 #ifdef HAVE_SIGALTSTACK
             if (stack.ss_sp != NULL) {
                 /* Call the signal handler on an alternate signal stack
--- contrib/deprecated/python/faulthandler/traceback.c	(b4ffd42d61e5a2398623b2c73b681b72896da86b)
+++ contrib/deprecated/python/faulthandler/traceback.c	(1a1c8a87cb6e966c8d716a90d516ee9ed23f5bef)
@@ -45,7 +45,7 @@ _Py_write_noraise(int fd, const char *buf, size_t count)
 
    This function is signal safe. */
 
-static void
+void
 reverse_string(char *text, const size_t len)
 {
     char tmp;
@@ -59,17 +59,17 @@ reverse_string(char *text, const size_t len)
     }
 }
 
-/* Format an integer in range [0; 999999] to decimal,
+/* Format an integer in range [0; 999999999] to decimal,
    and write it into the file fd.
 
    This function is signal safe. */
 
-static void
+void
 dump_decimal(int fd, int value)
 {
-    char buffer[7];
+    char buffer[10];
     int len;
-    if (value < 0 || 999999 < value)
+    if (value < 0 || 999999999 < value)
         return;
     len = 0;
     do {