[PATCH libinput] test: replace hand-rolled backtrace function with gstack
Peter Hutterer
peter.hutterer at who-t.net
Thu Aug 9 00:03:17 UTC 2018
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.hutterer at 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
More information about the wayland-devel
mailing list