about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/libraries/libbacktrace/0003-libbacktrace-Support-multiple-build-id-directories.patch
blob: 7b8f8f0f61dc5441cc4928bbcc3a890eb63bcb63 (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
From 47c3503938c863d55c835463d8815b5fa4ab8326 Mon Sep 17 00:00:00 2001
From: Jan Tojnar <jtojnar@gmail.com>
Date: Sat, 24 Dec 2022 20:19:27 +0100
Subject: [PATCH 3/4] libbacktrace: Support multiple build id directories
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

gdb supports multiple debug directories separated by colons:
https://github.com/bminor/binutils-gdb/blob/fcbfb25dcca625a7f999ec51d48b6fc3a32123c3/gdb/build-id.c#L136-L142

This is useful for example when using dwarffs in addition
to debug data installed using distribution’s package manager.
---
 elf.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 21 deletions(-)

diff --git a/elf.c b/elf.c
index 21fbe4f..ccffa95 100644
--- a/elf.c
+++ b/elf.c
@@ -865,12 +865,12 @@ elf_readlink (struct backtrace_state *state, const char *filename,
    when the build ID is known is in /usr/lib/debug/.build-id.  */
 
 static int
-elf_open_debugfile_by_buildid (struct backtrace_state *state,
+elf_open_debugfile_by_buildid (const char * const prefix,
+                               struct backtrace_state *state,
 			       const char *buildid_data, size_t buildid_size,
 			       backtrace_error_callback error_callback,
 			       void *data)
 {
-  const char * const prefix = SYSTEM_DEBUG_DIR BUILD_ID_DIR;
   const size_t prefix_len = strlen (prefix);
   const char * const suffix = ".debug";
   const size_t suffix_len = strlen (suffix);
@@ -6947,27 +6947,42 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
   if (buildid_data != NULL)
     {
       int d;
+      char debug_directories[strlen(SYSTEM_DEBUG_DIR) + 1];
+      char *debug_dir;
 
-      d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size,
-					 error_callback, data);
-      if (d >= 0)
-	{
-	  int ret;
+      strcpy(debug_directories, SYSTEM_DEBUG_DIR);
 
-	  elf_release_view (state, &buildid_view, error_callback, data);
-	  if (debuglink_view_valid)
-	    elf_release_view (state, &debuglink_view, error_callback, data);
-	  if (debugaltlink_view_valid)
-	    elf_release_view (state, &debugaltlink_view, error_callback, data);
-	  ret = elf_add (state, "", d, NULL, 0, base_address, opd,
-			 error_callback, data, fileline_fn, found_sym,
-			 found_dwarf, NULL, 0, 1, NULL, 0);
-	  if (ret < 0)
-	    backtrace_close (d, error_callback, data);
-	  else if (descriptor >= 0)
-	    backtrace_close (descriptor, error_callback, data);
-	  return ret;
-	}
+      debug_dir = strtok (debug_directories, ":");
+      while (debug_dir != NULL)
+      {
+        char prefix[strlen(debug_dir) + strlen(BUILD_ID_DIR) + 1];
+        strcpy(prefix, debug_dir);
+        strcat(prefix, BUILD_ID_DIR);
+
+        d = elf_open_debugfile_by_buildid (prefix, state, buildid_data, buildid_size,
+                                           error_callback, data);
+
+        if (d >= 0)
+          {
+            int ret;
+
+            elf_release_view (state, &buildid_view, error_callback, data);
+            if (debuglink_view_valid)
+              elf_release_view (state, &debuglink_view, error_callback, data);
+            if (debugaltlink_view_valid)
+              elf_release_view (state, &debugaltlink_view, error_callback, data);
+            ret = elf_add (state, "", d, NULL, 0, base_address, opd,
+                           error_callback, data, fileline_fn, found_sym,
+                           found_dwarf, NULL, 0, 1, NULL, 0);
+            if (ret < 0)
+              backtrace_close (d, error_callback, data);
+            else if (descriptor >= 0)
+              backtrace_close (descriptor, error_callback, data);
+            return ret;
+          }
+
+        debug_dir = strtok (NULL, ":");
+      }
     }
 
   if (buildid_view_valid)
-- 
2.43.1