Skip to content

Commit 9934c39

Browse files
authored
feat: make bthread stack trace signal number configurable (#3124)
1 parent ef82950 commit 9934c39

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

src/bthread/task_control.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,7 @@ void TaskControl::stop_and_join() {
426426
for (auto worker: _workers) {
427427
// Interrupt blocking operations.
428428
#ifdef BRPC_BTHREAD_TRACER
429-
// TaskTracer has registered signal handler for SIGURG.
430-
pthread_kill(worker, SIGURG);
429+
pthread_kill(worker, _task_tracer.get_trace_signal());
431430
#else
432431
interrupt_pthread(worker);
433432
#endif // BRPC_BTHREAD_TRACER

src/bthread/task_tracer.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ namespace bthread {
3535

3636
DEFINE_uint32(signal_trace_timeout_ms, 50, "Timeout for signal trace in ms");
3737
BUTIL_VALIDATE_GFLAG(signal_trace_timeout_ms, butil::PositiveInteger<uint32_t>);
38+
// Note that SIGURG handler may be registered by some library such as cgo
39+
// so let the signal number be configurable
40+
DEFINE_int32(signal_number_for_trace, SIGURG,
41+
"signal number used for stack trace, default to SIGURG");
3842

3943
extern BAIDU_THREAD_LOCAL TaskMeta* pthread_fake_meta;
4044

@@ -315,17 +319,19 @@ TaskTracer::Result TaskTracer::TraceByLibunwind(unw_cursor_t& cursor) {
315319

316320
bool TaskTracer::RegisterSignalHandler() {
317321
// Set up the signal handler.
322+
_signal_num = FLAGS_signal_number_for_trace;
318323
struct sigaction old_sa{};
319324
struct sigaction sa{};
320325
sa.sa_sigaction = SignalHandler;
321326
sa.sa_flags = SA_SIGINFO;
322327
sigfillset(&sa.sa_mask);
323-
if (sigaction(SIGURG, &sa, &old_sa) != 0) {
328+
if (sigaction(_signal_num, &sa, &old_sa) != 0) {
324329
PLOG(ERROR) << "Failed to sigaction";
325330
return false;
326331
}
327332
if (NULL != old_sa.sa_handler || NULL != old_sa.sa_sigaction) {
328-
LOG(ERROR) << "Signal handler of SIGURG is already registered";
333+
LOG(ERROR) << "Signal handler of signal number "
334+
<< _signal_num << " is already registered";
329335
return false;
330336
}
331337

@@ -403,7 +409,7 @@ TaskTracer::Result TaskTracer::SignalTrace(pthread_t worker_tid) {
403409
sigval value{};
404410
value.sival_ptr = signal_sync.get();
405411
size_t sigqueue_try = 0;
406-
while (pthread_sigqueue(worker_tid, SIGURG, value) != 0) {
412+
while (pthread_sigqueue(worker_tid, _signal_num, value) != 0) {
407413
if (errno != EAGAIN || sigqueue_try++ >= 3) {
408414
// Remove reference for SignalHandler.
409415
signal_sync->RemoveRefManually();

src/bthread/task_tracer.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class TaskTracer {
4949
// When the worker is jumping stack from a bthread to another,
5050
static void WaitForTracing(TaskMeta* m);
5151

52+
int get_trace_signal() const {
53+
return _signal_num;
54+
}
5255
private:
5356
// Error number guard used in signal handler.
5457
class ErrnoGuard {
@@ -100,7 +103,7 @@ class TaskTracer {
100103
Result ContextTrace(bthread_fcontext_t fcontext);
101104
static Result TraceByLibunwind(unw_cursor_t& cursor);
102105

103-
static bool RegisterSignalHandler();
106+
bool RegisterSignalHandler();
104107
static void SignalHandler(int sig, siginfo_t* info, void* context);
105108
Result SignalTrace(pthread_t worker_tid);
106109

@@ -115,6 +118,7 @@ class TaskTracer {
115118
std::vector<butil::intrusive_ptr<SignalSync>> _inuse_signal_syncs;
116119

117120
bvar::LatencyRecorder _trace_time{"bthread_trace_time"};
121+
int _signal_num{SIGURG};
118122
};
119123

120124
} // namespace bthread

test/brpc_builtin_service_unittest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,19 @@ DECLARE_bool(rpcz_hex_log_id);
6666
DECLARE_int32(idle_timeout_second);
6767
} // namespace rpc
6868

69+
#ifdef BRPC_BTHREAD_TRACER
70+
namespace bthread {
71+
DECLARE_int32(signal_number_for_trace);
72+
}
73+
#endif
74+
6975
int main(int argc, char* argv[]) {
7076
brpc::FLAGS_idle_timeout_second = 0;
7177
testing::InitGoogleTest(&argc, argv);
78+
#ifdef BRPC_BTHREAD_TRACER
79+
// test using signal number other than SIGURG
80+
bthread::FLAGS_signal_number_for_trace = SIGUSR2;
81+
#endif
7282
return RUN_ALL_TESTS();
7383
}
7484

0 commit comments

Comments
 (0)