From 3974ef045ef270e72be6ca1d20baf67bfbecfbe5 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Fri, 10 May 2024 11:26:11 +1000 Subject: [PATCH] libspl: lift backtrace into a separate file If it's going to be used directly by zdb/ztest, then it sort of doesn't make sense to carry it with the assert code. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf Signed-off-by: Rob Norris Closes #16181 --- cmd/zdb/zdb.c | 3 +- cmd/ztest.c | 3 +- lib/libnvpair/libnvpair.abi | 111 +++++++++++++++++++++++++++-- lib/libspl/Makefile.am | 3 +- lib/libspl/assert.c | 55 +------------- lib/libspl/backtrace.c | 80 +++++++++++++++++++++ lib/libspl/include/Makefile.am | 1 + lib/libspl/include/assert.h | 2 - lib/libspl/include/sys/backtrace.h | 32 +++++++++ lib/libuutil/libuutil.abi | 85 ++++++++++++++++++++-- lib/libzfs/libzfs.abi | 41 ++++++++++- lib/libzfs_core/libzfs_core.abi | 89 ++++++++++++++++++++--- 12 files changed, 426 insertions(+), 79 deletions(-) create mode 100644 lib/libspl/backtrace.c create mode 100644 lib/libspl/include/sys/backtrace.h diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 908e4e0ab..01d584844 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -85,6 +85,7 @@ #include #include #include +#include #include #include @@ -844,7 +845,7 @@ static void sig_handler(int signo) { struct sigaction action; - libspl_dump_backtrace(); + libspl_backtrace(); dump_debug_buffer(); /* diff --git a/cmd/ztest.c b/cmd/ztest.c index ccfe71c29..d6f22d04a 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -136,6 +136,7 @@ #include #include #include +#include static int ztest_fd_data = -1; static int ztest_fd_rand = -1; @@ -622,7 +623,7 @@ static void sig_handler(int signo) { struct sigaction action; - libspl_dump_backtrace(); + libspl_backtrace(); dump_debug_buffer(); /* diff --git a/lib/libnvpair/libnvpair.abi b/lib/libnvpair/libnvpair.abi index ef92f3e9b..69009375e 100644 --- a/lib/libnvpair/libnvpair.abi +++ b/lib/libnvpair/libnvpair.abi @@ -79,6 +79,7 @@ + @@ -1156,6 +1157,11 @@ + + + + + @@ -2041,9 +2047,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2051,11 +2125,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2536,11 +2642,6 @@ - - - - - diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am index 94be416d4..f8943572b 100644 --- a/lib/libspl/Makefile.am +++ b/lib/libspl/Makefile.am @@ -7,7 +7,8 @@ noinst_LTLIBRARIES += libspl_assert.la libspl.la CPPCHECKTARGETS += libspl_assert.la libspl.la libspl_assert_la_SOURCES = \ - %D%/assert.c + %D%/assert.c \ + %D%/backtrace.c libspl_la_SOURCES = \ %D%/libspl_impl.h \ diff --git a/lib/libspl/assert.c b/lib/libspl/assert.c index 79b640d89..ff0d17ba2 100644 --- a/lib/libspl/assert.c +++ b/lib/libspl/assert.c @@ -28,6 +28,7 @@ #include #include +#include #if defined(__linux__) #include @@ -51,58 +52,6 @@ pthread_getname_np(pthread_self(), buf, len); #endif -#if defined(HAVE_LIBUNWIND) -#define UNW_LOCAL_ONLY -#include - -void -libspl_dump_backtrace(void) -{ - unw_context_t uc; - unw_cursor_t cp; - unw_word_t ip, off; - char funcname[128]; -#ifdef HAVE_LIBUNWIND_ELF - char objname[128]; - unw_word_t objoff; -#endif - - fprintf(stderr, "Call trace:\n"); - unw_getcontext(&uc); - unw_init_local(&cp, &uc); - while (unw_step(&cp) > 0) { - unw_get_reg(&cp, UNW_REG_IP, &ip); - unw_get_proc_name(&cp, funcname, sizeof (funcname), &off); -#ifdef HAVE_LIBUNWIND_ELF - unw_get_elf_filename(&cp, objname, sizeof (objname), &objoff); - fprintf(stderr, " [0x%08lx] %s+0x%2lx (in %s +0x%2lx)\n", - ip, funcname, off, objname, objoff); -#else - fprintf(stderr, " [0x%08lx] %s+0x%2lx\n", ip, funcname, off); -#endif - } -} -#elif defined(HAVE_BACKTRACE) -#include - -void -libspl_dump_backtrace(void) -{ - void *btptrs[100]; - size_t nptrs = backtrace(btptrs, 100); - char **bt = backtrace_symbols(btptrs, nptrs); - fprintf(stderr, "Call trace:\n"); - for (size_t i = 0; i < nptrs; i++) - fprintf(stderr, " %s\n", bt[i]); - free(bt); -} -#else -void -libspl_dump_backtrace(void) -{ -} -#endif - #if defined(__APPLE__) static inline uint64_t libspl_gettid(void) @@ -154,7 +103,7 @@ libspl_assertf(const char *file, const char *func, int line, getpid(), libspl_getprogname(), libspl_gettid(), tname); - libspl_dump_backtrace(); + libspl_backtrace(); #if !__has_feature(attribute_analyzer_noreturn) && !defined(__COVERITY__) if (libspl_assert_ok) { diff --git a/lib/libspl/backtrace.c b/lib/libspl/backtrace.c new file mode 100644 index 000000000..0e653cd96 --- /dev/null +++ b/lib/libspl/backtrace.c @@ -0,0 +1,80 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2024, Rob Norris + * Copyright (c) 2024, Klara Inc. + */ + +#include +#include + +#if defined(HAVE_LIBUNWIND) +#define UNW_LOCAL_ONLY +#include + +void +libspl_backtrace(void) +{ + unw_context_t uc; + unw_cursor_t cp; + unw_word_t ip, off; + char funcname[128]; +#ifdef HAVE_LIBUNWIND_ELF + char objname[128]; + unw_word_t objoff; +#endif + + fprintf(stderr, "Call trace:\n"); + unw_getcontext(&uc); + unw_init_local(&cp, &uc); + while (unw_step(&cp) > 0) { + unw_get_reg(&cp, UNW_REG_IP, &ip); + unw_get_proc_name(&cp, funcname, sizeof (funcname), &off); +#ifdef HAVE_LIBUNWIND_ELF + unw_get_elf_filename(&cp, objname, sizeof (objname), &objoff); + fprintf(stderr, " [0x%08lx] %s+0x%2lx (in %s +0x%2lx)\n", + ip, funcname, off, objname, objoff); +#else + fprintf(stderr, " [0x%08lx] %s+0x%2lx\n", ip, funcname, off); +#endif + } +} +#elif defined(HAVE_BACKTRACE) +#include + +void +libspl_backtrace(void) +{ + void *btptrs[100]; + size_t nptrs = backtrace(btptrs, 100); + char **bt = backtrace_symbols(btptrs, nptrs); + fprintf(stderr, "Call trace:\n"); + for (size_t i = 0; i < nptrs; i++) + fprintf(stderr, " %s\n", bt[i]); + free(bt); +} +#else +void +libspl_backtrace(void) +{ +} +#endif + diff --git a/lib/libspl/include/Makefile.am b/lib/libspl/include/Makefile.am index 2c1d21edf..4ad3b854c 100644 --- a/lib/libspl/include/Makefile.am +++ b/lib/libspl/include/Makefile.am @@ -27,6 +27,7 @@ libspl_sys_HEADERS = \ %D%/sys/acl.h \ %D%/sys/acl_impl.h \ %D%/sys/asm_linkage.h \ + %D%/sys/backtrace.h \ %D%/sys/callb.h \ %D%/sys/cmn_err.h \ %D%/sys/cred.h \ diff --git a/lib/libspl/include/assert.h b/lib/libspl/include/assert.h index 126f2db24..155bbab30 100644 --- a/lib/libspl/include/assert.h +++ b/lib/libspl/include/assert.h @@ -60,8 +60,6 @@ libspl_assert(const char *buf, const char *file, const char *func, int line) return (0); } -extern void libspl_dump_backtrace(void); - #ifdef verify #undef verify #endif diff --git a/lib/libspl/include/sys/backtrace.h b/lib/libspl/include/sys/backtrace.h new file mode 100644 index 000000000..97ee7740c --- /dev/null +++ b/lib/libspl/include/sys/backtrace.h @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2024, Rob Norris + * Copyright (c) 2024, Klara Inc. + */ + +#ifndef _LIBSPL_SYS_BACKTRACE_H +#define _LIBSPL_SYS_BACKTRACE_H + +void libspl_backtrace(void); + +#endif diff --git a/lib/libuutil/libuutil.abi b/lib/libuutil/libuutil.abi index e942d24c6..2ed2fb2e4 100644 --- a/lib/libuutil/libuutil.abi +++ b/lib/libuutil/libuutil.abi @@ -149,6 +149,7 @@ + @@ -242,6 +243,22 @@ + + + + + + + + + + + + + + + + @@ -576,6 +593,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -596,14 +634,11 @@ - + - - - - + @@ -800,9 +835,16 @@ + + + + + + + @@ -912,6 +954,25 @@ + + + + + + + + + + + + + + + + + + + @@ -920,12 +981,23 @@ + + + + + + + + + + + @@ -937,8 +1009,9 @@ - + + diff --git a/lib/libzfs/libzfs.abi b/lib/libzfs/libzfs.abi index c3efb2984..80f4b7439 100644 --- a/lib/libzfs/libzfs.abi +++ b/lib/libzfs/libzfs.abi @@ -191,6 +191,7 @@ + @@ -777,6 +778,18 @@ + + + + + + + + + + + + @@ -1092,6 +1105,19 @@ + + + + + + + + + + + + + @@ -6252,6 +6278,11 @@ + + + + + @@ -6363,7 +6394,7 @@ - + @@ -8672,7 +8703,7 @@ - + @@ -8697,6 +8728,12 @@ + + + + + + diff --git a/lib/libzfs_core/libzfs_core.abi b/lib/libzfs_core/libzfs_core.abi index 5b95c8f77..cf9d6bddc 100644 --- a/lib/libzfs_core/libzfs_core.abi +++ b/lib/libzfs_core/libzfs_core.abi @@ -132,6 +132,7 @@ + @@ -231,10 +232,18 @@ + + + + + + + + @@ -242,6 +251,14 @@ + + + + + + + + @@ -574,6 +591,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -594,14 +632,11 @@ - + - - - - + @@ -770,6 +805,13 @@ + + + + + + + @@ -873,12 +915,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -895,8 +967,9 @@ - + + @@ -1119,7 +1192,7 @@ - + @@ -1127,7 +1200,7 @@ - +