Let's use something that specializes in that task and does a better job of it than whatever we'll come up with. Due to how it's implemented the stacktrace will always show waitpid() as frame 0 now but we can live with that.
gstack prints to stdout but litest_log() uses stderr, so we cannot just call system(), we have do do the pipe/fork/exec/waitpid/read dance. We could use that to filter the #0 frame showing waidpid() from gstack but meh. This drops the libunwind and addr2line dependency and replaces it with gstack instead. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- .gitlab-ci.yml | 6 +- meson.build | 11 +-- test/litest.c | 188 +++++++++---------------------------------------- 3 files changed, 38 insertions(+), 167 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e4f0f649..e683e2252 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -41,9 +41,9 @@ variables: # See the documentation here: # # https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html # ############################################################################### - FEDORA_RPMS: 'git gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark valgrind binutils libwacom-devel cairo-devel gtk3-devel glib2-devel mtdev-devel' - UBUNTU_DEBS: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme valgrind binutils libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev' - ARCH_PKGS: 'git gcc pkgconfig meson check libsystemd libevdev doxygen graphviz python-sphinx python-recommonmark valgrind binutils libwacom gtk3 mtdev ' + FEDORA_RPMS: 'git gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark valgrind libwacom-devel cairo-devel gtk3-devel glib2-devel mtdev-devel' + UBUNTU_DEBS: 'git gcc g++ pkg-config meson check libudev-dev libevdev-dev doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme valgrind libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev' + ARCH_PKGS: 'git gcc pkgconfig meson check libsystemd libevdev doxygen graphviz python-sphinx python-recommonmark valgrind libwacom gtk3 mtdev ' FREEBSD_BUILD_PKGS: 'meson' FREEBSD_PKGS: 'libepoll-shim libudev-devd libevdev libwacom gtk3 libmtdev ' ############################ end of package lists ############################# diff --git a/meson.build b/meson.build index ac631312e..964c50c46 100644 --- a/meson.build +++ b/meson.build @@ -643,18 +643,12 @@ executable('test-build-cxx', if get_option('tests') dep_check = dependency('check', version : '>= 0.9.10') valgrind = find_program('valgrind') - addr2line = find_program('addr2line') - - if addr2line.found() - config_h.set('HAVE_ADDR2LINE', '1') - config_h.set_quoted('ADDR2LINE', addr2line.path()) - endif leftover_rules = find_program('test/check-leftover-udev-rules.sh') test('leftover-rules', leftover_rules, is_parallel : false) - dep_libunwind = dependency('libunwind', required : false) - config_h.set10('HAVE_LIBUNWIND', dep_libunwind.found()) + gstack = find_program('gstack', required : false) + config_h.set10('HAVE_GSTACK', gstack.found()) # for inhibit support during test run dep_libsystemd = dependency('libsystemd', version : '>= 221', required : false) @@ -748,7 +742,6 @@ if get_option('tests') deps_litest = [ dep_libinput, dep_check, - dep_libunwind, dep_udev, dep_libevdev, dep_dl, diff --git a/test/litest.c b/test/litest.c index 5c87db953..06c3a4655 100644 --- a/test/litest.c +++ b/test/litest.c @@ -102,175 +102,53 @@ static inline char *litest_install_quirks(struct list *created_files_list); #define litest_vlog(...) { /* __VA_ARGS__ */ } #endif -#if HAVE_LIBUNWIND -#define UNW_LOCAL_ONLY -#include <libunwind.h> -#include <dlfcn.h> - -static char cwd[PATH_MAX]; - -static bool -litest_backtrace_get_lineno(const char *executable, - unw_word_t addr, - char *file_return, - int *line_return) -{ -#if HAVE_ADDR2LINE - FILE* f; - char buffer[PATH_MAX]; - char *s; - unsigned int i; - - if (!cwd[0]) { - if (getcwd(cwd, sizeof(cwd)) == NULL) - cwd[0] = 0; /* contents otherwise undefined. */ - } - - sprintf (buffer, - ADDR2LINE " -C -e %s -i %lx", - executable, - (unsigned long) addr); - - f = popen(buffer, "r"); - if (f == NULL) { - litest_log("Failed to execute: %s\n", buffer); - return false; - } - - buffer[0] = '?'; - if (fgets(buffer, sizeof(buffer), f) == NULL) { - pclose(f); - return false; - } - pclose(f); - - if (buffer[0] == '?') - return false; - - s = strrchr(buffer, ':'); - if (!s) - return false; - - *s = '\0'; - s++; - sscanf(s, "%d", line_return); - - /* now strip cwd from buffer */ - s = buffer; - i = 0; - while(i < strlen(cwd) && *s != '\0' && cwd[i] == *s) { - *s = '\0'; - s++; - i++; - } - - if (i > 0) - *(--s) = '.'; - strcpy(file_return, s); - - return true; -#else /* HAVE_ADDR2LINE */ - return false; -#endif -} - static void litest_backtrace(void) { - unw_cursor_t cursor; - unw_context_t context; - unw_word_t off; - unw_proc_info_t pip; - int ret; - char procname[256]; - Dl_info dlinfo; +#if HAVE_GSTACK + pid_t parent, child; + int pipefd[2]; - pip.unwind_info = NULL; - ret = unw_getcontext(&context); - if (ret) { - litest_log("unw_getcontext failed: %s [%d]\n", - unw_strerror(ret), - ret); + if (pipe(pipefd) == -1) return; - } - ret = unw_init_local(&cursor, &context); - if (ret) { - litest_log("unw_init_local failed: %s [%d]\n", - unw_strerror(ret), - ret); - return; - } + parent = getpid(); + child = fork(); - litest_log("\nBacktrace:\n"); - ret = unw_step(&cursor); - while (ret > 0) { - char file[PATH_MAX]; - int line; - bool have_lineno = false; - const char *filename = "?"; - int i = 0; + if (child == 0) { + char pid[8]; - ret = unw_get_proc_info(&cursor, &pip); - if (ret) { - litest_log("unw_get_proc_info failed: %s [%d]\n", - unw_strerror(ret), - ret); - break; - } + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); - ret = unw_get_proc_name(&cursor, procname, 256, &off); - if (ret && ret != -UNW_ENOMEM) { - if (ret != -UNW_EUNSPEC) - litest_log("unw_get_proc_name failed: %s [%d]\n", - unw_strerror(ret), - ret); - procname[0] = '?'; - procname[1] = 0; - } + sprintf(pid, "%d", parent); - if (dladdr((void *)(pip.start_ip + off), &dlinfo) && - dlinfo.dli_fname && - *dlinfo.dli_fname) { - filename = dlinfo.dli_fname; - have_lineno = litest_backtrace_get_lineno(filename, - (pip.start_ip + off), - file, - &line); - } + execlp("gstack", "gstack", pid, NULL); + exit(errno); + } - if (have_lineno) { - litest_log("%d: %s() (%s:%d)\n", - i, - procname, - file, - line); - } else { - litest_log("%d: %s (%s%s+%#x) [%p]\n", - i, - filename, - procname, - ret == -UNW_ENOMEM ? "..." : "", - (int)off, - (void *)(pip.start_ip + off)); + /* parent */ + char buf[1024]; + int status, nread; + + close(pipefd[1]); + waitpid(child, &status, 0); + + status = WEXITSTATUS(status); + if (status != 0) { + litest_log("ERROR: gstack failed, no backtrace available: %s\n", + strerror(status)); + } else { + litest_log("\nBacktrace:\n"); + while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) { + buf[nread] = '\0'; + litest_log("%s", buf); } - - i++; - ret = unw_step(&cursor); - if (ret < 0) - litest_log("unw_step failed: %s [%d]\n", - unw_strerror(ret), - ret); + litest_log("\n"); } - litest_log("\n"); -} -#else /* HAVE_LIBUNWIND */ -static inline void -litest_backtrace(void) -{ - /* thou shall install libunwind */ -} + close(pipefd[0]); #endif +} LIBINPUT_ATTRIBUTE_PRINTF(5, 6) __attribute__((noreturn)) -- 2.17.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel