Skip to content

Commit 1e03848

Browse files
committed
libbacktrace: Add support for NIX_DEBUG_INFO_DIRS
Also fix tests.
1 parent 14c5fae commit 1e03848

4 files changed

Lines changed: 259 additions & 0 deletions
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
From f409ee343fe6cdc059bb411746f27a515aec66a8 Mon Sep 17 00:00:00 2001
2+
From: Jan Tojnar <jtojnar@gmail.com>
3+
Date: Sat, 24 Dec 2022 16:46:18 +0100
4+
Subject: [PATCH 2/4] libbacktrace: Allow configuring debug dir
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
On platforms that do not use FHS like NixOS or GNU Guix,
10+
the build-id directories are not under `/usr/lib/debug`.
11+
12+
Let’s add `--with-separate-debug-dir` configure flag so that
13+
the path can be changed. The same flag is supported by gdb:
14+
15+
https://github.com/bminor/binutils-gdb/blob/095f84c7e3cf85cd68c657c46b80be078f336bc9/gdb/configure.ac#L113-L115
16+
---
17+
Makefile.am | 11 ++++++-----
18+
configure.ac | 8 ++++++++
19+
elf.c | 4 ++--
20+
3 files changed, 16 insertions(+), 7 deletions(-)
21+
22+
diff --git a/Makefile.am b/Makefile.am
23+
index 6eab991..da443c1 100644
24+
--- a/Makefile.am
25+
+++ b/Makefile.am
26+
@@ -33,7 +33,8 @@ ACLOCAL_AMFLAGS = -I config
27+
28+
AM_CPPFLAGS =
29+
30+
-AM_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) $(PIC_FLAG)
31+
+AM_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) $(PIC_FLAG) \
32+
+ -DSYSTEM_DEBUG_DIR=\"$(SEPARATE_DEBUG_DIR)\"
33+
34+
include_HEADERS = backtrace.h backtrace-supported.h
35+
36+
@@ -134,7 +135,7 @@ libbacktrace_noformat_la_DEPENDENCIES = $(libbacktrace_noformat_la_LIBADD)
37+
if HAVE_ELF
38+
if HAVE_OBJCOPY_DEBUGLINK
39+
40+
-TEST_BUILD_ID_DIR=$(abs_builddir)/usr/lib/debug/.build-id/
41+
+TEST_DEBUG_DIR=$(abs_builddir)/usr/lib/debug
42+
43+
check_LTLIBRARIES += libbacktrace_elf_for_test.la
44+
45+
@@ -143,8 +144,8 @@ libbacktrace_elf_for_test_la_LIBADD = $(BACKTRACE_FILE) elf_for_test.lo \
46+
$(VIEW_FILE) $(ALLOC_FILE)
47+
48+
elf_for_test.c: elf.c
49+
- SEARCH='^#define SYSTEM_BUILD_ID_DIR.*$$'; \
50+
- REPLACE="#define SYSTEM_BUILD_ID_DIR \"$(TEST_BUILD_ID_DIR)\""; \
51+
+ SEARCH='^#define BUILD_ID_DIR.*$$'; \
52+
+ REPLACE='\0\n#undef SYSTEM_DEBUG_DIR\n#define SYSTEM_DEBUG_DIR "$(TEST_DEBUG_DIR)"'; \
53+
$(SED) "s%$$SEARCH%$$REPLACE%" \
54+
$< \
55+
> $@.tmp
56+
@@ -468,7 +469,7 @@ endif HAVE_OBJCOPY_DEBUGLINK
57+
58+
%_buildid: %
59+
./install-debuginfo-for-buildid.sh \
60+
- "$(TEST_BUILD_ID_DIR)" \
61+
+ "$(TEST_DEBUG_DIR)/.build-id" \
62+
$<
63+
$(OBJCOPY) --strip-debug $< $@
64+
65+
diff --git a/configure.ac b/configure.ac
66+
index 7f122cb..bb590ab 100644
67+
--- a/configure.ac
68+
+++ b/configure.ac
69+
@@ -67,6 +67,14 @@ AM_MAINTAINER_MODE
70+
AC_ARG_WITH(target-subdir,
71+
[ --with-target-subdir=SUBDIR Configuring in a subdirectory for target])
72+
73+
+AC_ARG_WITH(separate-debug-dir,
74+
+[ --with-separate-debug-dir=DEBUGDIR Look for global separate debug info in this path @<:@LIBDIR/debug@:>@],
75+
+[separate_debug_dir=$withval],
76+
+[separate_debug_dir=$libdir/debug])
77+
+
78+
+SEPARATE_DEBUG_DIR=$separate_debug_dir
79+
+AC_SUBST(SEPARATE_DEBUG_DIR)
80+
+
81+
# We must force CC to /not/ be precious variables; otherwise
82+
# the wrong, non-multilib-adjusted value will be used in multilibs.
83+
# As a side effect, we have to subst CFLAGS ourselves.
84+
diff --git a/elf.c b/elf.c
85+
index e82ecc5..8b1189c 100644
86+
--- a/elf.c
87+
+++ b/elf.c
88+
@@ -856,7 +856,7 @@ elf_readlink (struct backtrace_state *state, const char *filename,
89+
}
90+
}
91+
92+
-#define SYSTEM_BUILD_ID_DIR "/usr/lib/debug/.build-id/"
93+
+#define BUILD_ID_DIR "/.build-id/"
94+
95+
/* Open a separate debug info file, using the build ID to find it.
96+
Returns an open file descriptor, or -1.
97+
@@ -870,7 +870,7 @@ elf_open_debugfile_by_buildid (struct backtrace_state *state,
98+
backtrace_error_callback error_callback,
99+
void *data)
100+
{
101+
- const char * const prefix = SYSTEM_BUILD_ID_DIR;
102+
+ const char * const prefix = SYSTEM_DEBUG_DIR BUILD_ID_DIR;
103+
const size_t prefix_len = strlen (prefix);
104+
const char * const suffix = ".debug";
105+
const size_t suffix_len = strlen (suffix);
106+
--
107+
2.38.1
108+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
From de122af5382d8017cae63bdee946206c6c6c23ab Mon Sep 17 00:00:00 2001
2+
From: Jan Tojnar <jtojnar@gmail.com>
3+
Date: Sat, 24 Dec 2022 20:19:27 +0100
4+
Subject: [PATCH 3/4] libbacktrace: Support multiple build id directories
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
gdb supports multiple debug directories separated by colons:
10+
https://github.com/bminor/binutils-gdb/blob/fcbfb25dcca625a7f999ec51d48b6fc3a32123c3/gdb/build-id.c#L136-L142
11+
12+
This is useful for example when using dwarffs in addition
13+
to debug data installed using distribution’s package manager.
14+
---
15+
elf.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
16+
1 file changed, 36 insertions(+), 21 deletions(-)
17+
18+
diff --git a/elf.c b/elf.c
19+
index 8b1189c..65c647a 100644
20+
--- a/elf.c
21+
+++ b/elf.c
22+
@@ -865,12 +865,12 @@ elf_readlink (struct backtrace_state *state, const char *filename,
23+
when the build ID is known is in /usr/lib/debug/.build-id. */
24+
25+
static int
26+
-elf_open_debugfile_by_buildid (struct backtrace_state *state,
27+
+elf_open_debugfile_by_buildid (const char * const prefix,
28+
+ struct backtrace_state *state,
29+
const char *buildid_data, size_t buildid_size,
30+
backtrace_error_callback error_callback,
31+
void *data)
32+
{
33+
- const char * const prefix = SYSTEM_DEBUG_DIR BUILD_ID_DIR;
34+
const size_t prefix_len = strlen (prefix);
35+
const char * const suffix = ".debug";
36+
const size_t suffix_len = strlen (suffix);
37+
@@ -6936,27 +6936,42 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
38+
if (buildid_data != NULL)
39+
{
40+
int d;
41+
+ char debug_directories[strlen(SYSTEM_DEBUG_DIR) + 1];
42+
+ char *debug_dir;
43+
44+
- d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size,
45+
- error_callback, data);
46+
- if (d >= 0)
47+
- {
48+
- int ret;
49+
+ strcpy(debug_directories, SYSTEM_DEBUG_DIR);
50+
51+
- elf_release_view (state, &buildid_view, error_callback, data);
52+
- if (debuglink_view_valid)
53+
- elf_release_view (state, &debuglink_view, error_callback, data);
54+
- if (debugaltlink_view_valid)
55+
- elf_release_view (state, &debugaltlink_view, error_callback, data);
56+
- ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
57+
- data, fileline_fn, found_sym, found_dwarf, NULL, 0,
58+
- 1, NULL, 0);
59+
- if (ret < 0)
60+
- backtrace_close (d, error_callback, data);
61+
- else if (descriptor >= 0)
62+
- backtrace_close (descriptor, error_callback, data);
63+
- return ret;
64+
- }
65+
+ debug_dir = strtok (debug_directories, ":");
66+
+ while (debug_dir != NULL)
67+
+ {
68+
+ char prefix[strlen(debug_dir) + strlen(BUILD_ID_DIR) + 1];
69+
+ strcpy(prefix, debug_dir);
70+
+ strcat(prefix, BUILD_ID_DIR);
71+
+
72+
+ d = elf_open_debugfile_by_buildid (prefix, state, buildid_data, buildid_size,
73+
+ error_callback, data);
74+
+
75+
+ if (d >= 0)
76+
+ {
77+
+ int ret;
78+
+
79+
+ elf_release_view (state, &buildid_view, error_callback, data);
80+
+ if (debuglink_view_valid)
81+
+ elf_release_view (state, &debuglink_view, error_callback, data);
82+
+ if (debugaltlink_view_valid)
83+
+ elf_release_view (state, &debugaltlink_view, error_callback, data);
84+
+ ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
85+
+ data, fileline_fn, found_sym, found_dwarf, NULL, 0,
86+
+ 1, NULL, 0);
87+
+ if (ret < 0)
88+
+ backtrace_close (d, error_callback, data);
89+
+ else if (descriptor >= 0)
90+
+ backtrace_close (descriptor, error_callback, data);
91+
+ return ret;
92+
+ }
93+
+
94+
+ debug_dir = strtok (NULL, ":");
95+
+ }
96+
}
97+
98+
if (buildid_view_valid)
99+
--
100+
2.38.1
101+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
From a3b7510e4c9e7201a4301f2a45d8569b06354607 Mon Sep 17 00:00:00 2001
2+
From: Jan Tojnar <jtojnar@gmail.com>
3+
Date: Sat, 24 Dec 2022 20:30:22 +0100
4+
Subject: [PATCH 4/4] libbacktrace: Support NIX_DEBUG_INFO_DIRS environment
5+
variable
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset=UTF-8
8+
Content-Transfer-Encoding: 8bit
9+
10+
Let’s make debug data lookup work on NixOS just like in gdb.
11+
---
12+
elf.c | 11 +++++++++--
13+
1 file changed, 9 insertions(+), 2 deletions(-)
14+
15+
diff --git a/elf.c b/elf.c
16+
index 65c647a..5c8abc0 100644
17+
--- a/elf.c
18+
+++ b/elf.c
19+
@@ -6935,11 +6935,18 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
20+
21+
if (buildid_data != NULL)
22+
{
23+
+ const char *debug_directories_immutable;
24+
+ const char *nix_debug = getenv ("NIX_DEBUG_INFO_DIRS");
25+
+ if (nix_debug != NULL)
26+
+ debug_directories_immutable = nix_debug;
27+
+ else
28+
+ debug_directories_immutable = SYSTEM_DEBUG_DIR;
29+
+
30+
int d;
31+
- char debug_directories[strlen(SYSTEM_DEBUG_DIR) + 1];
32+
+ char debug_directories[strlen(debug_directories_immutable) + 1];
33+
char *debug_dir;
34+
35+
- strcpy(debug_directories, SYSTEM_DEBUG_DIR);
36+
+ strcpy(debug_directories, debug_directories_immutable);
37+
38+
debug_dir = strtok (debug_directories, ":");
39+
while (debug_dir != NULL)
40+
--
41+
2.38.1
42+

pkgs/development/libraries/libbacktrace/default.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ stdenv.mkDerivation {
2222
# Fix tests with shared library.
2323
# https://github.com/ianlancetaylor/libbacktrace/pull/99
2424
./0001-libbacktrace-avoid-libtool-wrapping-tests.patch
25+
26+
# Support multiple debug dirs.
27+
# https://github.com/ianlancetaylor/libbacktrace/pull/100
28+
./0002-libbacktrace-Allow-configuring-debug-dir.patch
29+
./0003-libbacktrace-Support-multiple-build-id-directories.patch
30+
31+
# Support NIX_DEBUG_INFO_DIRS environment variable.
32+
./0004-libbacktrace-Support-NIX_DEBUG_INFO_DIRS-environment.patch
2533
];
2634

2735
nativeBuildInputs = [

0 commit comments

Comments
 (0)