From e0f671126d485ff1356a0181aa3ab9631268e17b Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 21 Oct 2024 09:16:04 +1000 Subject: [PATCH] util: add the backtrace printing function as separate util Might as well make this easier to re-use since it doesn't do anything specific to litest. Part-of: --- meson.build | 1 + src/util-backtrace.h | 79 ++++++++++++++++++++++++++++++++++++++++++++ test/litest.c | 48 +++------------------------ 3 files changed, 85 insertions(+), 43 deletions(-) create mode 100644 src/util-backtrace.h diff --git a/meson.build b/meson.build index ecb63c48..aac0ea9b 100644 --- a/meson.build +++ b/meson.build @@ -255,6 +255,7 @@ endif # Basic compilation test to make sure the headers include and define all the # necessary bits. util_headers = [ + 'util-backtrace.h', 'util-bits.h', 'util-input-event.h', 'util-list.h', diff --git a/src/util-backtrace.h b/src/util-backtrace.h new file mode 100644 index 00000000..27f7b1fc --- /dev/null +++ b/src/util-backtrace.h @@ -0,0 +1,79 @@ +/* + * Copyright © 2024 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +static inline void +backtrace_print(FILE *fp) +{ +#if HAVE_GSTACK + pid_t parent, child; + int pipefd[2]; + + if (pipe(pipefd) == -1) + return; + + parent = getpid(); + child = fork(); + + if (child == 0) { + char pid[8]; + + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + + sprintf(pid, "%d", parent); + + execlp("gstack", "gstack", pid, NULL); + exit(errno); + } + + /* parent */ + char buf[1024]; + int status, nread; + + close(pipefd[1]); + waitpid(child, &status, 0); + + status = WEXITSTATUS(status); + if (status != 0) { + fprintf(fp, "ERROR: gstack failed, no backtrace available: %s\n", + strerror(status)); + } else { + fprintf(fp, "\nBacktrace:\n"); + while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) { + buf[nread] = '\0'; + fprintf(stderr, "%s", buf); + } + fprintf(fp, "\n"); + } + close(pipefd[0]); +#endif +} diff --git a/test/litest.c b/test/litest.c index bb649569..eb4d983f 100644 --- a/test/litest.c +++ b/test/litest.c @@ -63,6 +63,8 @@ #include "quirks.h" #include "builddir.h" +#include "util-backtrace.h" + #include #define evbit(t, c) ((t) << 16U | (c & 0xffff)) @@ -151,53 +153,13 @@ _litest_checkpoint(const char *func, static void litest_backtrace(void) { -#if HAVE_GSTACK - pid_t parent, child; - int pipefd[2]; - +#ifndef LITEST_DISABLE_BACKTRACE_LOGGING if (RUNNING_ON_VALGRIND) { - litest_log(" Using valgrind, omitting backtrace\n"); + fprintf(stderr, "Using valgrind, omitting backtrace\n"); return; } - if (pipe(pipefd) == -1) - return; - - parent = getpid(); - child = fork(); - - if (child == 0) { - char pid[8]; - - close(pipefd[0]); - dup2(pipefd[1], STDOUT_FILENO); - - sprintf(pid, "%d", parent); - - execlp("gstack", "gstack", pid, NULL); - exit(errno); - } - - /* 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); - } - litest_log("\n"); - } - close(pipefd[0]); + backtrace_print(stderr); #endif } -- 2.34.1