Signal handler for our stack trace signal. We expect that the signal is only sent from DumpThreadStack() -- not by a user.
| 256 | // Signal handler for our stack trace signal. |
| 257 | // We expect that the signal is only sent from DumpThreadStack() -- not by a user. |
| 258 | void HandleStackTraceSignal(int /*signum*/, siginfo_t* info, void* /*ucontext*/) { |
| 259 | // Signal handlers may be invoked at any point, so it's important to preserve |
| 260 | // errno. |
| 261 | int save_errno = errno; |
| 262 | SCOPED_CLEANUP({ |
| 263 | errno = save_errno; |
| 264 | }); |
| 265 | auto* sig_data = reinterpret_cast<SignalData*>(info->si_value.sival_ptr); |
| 266 | DCHECK(sig_data); |
| 267 | if (!sig_data) { |
| 268 | // Maybe the signal was sent by a user instead of by ourself, ignore it. |
| 269 | return; |
| 270 | } |
| 271 | ANNOTATE_HAPPENS_AFTER(sig_data); |
| 272 | int64_t my_tid = Thread::CurrentThreadId(); |
| 273 | |
| 274 | // If we were slow to process the signal, the sender may have given up and |
| 275 | // no longer wants our stack trace. In that case, the 'sig' object will |
| 276 | // no longer contain our thread. |
| 277 | if (!sig_data->queued_to_tid.compare_exchange_strong(my_tid, SignalData::kDumpStarted)) { |
| 278 | return; |
| 279 | } |
| 280 | // Marking it as kDumpStarted ensures that the caller thread must now wait |
| 281 | // for our response, since we are writing directly into their StackTrace object. |
| 282 | sig_data->stack->Collect(/*skip_frames=*/1); |
| 283 | sig_data->result_ready.Signal(); |
| 284 | } |
| 285 | |
| 286 | bool InitSignalHandlerUnlocked(int signum) { |
| 287 | enum InitState { |