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

Reply via email to