Matej Habrnal bcb3c1
From 4eee77568fe24bcb9341ee9c2eaa74cb048103cb Mon Sep 17 00:00:00 2001
Matej Habrnal bcb3c1
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal bcb3c1
Date: Thu, 13 Nov 2014 12:08:07 +0100
Matej Habrnal bcb3c1
Subject: [PATCH] gdb: make gdb aware of the abrt's debuginfo dir
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
A debuginfo package might ship an auto-loaded gdb script. If abrt
Matej Habrnal bcb3c1
unpacks that package into the abrt's debuginfo cache dir and points gdb
Matej Habrnal bcb3c1
to that directory, gdb refuses to auto-loaded that gdb scripts and
Matej Habrnal bcb3c1
produces a plenty of warning messages that abrt writes to 'backtrace'
Matej Habrnal bcb3c1
file.
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
The previous solution of this issue was to turn auto-load off completely
Matej Habrnal bcb3c1
but it turned the pretty printer off too.
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
The correct solution is to add the abrt's debuginfo cache directory to
Matej Habrnal bcb3c1
auto-load safe-path and auto-load scripts-dir settings.
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
Thanks Jan Kratochvil <jkratoch@redhat.com>
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
Requires: rhbz#1163335
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal bcb3c1
---
Matej Habrnal bcb3c1
 src/lib/hooklib.c | 83 ++++++++++++++++++++++++++++++++++++-------------------
Matej Habrnal bcb3c1
 1 file changed, 55 insertions(+), 28 deletions(-)
Matej Habrnal bcb3c1
Matej Habrnal bcb3c1
diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c
Matej Habrnal bcb3c1
index 4a50727..1d45cdd 100644
Matej Habrnal bcb3c1
--- a/src/lib/hooklib.c
Matej Habrnal bcb3c1
+++ b/src/lib/hooklib.c
Matej Habrnal bcb3c1
@@ -252,11 +252,12 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
     /* Let user know what's going on */
Matej Habrnal bcb3c1
     log(_("Generating backtrace"));
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
-    char *args[21];
Matej Habrnal bcb3c1
-    args[0] = (char*)"gdb";
Matej Habrnal bcb3c1
-    args[1] = (char*)"-batch";
Matej Habrnal bcb3c1
-    args[2] = (char*)"-ex";
Matej Habrnal bcb3c1
+    unsigned i = 0;
Matej Habrnal bcb3c1
+    char *args[25];
Matej Habrnal bcb3c1
+    args[i++] = (char*)"gdb";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-batch";
Matej Habrnal bcb3c1
     struct strbuf *set_debug_file_directory = strbuf_new();
Matej Habrnal bcb3c1
+    unsigned auto_load_base_index = 0;
Matej Habrnal bcb3c1
     if(debuginfo_dirs == NULL)
Matej Habrnal bcb3c1
     {
Matej Habrnal bcb3c1
         // set non-existent debug file directory to prevent resolving
Matej Habrnal bcb3c1
@@ -266,6 +267,8 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
     else
Matej Habrnal bcb3c1
     {
Matej Habrnal bcb3c1
         strbuf_append_str(set_debug_file_directory, "set debug-file-directory /usr/lib/debug");
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+        struct strbuf *debug_directories = strbuf_new();
Matej Habrnal bcb3c1
         const char *p = debuginfo_dirs;
Matej Habrnal bcb3c1
         while (1)
Matej Habrnal bcb3c1
         {
Matej Habrnal bcb3c1
@@ -274,11 +277,25 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
             if (*p == '\0')
Matej Habrnal bcb3c1
                 break;
Matej Habrnal bcb3c1
             const char *colon_or_nul = strchrnul(p, ':');
Matej Habrnal bcb3c1
-            strbuf_append_strf(set_debug_file_directory, ":%.*s/usr/lib/debug", (int)(colon_or_nul - p), p);
Matej Habrnal bcb3c1
+            strbuf_append_strf(debug_directories, "%s%.*s/usr/lib/debug", (debug_directories->len == 0 ? "" : ":"),
Matej Habrnal bcb3c1
+                                                                          (int)(colon_or_nul - p), p);
Matej Habrnal bcb3c1
             p = colon_or_nul;
Matej Habrnal bcb3c1
         }
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+        strbuf_append_strf(set_debug_file_directory, ":%s", debug_directories->buf);
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+        args[i++] = (char*)"-iex";
Matej Habrnal bcb3c1
+        auto_load_base_index = i;
Matej Habrnal bcb3c1
+        args[i++] = xasprintf("add-auto-load-safe-path %s", debug_directories->buf);
Matej Habrnal bcb3c1
+        args[i++] = (char*)"-iex";
Matej Habrnal bcb3c1
+        args[i++] = xasprintf("add-auto-load-scripts-directory %s", debug_directories->buf);
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+        strbuf_free(debug_directories);
Matej Habrnal bcb3c1
     }
Matej Habrnal bcb3c1
-    args[3] = strbuf_free_nobuf(set_debug_file_directory);
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    const unsigned debug_dir_cmd_index = i++;
Matej Habrnal bcb3c1
+    args[debug_dir_cmd_index] = strbuf_free_nobuf(set_debug_file_directory);
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
     /* "file BINARY_FILE" is needed, without it gdb cannot properly
Matej Habrnal bcb3c1
      * unwind the stack. Currently the unwind information is located
Matej Habrnal bcb3c1
@@ -300,27 +317,31 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
      * TODO: check mtimes on COREFILE and BINARY_FILE and not supply
Matej Habrnal bcb3c1
      * BINARY_FILE if it is newer (to at least avoid gdb complaining).
Matej Habrnal bcb3c1
      */
Matej Habrnal bcb3c1
-    args[4] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[5] = xasprintf("file %s", executable);
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    const unsigned file_cmd_index = i++;
Matej Habrnal bcb3c1
+    args[file_cmd_index] = xasprintf("file %s", executable);
Matej Habrnal bcb3c1
     free(executable);
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
-    args[6] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, dump_dir_name);
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    const unsigned core_cmd_index = i++;
Matej Habrnal bcb3c1
+    args[core_cmd_index] = xasprintf("core-file %s/"FILENAME_COREDUMP, dump_dir_name);
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
-    args[8] = (char*)"-ex";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    const unsigned bt_cmd_index = i++;
Matej Habrnal bcb3c1
     /*args[9] = ... see below */
Matej Habrnal bcb3c1
-    args[10] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[11] = (char*)"info sharedlib";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"info sharedlib";
Matej Habrnal bcb3c1
     /* glibc's abort() stores its message in __abort_msg variable */
Matej Habrnal bcb3c1
-    args[12] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[13] = (char*)"print (char*)__abort_msg";
Matej Habrnal bcb3c1
-    args[14] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[15] = (char*)"print (char*)__glib_assert_msg";
Matej Habrnal bcb3c1
-    args[16] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[17] = (char*)"info all-registers";
Matej Habrnal bcb3c1
-    args[18] = (char*)"-ex";
Matej Habrnal bcb3c1
-    args[19] = (char*)"disassemble";
Matej Habrnal bcb3c1
-    args[20] = NULL;
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"print (char*)__abort_msg";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"print (char*)__glib_assert_msg";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"info all-registers";
Matej Habrnal bcb3c1
+    args[i++] = (char*)"-ex";
Matej Habrnal bcb3c1
+    const unsigned dis_cmd_index = i++;
Matej Habrnal bcb3c1
+    args[dis_cmd_index] = (char*)"disassemble";
Matej Habrnal bcb3c1
+    args[i++] = NULL;
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
     /* Get the backtrace, but try to cap its size */
Matej Habrnal bcb3c1
     /* Limit bt depth. With no limit, gdb sometimes OOMs the machine */
Matej Habrnal bcb3c1
@@ -330,9 +351,9 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
     char *bt = NULL;
Matej Habrnal bcb3c1
     while (1)
Matej Habrnal bcb3c1
     {
Matej Habrnal bcb3c1
-        args[9] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full);
Matej Habrnal bcb3c1
+        args[bt_cmd_index] = xasprintf("%s backtrace %u%s", thread_apply_all, bt_depth, full);
Matej Habrnal bcb3c1
         bt = exec_vp(args, /*redirect_stderr:*/ 1, timeout_sec, NULL);
Matej Habrnal bcb3c1
-        free(args[9]);
Matej Habrnal bcb3c1
+        free(args[bt_cmd_index]);
Matej Habrnal bcb3c1
         if ((bt && strnlen(bt, 256*1024) < 256*1024) || bt_depth <= 32)
Matej Habrnal bcb3c1
         {
Matej Habrnal bcb3c1
             break;
Matej Habrnal bcb3c1
@@ -357,7 +378,7 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
          * End of assembler dump.
Matej Habrnal bcb3c1
          * (IOW: "empty" dump)
Matej Habrnal bcb3c1
          */
Matej Habrnal bcb3c1
-        args[19] = (char*)"disassemble $pc-20, $pc+64";
Matej Habrnal bcb3c1
+        args[dis_cmd_index] = (char*)"disassemble $pc-20, $pc+64";
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
         if (bt_depth <= 64 && thread_apply_all[0] != '\0')
Matej Habrnal bcb3c1
         {
Matej Habrnal bcb3c1
@@ -373,9 +394,15 @@ char *get_backtrace(const char *dump_dir_name, unsigned timeout_sec, const char
Matej Habrnal bcb3c1
         }
Matej Habrnal bcb3c1
     }
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
-    free(args[3]);
Matej Habrnal bcb3c1
-    free(args[5]);
Matej Habrnal bcb3c1
-    free(args[7]);
Matej Habrnal bcb3c1
+    if (auto_load_base_index > 0)
Matej Habrnal bcb3c1
+    {
Matej Habrnal bcb3c1
+        free(args[auto_load_base_index]);
Matej Habrnal bcb3c1
+        free(args[auto_load_base_index + 2]);
Matej Habrnal bcb3c1
+    }
Matej Habrnal bcb3c1
+
Matej Habrnal bcb3c1
+    free(args[debug_dir_cmd_index]);
Matej Habrnal bcb3c1
+    free(args[file_cmd_index]);
Matej Habrnal bcb3c1
+    free(args[core_cmd_index]);
Matej Habrnal bcb3c1
     return bt;
Matej Habrnal bcb3c1
 }
Matej Habrnal bcb3c1
 
Matej Habrnal bcb3c1
-- 
Matej Habrnal bcb3c1
2.1.0
Matej Habrnal bcb3c1