[PATCH v2 09/14] Print backtrace in a signal-safe manner

Chase Douglas chase.douglas at canonical.com
Mon Apr 9 11:17:35 PDT 2012


Backtraces are often printed in signal context, such as when a segfault
occurs.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 os/backtrace.c |   88 ++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/os/backtrace.c b/os/backtrace.c
index 81348f4..9c825fb 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -45,29 +45,52 @@ xorg_backtrace(void)
     int size, i;
     Dl_info info;
 
-    ErrorF("\n");
-    ErrorF("Backtrace:\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "Backtrace:\n");
     size = backtrace(array, 64);
     for (i = 0; i < size; i++) {
         int rc = dladdr(array[i], &info);
+        char string[20];
+        long unsigned int offset;
 
         if (rc == 0) {
-            ErrorF("%d: ?? [%p]\n", i, array[i]);
+            FormatUInt64(i, string);
+            LogMessageVerbSigSafe(X_NONE, -1, string);
+            LogMessageVerbSigSafe(X_NONE, -1, ": ?? [0x");
+            FormatUInt64((unsigned long)array[i], string);
+            LogMessageVerbSigSafe(X_NONE, -1, string);
+            LogMessageVerbSigSafe(X_NONE, -1, "]\n");
             continue;
         }
+
         mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
+
         if (info.dli_saddr)
-            ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod,
-                   info.dli_sname,
-                   (long unsigned int) ((char *) array[i] -
-                                        (char *) info.dli_saddr), array[i]);
+            offset = (char *) array[i] - (char *) info.dli_saddr;
         else
-            ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod,
-                   info.dli_fbase,
-                   (long unsigned int) ((char *) array[i] -
-                                        (char *) info.dli_fbase), array[i]);
+            offset = (char *) array[i] - (char *) info.dli_fbase;
+
+        FormatUInt64(i, string);
+        LogMessageVerbSigSafe(X_NONE, -1, string);
+        LogMessageVerbSigSafe(X_NONE, -1, ": ");
+        LogMessageVerbSigSafe(X_NONE, -1, mod);
+        LogMessageVerbSigSafe(X_NONE, -1, " (");
+        if (info.dli_saddr)
+            LogMessageVerbSigSafe(X_NONE, -1, info.dli_sname);
+        else {
+            LogMessageVerbSigSafe(X_NONE, -1, "0x");
+            FormatUInt64Hex((unsigned long)info.dli_fbase, string);
+            LogMessageVerbSigSafe(X_NONE, -1, string);
+        }
+        LogMessageVerbSigSafe(X_NONE, -1, "+0x");
+        FormatUInt64Hex(offset, string);
+        LogMessageVerbSigSafe(X_NONE, -1, string);
+        LogMessageVerbSigSafe(X_NONE, -1, ") [0x");
+        FormatUInt64Hex((unsigned long)array[i], string);
+        LogMessageVerbSigSafe(X_NONE, -1, string);
+        LogMessageVerbSigSafe(X_NONE, -1, "]\n");
     }
-    ErrorF("\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "\n");
 }
 
 #else                           /* not glibc or glibc < 2.1 */
@@ -95,8 +118,8 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
 {
     Dl_info dlinfo;
     ElfSym *dlsym;
-    char header[32];
     int depth = *((int *) arg);
+    char string[20];
 
     if (signo) {
         char signame[SIG2STR_MAX];
@@ -105,10 +128,20 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
             strcpy(signame, "unknown");
         }
 
-        ErrorF("** Signal %d (%s)\n", signo, signame);
+        LogMessageVerbSigSafe(X_NONE, -1, "** Signal ");
+        FormatUInt64(signo, string);
+        LogMessageVerbSigSafe(X_NONE, -1, string);
+        LogMessageVerbSigSafe(X_NONE, -1, " (");
+        LogMessageVerbSigSafe(X_NONE, -1, signame);
+        LogMessageVerbSigSafe(X_NONE, -1, ")\n");
     }
 
-    snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
+    FormatUInt64(depth, string);
+    LogMessageVerbSigSafe(X_NONE, -1, string);
+    LogMessageVerbSigSafe(X_NONE, -1, ": 0x");
+    FormatUInt64Hex((unsigned long)pc, string);
+    LogMessageVerbSigSafe(X_NONE, -1, string);
+
     *((int *) arg) = depth + 1;
 
     /* Ask system dynamic loader for info on the address */
@@ -123,15 +156,19 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
             symname = "<section start>";
             offset = pc - (uintptr_t) dlinfo.dli_fbase;
         }
-        ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname, symname, offset);
-
+        LogMessageVerbSigSafe(X_NONE, -1, ": ");
+        LogMessageVerbSigSafe(X_NONE, -1, dlinfo.dli_fname);
+        LogMessageVerbSigSafe(X_NONE, -1, ":");
+        LogMessageVerbSigSafe(X_NONE, -1, symname);
+        FormatUInt64Hex(offset, string);
+        LogMessageVerbSigSafe(X_NONE, -1, string);
     }
     else {
         /* Couldn't find symbol info from system dynamic loader, should
          * probably poke elfloader here, but haven't written that code yet,
          * so we just print the pc.
          */
-        ErrorF("%s\n", header);
+        LogMessageVerbSigSafe(X_NONE, -1, "\n");
     }
 
     return 0;
@@ -183,7 +220,7 @@ xorg_backtrace_pstack(void)
 
             if (bytesread > 0) {
                 btline[bytesread] = 0;
-                ErrorF("%s", btline);
+                LogMessageVerbSigSafe(X_NONE, -1, btline);
             }
             else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN)))
                 done = 1;
@@ -202,9 +239,8 @@ xorg_backtrace_pstack(void)
 void
 xorg_backtrace(void)
 {
-
-    ErrorF("\n");
-    ErrorF("Backtrace:\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "Backtrace:\n");
 
 #ifdef HAVE_PSTACK
 /* First try fork/exec of pstack - otherwise fall back to walkcontext
@@ -221,9 +257,13 @@ xorg_backtrace(void)
             walkcontext(&u, xorg_backtrace_frame, &depth);
         else
 #endif
-            ErrorF("Failed to get backtrace info: %s\n", strerror(errno));
+        {
+            LogMessageVerbSigSafe(X_NONE, -1, "Failed to get backtrace info: ");
+            LogMessageVerbSigSafe(X_NONE, -1, strerror(errno));
+            LogMessageVerbSigSafe(X_NONE, -1, "\n");
+        }
     }
-    ErrorF("\n");
+    LogMessageVerbSigSafe(X_NONE, -1, "\n");
 }
 
 #else
-- 
1.7.9.1



More information about the xorg-devel mailing list