Print backtrace in a signal-safe manner
Backtraces are often printed in signal context, such as when a segfault occurs. Signed-off-by: Chase Douglas <chase.douglas@canonical.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> os: print offset as unsigned int, not long unsigned int pnprintf() takes unsigned int for %u Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
		
							parent
							
								
									ac20815d52
								
							
						
					
					
						commit
						0fa5217836
					
				|  | @ -45,29 +45,37 @@ xorg_backtrace(void) | ||||||
|     int size, i; |     int size, i; | ||||||
|     Dl_info info; |     Dl_info info; | ||||||
| 
 | 
 | ||||||
|     ErrorF("\n"); |     ErrorFSigSafe("\n"); | ||||||
|     ErrorF("Backtrace:\n"); |     ErrorFSigSafe("Backtrace:\n"); | ||||||
|     size = backtrace(array, 64); |     size = backtrace(array, 64); | ||||||
|     for (i = 0; i < size; i++) { |     for (i = 0; i < size; i++) { | ||||||
|         int rc = dladdr(array[i], &info); |         int rc = dladdr(array[i], &info); | ||||||
| 
 | 
 | ||||||
|         if (rc == 0) { |         if (rc == 0) { | ||||||
|             ErrorF("%d: ?? [%p]\n", i, array[i]); |             ErrorFSigSafe("%u: ?? [%p]\n", i, array[i]); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; |         mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)"; | ||||||
|         if (info.dli_saddr) |         if (info.dli_saddr) | ||||||
|             ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod, |             ErrorFSigSafe( | ||||||
|                    info.dli_sname, |                 "%u: %s (%s+0x%x) [%p]\n", | ||||||
|                    (long unsigned int) ((char *) array[i] - |                 i, | ||||||
|                                         (char *) info.dli_saddr), array[i]); |                 mod, | ||||||
|  |                 info.dli_sname, | ||||||
|  |                 (unsigned int)((char *) array[i] - | ||||||
|  |                                (char *) info.dli_saddr), | ||||||
|  |                 array[i]); | ||||||
|         else |         else | ||||||
|             ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod, |             ErrorFSigSafe( | ||||||
|                    info.dli_fbase, |                 "%u: %s (%p+0x%x) [%p]\n", | ||||||
|                    (long unsigned int) ((char *) array[i] - |                 i, | ||||||
|                                         (char *) info.dli_fbase), array[i]); |                 mod, | ||||||
|  |                 info.dli_fbase, | ||||||
|  |                 (unsigned int)((char *) array[i] - | ||||||
|  |                                (char *) info.dli_fbase), | ||||||
|  |                 array[i]); | ||||||
|     } |     } | ||||||
|     ErrorF("\n"); |     ErrorFSigSafe("\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else                           /* not glibc or glibc < 2.1 */ | #else                           /* not glibc or glibc < 2.1 */ | ||||||
|  | @ -105,7 +113,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg) | ||||||
|             strcpy(signame, "unknown"); |             strcpy(signame, "unknown"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ErrorF("** Signal %d (%s)\n", signo, signame); |         ErrorFSigSafe("** Signal %u (%s)\n", signo, signame); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc); |     snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc); | ||||||
|  | @ -123,7 +131,8 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg) | ||||||
|             symname = "<section start>"; |             symname = "<section start>"; | ||||||
|             offset = pc - (uintptr_t) dlinfo.dli_fbase; |             offset = pc - (uintptr_t) dlinfo.dli_fbase; | ||||||
|         } |         } | ||||||
|         ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname, symname, offset); |         ErrorFSigSafe("%s: %s:%s+0x%x\n", header, dlinfo.dli_fname, symname, | ||||||
|  |                      offset); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|  | @ -131,7 +140,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg) | ||||||
|          * probably poke elfloader here, but haven't written that code yet, |          * probably poke elfloader here, but haven't written that code yet, | ||||||
|          * so we just print the pc. |          * so we just print the pc. | ||||||
|          */ |          */ | ||||||
|         ErrorF("%s\n", header); |         ErrorFSigSafe("%s\n", header); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
|  | @ -183,7 +192,7 @@ xorg_backtrace_pstack(void) | ||||||
| 
 | 
 | ||||||
|             if (bytesread > 0) { |             if (bytesread > 0) { | ||||||
|                 btline[bytesread] = 0; |                 btline[bytesread] = 0; | ||||||
|                 ErrorF("%s", btline); |                 ErrorFSigSafe("%s", btline); | ||||||
|             } |             } | ||||||
|             else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN))) |             else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN))) | ||||||
|                 done = 1; |                 done = 1; | ||||||
|  | @ -203,8 +212,8 @@ void | ||||||
| xorg_backtrace(void) | xorg_backtrace(void) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|     ErrorF("\n"); |     ErrorFSigSafe("\n"); | ||||||
|     ErrorF("Backtrace:\n"); |     ErrorFSigSafe("Backtrace:\n"); | ||||||
| 
 | 
 | ||||||
| #ifdef HAVE_PSTACK | #ifdef HAVE_PSTACK | ||||||
| /* First try fork/exec of pstack - otherwise fall back to walkcontext
 | /* First try fork/exec of pstack - otherwise fall back to walkcontext
 | ||||||
|  | @ -221,9 +230,9 @@ xorg_backtrace(void) | ||||||
|             walkcontext(&u, xorg_backtrace_frame, &depth); |             walkcontext(&u, xorg_backtrace_frame, &depth); | ||||||
|         else |         else | ||||||
| #endif | #endif | ||||||
|             ErrorF("Failed to get backtrace info: %s\n", strerror(errno)); |             ErrorFSigSafe("Failed to get backtrace info: %s\n", strerror(errno)); | ||||||
|     } |     } | ||||||
|     ErrorF("\n"); |     ErrorFSigSafe("\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #else | #else | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue