| 467 | } |
| 468 | |
| 469 | Status StackTraceCollector::AwaitCollection(MonoTime deadline) { |
| 470 | CHECK(sig_data_) << "Must successfully call TriggerAsync() first"; |
| 471 | |
| 472 | // We give the thread ~1s to respond. In testing, threads typically respond within |
| 473 | // a few milliseconds, so this timeout is very conservative. |
| 474 | // |
| 475 | // The main reason that a thread would not respond is that it has blocked signals. For |
| 476 | // example, glibc's timer_thread doesn't respond to our signal, so we always time out |
| 477 | // on that one. |
| 478 | ignore_result(sig_data_->result_ready.WaitUntil(deadline)); |
| 479 | |
| 480 | // Whether or not we timed out above, revoke the signal data structure. |
| 481 | // It's possible that the above 'Wait' times out but it succeeds exactly |
| 482 | // after that timeout. In that case, RevokeSigData() will return true |
| 483 | // and we can return a successful result, because the destination stack trace |
| 484 | // has in fact been populated. |
| 485 | bool completed = RevokeSigData(); |
| 486 | if (!completed) { |
| 487 | return Status::TimedOut("thread did not respond: maybe it is blocking signals"); |
| 488 | } |
| 489 | |
| 490 | return Status::OK(); |
| 491 | } |
| 492 | |
| 493 | #else // #ifdef __linux__ ... |
| 494 | Status StackTraceCollector::TriggerAsync(int64_t tid_, StackTrace* stack) { |