25
25
26
26
#include <sys/backtrace.h>
27
27
#include <sys/types.h>
28
+ #include <sys/debug.h>
28
29
#include <unistd.h>
29
30
30
31
/*
31
- * libspl_backtrace() must be safe to call from inside a signal hander. This
32
- * mostly means it must not allocate, and so we can't use things like printf.
32
+ * Output helpers. libspl_backtrace() must not block, must be thread-safe and
33
+ * must be safe to call from a signal handler. At least, that means not having
34
+ * printf, so we end up having to call write() directly on the fd. That's
35
+ * awkward, as we always have to pass through a length, and some systems will
36
+ * complain if we don't consume the return. So we have some macros to make
37
+ * things a little more palatable.
33
38
*/
39
+ #define spl_bt_write_n (fd , s , n ) \
40
+ do { ssize_t r __maybe_unused = write(fd, s, n); } while (0)
41
+ #define spl_bt_write (fd , s ) spl_bt_write_n(fd, s, sizeof (s))
34
42
35
43
#if defined(HAVE_LIBUNWIND )
36
44
#define UNW_LOCAL_ONLY
@@ -62,7 +70,6 @@ libspl_u64_to_hex_str(uint64_t v, size_t digits, char *buf, size_t buflen)
62
70
void
63
71
libspl_backtrace (int fd )
64
72
{
65
- ssize_t ret __attribute__((unused ));
66
73
unw_context_t uc ;
67
74
unw_cursor_t cp ;
68
75
unw_word_t v ;
@@ -72,7 +79,7 @@ libspl_backtrace(int fd)
72
79
unw_getcontext (& uc );
73
80
74
81
unw_init_local (& cp , & uc );
75
- ret = write (fd , "Registers:\n" , 11 );
82
+ spl_bt_write (fd , "Registers:\n" );
76
83
c = 0 ;
77
84
for (uint_t regnum = 0 ; regnum <= UNW_TDEP_LAST_REG ; regnum ++ ) {
78
85
if (unw_get_reg (& cp , regnum , & v ) < 0 )
@@ -85,42 +92,42 @@ libspl_backtrace(int fd)
85
92
& buf [1 ], sizeof (buf )- 1 ) + 1 ;
86
93
name = buf ;
87
94
}
88
- ret = write (fd , " " , 5 - MIN (n , 3 ));
89
- ret = write (fd , name , n );
90
- ret = write (fd , ": 0x" , 4 );
95
+ spl_bt_write_n (fd , " " , 5 - MIN (n , 3 ));
96
+ spl_bt_write_n (fd , name , n );
97
+ spl_bt_write (fd , ": 0x" );
91
98
n = libspl_u64_to_hex_str (v , 18 , buf , sizeof (buf ));
92
- ret = write (fd , buf , n );
99
+ spl_bt_write_n (fd , buf , n );
93
100
if (!(++ c % 3 ))
94
- ret = write (fd , "\n" , 1 );
101
+ spl_bt_write (fd , "\n" );
95
102
}
96
103
if (c % 3 )
97
- ret = write (fd , "\n" , 1 );
104
+ spl_bt_write (fd , "\n" );
98
105
99
106
unw_init_local (& cp , & uc );
100
- ret = write (fd , "Call trace:\n" , 12 );
107
+ spl_bt_write (fd , "Call trace:\n" );
101
108
while (unw_step (& cp ) > 0 ) {
102
109
unw_get_reg (& cp , UNW_REG_IP , & v );
103
- ret = write (fd , " [0x" , 5 );
110
+ spl_bt_write (fd , " [0x" );
104
111
n = libspl_u64_to_hex_str (v , 18 , buf , sizeof (buf ));
105
- ret = write (fd , buf , n );
106
- ret = write (fd , "] " , 2 );
112
+ spl_bt_write_n (fd , buf , n );
113
+ spl_bt_write (fd , "] " );
107
114
unw_get_proc_name (& cp , buf , sizeof (buf ), & v );
108
115
for (n = 0 ; n < sizeof (buf ) && buf [n ] != '\0' ; n ++ ) {}
109
- ret = write (fd , buf , n );
110
- ret = write (fd , "+0x" , 3 );
116
+ spl_bt_write_n (fd , buf , n );
117
+ spl_bt_write (fd , "+0x" );
111
118
n = libspl_u64_to_hex_str (v , 2 , buf , sizeof (buf ));
112
- ret = write (fd , buf , n );
119
+ spl_bt_write_n (fd , buf , n );
113
120
#ifdef HAVE_LIBUNWIND_ELF
114
- ret = write (fd , " (in " , 5 );
121
+ spl_bt_write (fd , " (in " );
115
122
unw_get_elf_filename (& cp , buf , sizeof (buf ), & v );
116
123
for (n = 0 ; n < sizeof (buf ) && buf [n ] != '\0' ; n ++ ) {}
117
- ret = write (fd , buf , n );
118
- ret = write (fd , " +0x" , 4 );
124
+ spl_bt_write_n (fd , buf , n );
125
+ spl_bt_write (fd , " +0x" );
119
126
n = libspl_u64_to_hex_str (v , 2 , buf , sizeof (buf ));
120
- ret = write (fd , buf , n );
121
- ret = write (fd , ")" , 1 );
127
+ spl_bt_write_n (fd , buf , n );
128
+ spl_bt_write (fd , ")" );
122
129
#endif
123
- ret = write (fd , "\n" , 1 );
130
+ spl_bt_write (fd , "\n" );
124
131
}
125
132
}
126
133
#elif defined(HAVE_BACKTRACE )
@@ -129,15 +136,12 @@ libspl_backtrace(int fd)
129
136
void
130
137
libspl_backtrace (int fd )
131
138
{
132
- ssize_t ret __attribute__((unused ));
133
139
void * btptrs [64 ];
134
140
size_t nptrs = backtrace (btptrs , 64 );
135
- ret = write (fd , "Call trace:\n" , 12 );
141
+ spl_bt_write (fd , "Call trace:\n" );
136
142
backtrace_symbols_fd (btptrs , nptrs , fd );
137
143
}
138
144
#else
139
- #include <sys/debug.h>
140
-
141
145
void
142
146
libspl_backtrace (int fd __maybe_unused )
143
147
{
0 commit comments