Skip to content

Commit 7de555d

Browse files
committed
tests: fix build on musl-based systems
Musl libc does not provide the backtrace functions in its implementation. These functions are typically provided by glibc's <execinfo.h>. As a fallback for musl-based systems, support linking against the external libunwind library and using dladdr() to obtain similar stack trace info. Note that the usage of dladdr() is similar to that of backtrace_symbols in glibc, and it can be used with glibc as well. Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
1 parent afc4955 commit 7de555d

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

include/test.mk

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ DEBUG_PRINTS ?= 0
1313
OPTIMIZATIONS=-O2 -ggdb
1414
CFLAGS_LTO =
1515
CFLAGS_GCOV =
16+
LIBS = -lefivar
17+
BACKTRACE_DEFINES ?=
18+
19+
INCL_LIBUNWIND = '\#include <libunwind.h>'
20+
HAVE_LIBUNWIND := $(shell echo $(INCL_LIBUNWIND) | $(CC) -E - >/dev/null 2>&1 && echo 1 || echo 0)
21+
22+
ifeq ($(HAVE_LIBUNWIND),1)
23+
BACKTRACE_DEFINES = -DHAVE_LIBUNWIND
24+
LIBS += -lunwind
25+
endif
26+
1627
CFLAGS = $(OPTIMIZATIONS) -std=gnu11 \
1728
-isystem $(TOPDIR)/include/system \
1829
$(EFI_INCLUDES) \
@@ -44,7 +55,8 @@ CFLAGS = $(OPTIMIZATIONS) -std=gnu11 \
4455
-DEFI_FUNCTION_WRAPPER \
4556
-DGNU_EFI_USE_MS_ABI -DPAGE_SIZE=4096 \
4657
-DSHIM_UNIT_TEST \
47-
"-DDEFAULT_DEBUG_PRINT_STATE=$(DEBUG_PRINTS)"
58+
"-DDEFAULT_DEBUG_PRINT_STATE=$(DEBUG_PRINTS)" \
59+
$(BACKTRACE_DEFINES)
4860

4961
# On some systems (e.g. Arch Linux), limits.h is in the "include-fixed" instead
5062
# of the "include" directory
@@ -109,7 +121,7 @@ tests := $(patsubst %.c,%,$(wildcard test-*.c))
109121
$(tests) :: test-% : | libefi-test.a
110122

111123
$(tests) :: test-% : test.c test-%.c $(test-%_FILES)
112-
$(CC) $(CFLAGS) -o $@ $(sort $^ $(wildcard $*.c) $(test-$*_FILES)) libefi-test.a -lefivar
124+
$(CC) $(CFLAGS) -o $@ $(sort $^ $(wildcard $*.c) $(test-$*_FILES)) libefi-test.a $(LIBS)
113125
$(VALGRIND) ./$@
114126

115127
test : $(tests)

test-load-options.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
#include "shim.h"
1616

17-
#include <execinfo.h>
1817
#include <stdio.h>
1918
#include <efivar/efivar.h>
2019

test.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@
66

77
#include "shim.h"
88

9-
#include <execinfo.h>
109
#include <stdio.h>
1110
#include <string.h>
1211

12+
#if defined(__GLIBC__)
13+
#include <execinfo.h>
14+
#elif defined(HAVE_LIBUNWIND)
15+
#include <stddef.h>
16+
#include <dlfcn.h>
17+
/* no backtrace() prototype in libunwind.h, however the library adds the symbol */
18+
extern int backtrace(void **buffer, int size);
19+
#else
20+
static int backtrace(void **buffer, int size) { (void)buffer; (void)size; return 0; }
21+
#endif
22+
1323
#define BT_BUF_SIZE (4096/sizeof(void *))
1424

1525
static void *frames[BT_BUF_SIZE] = { 0, };
@@ -20,19 +30,33 @@ int debug = DEFAULT_DEBUG_PRINT_STATE;
2030
void
2131
print_traceback(int skip)
2232
{
23-
int nptrs;
24-
char **strings;
25-
26-
nptrs = backtrace(frames, BT_BUF_SIZE);
27-
if (nptrs < skip)
33+
int nptrs = backtrace(frames, BT_BUF_SIZE);
34+
if (nptrs <= skip)
2835
return;
2936

30-
strings = backtrace_symbols(frames, nptrs);
31-
for (int i = skip; strings != NULL && i < nptrs; i++) {
37+
#if defined(__GLIBC__)
38+
char **strings = backtrace_symbols(frames, nptrs);
39+
for (int i = skip; strings != NULL && i < nptrs; i++)
3240
printf("%p %s\n", (void *)frames[i], strings[i]);
41+
free(strings);
42+
#elif defined(HAVE_LIBUNWIND)
43+
for (int i = skip; i < nptrs; ++i) {
44+
void *addr = frames[i];
45+
Dl_info dlinfo;
46+
47+
if (!dladdr(addr, &dlinfo)) {
48+
printf("%p\n", addr);
49+
continue;
50+
}
51+
52+
ptrdiff_t offset = addr - dlinfo.dli_saddr;
53+
printf("%p %s(%s%c%#tx)\n", addr,
54+
dlinfo.dli_fname ?: "",
55+
dlinfo.dli_sname ?: "",
56+
offset < 0 ? '-' : '+',
57+
offset < 0 ? -offset : offset);
3358
}
34-
if (strings)
35-
free(strings);
59+
#endif
3660
}
3761

3862
#pragma GCC diagnostic ignored "-Wunused-parameter"

0 commit comments

Comments
 (0)