Skip to content

Commit

Permalink
libspl: lift backtrace into a separate file
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Rob Norris <[email protected]>
Closes openzfs#16181
(cherry picked from commit 3974ef0)
  • Loading branch information
robn committed Jul 17, 2024
1 parent cb2743d commit 87b954a
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 58 deletions.
3 changes: 2 additions & 1 deletion cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#include <sys/brt_impl.h>
#include <zfs_comutil.h>
#include <sys/zstd/zstd.h>
#include <sys/backtrace.h>

#include <libnvpair.h>
#include <libzutil.h>
Expand Down Expand Up @@ -942,7 +943,7 @@ static void sig_handler(int signo)
{
struct sigaction action;

libspl_dump_backtrace();
libspl_backtrace();
dump_debug_buffer();

/*
Expand Down
3 changes: 2 additions & 1 deletion cmd/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
#include <libzutil.h>
#include <sys/crypto/icp.h>
#include <sys/zfs_impl.h>
#include <sys/backtrace.h>

static int ztest_fd_data = -1;
static int ztest_fd_rand = -1;
Expand Down Expand Up @@ -598,7 +599,7 @@ static void sig_handler(int signo)
{
struct sigaction action;

libspl_dump_backtrace();
libspl_backtrace();
dump_debug_buffer();

/*
Expand Down
3 changes: 2 additions & 1 deletion lib/libspl/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
55 changes: 2 additions & 53 deletions lib/libspl/assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <assert.h>
#include <pthread.h>
#include <sys/backtrace.h>

#if defined(__linux__)
#include <errno.h>
Expand All @@ -51,58 +52,6 @@
pthread_getname_np(pthread_self(), buf, len);
#endif

#if defined(HAVE_LIBUNWIND)
#define UNW_LOCAL_ONLY
#include <libunwind.h>

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 <execinfo.h>

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)
Expand Down Expand Up @@ -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) {
Expand Down
80 changes: 80 additions & 0 deletions lib/libspl/backtrace.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 2024, Klara Inc.
*/

#include <sys/backtrace.h>
#include <stdio.h>

#if defined(HAVE_LIBUNWIND)
#define UNW_LOCAL_ONLY
#include <libunwind.h>

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 <execinfo.h>

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

1 change: 1 addition & 0 deletions lib/libspl/include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
2 changes: 0 additions & 2 deletions lib/libspl/include/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions lib/libspl/include/sys/backtrace.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* Copyright (c) 2024, Klara Inc.
*/

#ifndef _LIBSPL_SYS_BACKTRACE_H
#define _LIBSPL_SYS_BACKTRACE_H

void libspl_backtrace(void);

#endif

0 comments on commit 87b954a

Please sign in to comment.