@@ -356,15 +356,18 @@ void TaskTracer::SignalHandler(int, siginfo_t* info, void* context) {
356356 // Ref has been taken before the signal is sent, so no need to add ref here.
357357 butil::intrusive_ptr<SignalSync> signal_sync (
358358 static_cast <SignalSync*>(info->si_value .sival_ptr ), false );
359- if (NULL == signal_sync || NULL == signal_sync-> result ) {
359+ if (NULL == signal_sync) {
360360 // The signal is not from Tracer, such as TaskControl, do nothing.
361361 return ;
362362 }
363- Result* result = signal_sync-> result ;
363+ void *pcs[Result::MAX_TRACE_NUM] ;
364364 // Skip the first frame, which is the signal handler itself.
365- result->frame_count = absl::DefaultStackUnwinder (&result->ips [0 ], NULL ,
366- arraysize (result->ips ),
367- 1 , context, NULL );
365+ int depth = absl::DefaultStackUnwinder (pcs, NULL , arraysize (pcs), 1 ,
366+ context, NULL );
367+ signal_sync->pcs .reserve (depth);
368+ for (int i = 0 ; i < depth; ++i) {
369+ signal_sync->pcs .push_back (pcs[i]);
370+ }
368371 // write() is async-signal-safe.
369372 // Don't care about the return value.
370373 butil::ignore_result (write (signal_sync->pipe_fds [1 ], " 1" , 1 ));
@@ -415,11 +418,9 @@ TaskTracer::Result TaskTracer::SignalTrace(pid_t tid) {
415418
416419 // Each signal trace has an independent SignalSync to
417420 // prevent the previous SignalHandler from affecting the new SignalTrace.
418- Result result;
419- butil::intrusive_ptr<SignalSync> signal_sync (new SignalSync (&result));
421+ butil::intrusive_ptr<SignalSync> signal_sync (new SignalSync ());
420422 if (!signal_sync->Init ()) {
421- result.SetError (" Fail to init SignalSync" );
422- return result;
423+ return Result::MakeErrorResult (" Fail to init SignalSync" );
423424 }
424425
425426 // Add reference for SignalHandler.
@@ -432,8 +433,7 @@ TaskTracer::Result TaskTracer::SignalTrace(pid_t tid) {
432433 if (errno != EAGAIN || sigqueue_try++ >= 3 ) {
433434 // Remove reference for SignalHandler.
434435 signal_sync->RemoveRefManually ();
435- result.SetError (" Fail to sigqueue: %s" , berror ());
436- return result;
436+ return Result::MakeErrorResult (" Fail to sigqueue: %s, tid: %d" , berror (), tid);
437437 }
438438 }
439439 _inuse_signal_syncs.push_back (signal_sync);
@@ -450,8 +450,7 @@ TaskTracer::Result TaskTracer::SignalTrace(pid_t tid) {
450450 if (FLAGS_signal_trace_timeout_ms > 0 ) {
451451 timer.stop ();
452452 if (timer.m_elapsed () >= FLAGS_signal_trace_timeout_ms) {
453- result.SetError (" Timeout exceed %dms" , FLAGS_signal_trace_timeout_ms);
454- break ;
453+ return Result::MakeErrorResult (" Timeout exceed %dms" , FLAGS_signal_trace_timeout_ms);
455454 }
456455 timeout = (int64_t )FLAGS_signal_trace_timeout_ms - timer.m_elapsed ();
457456 }
@@ -462,10 +461,17 @@ TaskTracer::Result TaskTracer::SignalTrace(pid_t tid) {
462461 if (EINTR == errno) {
463462 continue ;
464463 }
465- result. SetError (" Fail to poll: %s" , berror ());
464+ return Result::MakeErrorResult (" Fail to poll: %s" , berror ());
466465 }
467466 break ;
468467 }
468+
469+ Result result;
470+ result.frame_count = signal_sync->pcs .size ();
471+ for (size_t i = 0 ; i < result.frame_count ; ++i) {
472+ result.ips [i] = signal_sync->pcs [i];
473+ }
474+
469475 return result;
470476}
471477
0 commit comments