|
25 | 25 |
|
26 | 26 | #include <seastar/core/internal/cpu_profiler.hh> |
27 | 27 | #include <seastar/core/scheduling.hh> |
| 28 | +#include <seastar/core/thread_impl.hh> |
28 | 29 | #include <seastar/util/log.hh> |
29 | 30 |
|
30 | 31 | namespace seastar { |
@@ -117,13 +118,20 @@ void cpu_profiler::on_signal() { |
117 | 118 | // is currently being unwound and avoid taking a profiling sample if so. |
118 | 119 | // |
119 | 120 | // Note: this only protects against C++ exceptions, therefore foreign |
120 | | - // exceptions or long jumps could still cause segfaults within the profiler. |
| 121 | + // exceptions could still cause segfaults within the profiler. |
121 | 122 | const bool no_uncaught_exceptions = std::uncaught_exceptions() == 0; |
122 | 123 |
|
123 | 124 | if (force_drop_stacktraces) { |
124 | 125 | _stats.dropped_samples_from_manual_disablement++; |
125 | 126 | } else if (!no_uncaught_exceptions) { |
126 | 127 | _stats.dropped_samples_from_exceptions++; |
| 128 | + } else if (thread_impl::is_context_switch_in_progress()) { |
| 129 | + // While a seastar::thread switches stacks the register state is |
| 130 | + // inconsistent with the unwind info (glibc's swapcontext/longjmp |
| 131 | + // clobber the link register on aarch64 while their CFI still claims |
| 132 | + // the return address lives there), so backtracing from here would |
| 133 | + // walk garbage frames and can crash in libgcc's unwinder. |
| 134 | + _stats.dropped_samples_from_context_switches++; |
127 | 135 | } else if (auto guard_opt = _traces_mutex.try_lock(); guard_opt.has_value()) { |
128 | 136 | // Skip the sample if the main thread is currently reading |
129 | 137 | // _traces. This case shouldn't happen often though. |
|
0 commit comments