xref: /aosp_15_r20/external/cronet/base/profiler/stack_copier_signal.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/profiler/stack_copier_signal.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <errno.h>
8*6777b538SAndroid Build Coastguard Worker #include <linux/futex.h>
9*6777b538SAndroid Build Coastguard Worker #include <signal.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker #include <sys/ucontext.h>
12*6777b538SAndroid Build Coastguard Worker #include <syscall.h>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include <atomic>
15*6777b538SAndroid Build Coastguard Worker #include <cstring>
16*6777b538SAndroid Build Coastguard Worker #include <optional>
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/profiler/register_context.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/profiler/stack_buffer.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/profiler/suspendable_thread_delegate.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/time/time_override.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/base_tracing.h"
26*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker namespace base {
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker namespace {
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker // Waitable event implementation with futex and without DCHECK(s), since signal
33*6777b538SAndroid Build Coastguard Worker // handlers cannot allocate memory or use pthread api.
34*6777b538SAndroid Build Coastguard Worker class AsyncSafeWaitableEvent {
35*6777b538SAndroid Build Coastguard Worker  public:
AsyncSafeWaitableEvent()36*6777b538SAndroid Build Coastguard Worker   AsyncSafeWaitableEvent() {
37*6777b538SAndroid Build Coastguard Worker     futex_.store(kNotSignaled, std::memory_order_release);
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker   ~AsyncSafeWaitableEvent() = default;
40*6777b538SAndroid Build Coastguard Worker   AsyncSafeWaitableEvent(const AsyncSafeWaitableEvent&) = delete;
41*6777b538SAndroid Build Coastguard Worker   AsyncSafeWaitableEvent& operator=(const AsyncSafeWaitableEvent&) = delete;
42*6777b538SAndroid Build Coastguard Worker 
Wait()43*6777b538SAndroid Build Coastguard Worker   bool Wait() {
44*6777b538SAndroid Build Coastguard Worker     // futex() can wake up spuriously if this memory address was previously used
45*6777b538SAndroid Build Coastguard Worker     // for a pthread mutex or we get a signal. So, also check the condition.
46*6777b538SAndroid Build Coastguard Worker     while (true) {
47*6777b538SAndroid Build Coastguard Worker       long res =
48*6777b538SAndroid Build Coastguard Worker           syscall(SYS_futex, futex_ptr(), FUTEX_WAIT | FUTEX_PRIVATE_FLAG,
49*6777b538SAndroid Build Coastguard Worker                   kNotSignaled, nullptr, nullptr, 0);
50*6777b538SAndroid Build Coastguard Worker       int futex_errno = errno;
51*6777b538SAndroid Build Coastguard Worker       if (futex_.load(std::memory_order_acquire) != kNotSignaled) {
52*6777b538SAndroid Build Coastguard Worker         return true;
53*6777b538SAndroid Build Coastguard Worker       }
54*6777b538SAndroid Build Coastguard Worker       if (res != 0) {
55*6777b538SAndroid Build Coastguard Worker         // EINTR indicates the wait was interrupted by a signal; retry the wait.
56*6777b538SAndroid Build Coastguard Worker         // EAGAIN happens if this thread sees the FUTEX_WAKE before it sees the
57*6777b538SAndroid Build Coastguard Worker         // atomic_int store in Signal. This can't happen in an unoptimized
58*6777b538SAndroid Build Coastguard Worker         // single total modification order threading model; however, since we
59*6777b538SAndroid Build Coastguard Worker         // using release-acquire semantics on the atomic_uint32_t, it might be.
60*6777b538SAndroid Build Coastguard Worker         // (The futex docs aren't clear what memory/threading model they are
61*6777b538SAndroid Build Coastguard Worker         // using.)
62*6777b538SAndroid Build Coastguard Worker         if (futex_errno != EINTR && futex_errno != EAGAIN) {
63*6777b538SAndroid Build Coastguard Worker           return false;
64*6777b538SAndroid Build Coastguard Worker         }
65*6777b538SAndroid Build Coastguard Worker       }
66*6777b538SAndroid Build Coastguard Worker     }
67*6777b538SAndroid Build Coastguard Worker   }
68*6777b538SAndroid Build Coastguard Worker 
Signal()69*6777b538SAndroid Build Coastguard Worker   void Signal() {
70*6777b538SAndroid Build Coastguard Worker     futex_.store(kSignaled, std::memory_order_release);
71*6777b538SAndroid Build Coastguard Worker     syscall(SYS_futex, futex_ptr(), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, nullptr,
72*6777b538SAndroid Build Coastguard Worker             nullptr, 0);
73*6777b538SAndroid Build Coastguard Worker   }
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker  private:
76*6777b538SAndroid Build Coastguard Worker   // The possible values in the futex / atomic_int.
77*6777b538SAndroid Build Coastguard Worker   static constexpr uint32_t kNotSignaled = 0;
78*6777b538SAndroid Build Coastguard Worker   static constexpr uint32_t kSignaled = 1;
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   // Provides a pointer to the atomic's storage. std::atomic_uint32_t has
81*6777b538SAndroid Build Coastguard Worker   // standard layout so its address can be used for the pointer as long as it
82*6777b538SAndroid Build Coastguard Worker   // only contains the uint32_t.
futex_ptr()83*6777b538SAndroid Build Coastguard Worker   uint32_t* futex_ptr() {
84*6777b538SAndroid Build Coastguard Worker     // futex documents state the futex is 32 bits regardless of the platform
85*6777b538SAndroid Build Coastguard Worker     // size.
86*6777b538SAndroid Build Coastguard Worker     static_assert(sizeof(futex_) == sizeof(uint32_t),
87*6777b538SAndroid Build Coastguard Worker                   "Expected std::atomic_uint32_t to be the same size as "
88*6777b538SAndroid Build Coastguard Worker                   "uint32_t");
89*6777b538SAndroid Build Coastguard Worker     return reinterpret_cast<uint32_t*>(&futex_);
90*6777b538SAndroid Build Coastguard Worker   }
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   std::atomic_uint32_t futex_{kNotSignaled};
93*6777b538SAndroid Build Coastguard Worker };
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker // Scoped signal event that calls Signal on the AsyncSafeWaitableEvent at
96*6777b538SAndroid Build Coastguard Worker // destructor.
97*6777b538SAndroid Build Coastguard Worker class ScopedEventSignaller {
98*6777b538SAndroid Build Coastguard Worker  public:
ScopedEventSignaller(AsyncSafeWaitableEvent * event)99*6777b538SAndroid Build Coastguard Worker   ScopedEventSignaller(AsyncSafeWaitableEvent* event) : event_(event) {}
~ScopedEventSignaller()100*6777b538SAndroid Build Coastguard Worker   ~ScopedEventSignaller() { event_->Signal(); }
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker  private:
103*6777b538SAndroid Build Coastguard Worker   // RAW_PTR_EXCLUSION: raw_ptr<> is not safe within a signal handler.
104*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION AsyncSafeWaitableEvent* event_;
105*6777b538SAndroid Build Coastguard Worker };
106*6777b538SAndroid Build Coastguard Worker 
107*6777b538SAndroid Build Coastguard Worker // Struct to store the arguments to the signal handler.
108*6777b538SAndroid Build Coastguard Worker struct HandlerParams {
109*6777b538SAndroid Build Coastguard Worker   uintptr_t stack_base_address;
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   // RAW_PTR_EXCLUSION: raw_ptr<> is not safe within a signal handler,
112*6777b538SAndroid Build Coastguard Worker   // as the target thread could be in the middle of an allocation and
113*6777b538SAndroid Build Coastguard Worker   // PartitionAlloc's external invariants might be violated. So all
114*6777b538SAndroid Build Coastguard Worker   // the pointers below are C pointers.
115*6777b538SAndroid Build Coastguard Worker 
116*6777b538SAndroid Build Coastguard Worker   // The event is signalled when signal handler is done executing.
117*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION AsyncSafeWaitableEvent* event;
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // Return values:
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   // Successfully copied the stack segment.
122*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION bool* success;
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker   // The thread context of the leaf function.
125*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION mcontext_t* context;
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker   // Buffer to copy the stack segment.
128*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION StackBuffer* stack_buffer;
129*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION const uint8_t** stack_copy_bottom;
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   // The timestamp when the stack was copied.
132*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION std::optional<TimeTicks>* maybe_timestamp;
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   // The delegate provided to the StackCopier.
135*6777b538SAndroid Build Coastguard Worker   RAW_PTR_EXCLUSION StackCopier::Delegate* stack_copier_delegate;
136*6777b538SAndroid Build Coastguard Worker };
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker // Pointer to the parameters to be "passed" to the CopyStackSignalHandler() from
139*6777b538SAndroid Build Coastguard Worker // the sampling thread to the sampled (stopped) thread. This value is set just
140*6777b538SAndroid Build Coastguard Worker // before sending the signal to the thread and reset when the handler is done.
141*6777b538SAndroid Build Coastguard Worker std::atomic<HandlerParams*> g_handler_params;
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker // CopyStackSignalHandler is invoked on the stopped thread and records the
144*6777b538SAndroid Build Coastguard Worker // thread's stack and register context at the time the signal was received. This
145*6777b538SAndroid Build Coastguard Worker // function may only call reentrant code.
CopyStackSignalHandler(int n,siginfo_t * siginfo,void * sigcontext)146*6777b538SAndroid Build Coastguard Worker void CopyStackSignalHandler(int n, siginfo_t* siginfo, void* sigcontext) {
147*6777b538SAndroid Build Coastguard Worker   HandlerParams* params = g_handler_params.load(std::memory_order_acquire);
148*6777b538SAndroid Build Coastguard Worker 
149*6777b538SAndroid Build Coastguard Worker   // MaybeTimeTicksNowIgnoringOverride() is implemented in terms of
150*6777b538SAndroid Build Coastguard Worker   // clock_gettime on Linux, which is signal safe per the signal-safety(7) man
151*6777b538SAndroid Build Coastguard Worker   // page, but is not garanteed to succeed, in which case std::nullopt is
152*6777b538SAndroid Build Coastguard Worker   // returned. TimeTicks::Now() can't be used because it expects clock_gettime
153*6777b538SAndroid Build Coastguard Worker   // to always succeed and is thus not signal-safe.
154*6777b538SAndroid Build Coastguard Worker   *params->maybe_timestamp = subtle::MaybeTimeTicksNowIgnoringOverride();
155*6777b538SAndroid Build Coastguard Worker 
156*6777b538SAndroid Build Coastguard Worker   ScopedEventSignaller e(params->event);
157*6777b538SAndroid Build Coastguard Worker   *params->success = false;
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   const ucontext_t* ucontext = static_cast<ucontext_t*>(sigcontext);
160*6777b538SAndroid Build Coastguard Worker   std::memcpy(params->context, &ucontext->uc_mcontext, sizeof(mcontext_t));
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   const uintptr_t bottom = RegisterContextStackPointer(params->context);
163*6777b538SAndroid Build Coastguard Worker   const uintptr_t top = params->stack_base_address;
164*6777b538SAndroid Build Coastguard Worker   if ((top - bottom) > params->stack_buffer->size()) {
165*6777b538SAndroid Build Coastguard Worker     // The stack exceeds the size of the allocated buffer. The buffer is sized
166*6777b538SAndroid Build Coastguard Worker     // such that this shouldn't happen under typical execution so we can safely
167*6777b538SAndroid Build Coastguard Worker     // punt in this situation.
168*6777b538SAndroid Build Coastguard Worker     return;
169*6777b538SAndroid Build Coastguard Worker   }
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   params->stack_copier_delegate->OnStackCopy();
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   *params->stack_copy_bottom =
174*6777b538SAndroid Build Coastguard Worker       StackCopierSignal::CopyStackContentsAndRewritePointers(
175*6777b538SAndroid Build Coastguard Worker           reinterpret_cast<uint8_t*>(bottom), reinterpret_cast<uintptr_t*>(top),
176*6777b538SAndroid Build Coastguard Worker           StackBuffer::kPlatformStackAlignment, params->stack_buffer->buffer());
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   *params->success = true;
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker // Sets the global handler params for the signal handler function.
182*6777b538SAndroid Build Coastguard Worker class ScopedSetSignalHandlerParams {
183*6777b538SAndroid Build Coastguard Worker  public:
ScopedSetSignalHandlerParams(HandlerParams * params)184*6777b538SAndroid Build Coastguard Worker   ScopedSetSignalHandlerParams(HandlerParams* params) {
185*6777b538SAndroid Build Coastguard Worker     g_handler_params.store(params, std::memory_order_release);
186*6777b538SAndroid Build Coastguard Worker   }
187*6777b538SAndroid Build Coastguard Worker 
~ScopedSetSignalHandlerParams()188*6777b538SAndroid Build Coastguard Worker   ~ScopedSetSignalHandlerParams() {
189*6777b538SAndroid Build Coastguard Worker     g_handler_params.store(nullptr, std::memory_order_release);
190*6777b538SAndroid Build Coastguard Worker   }
191*6777b538SAndroid Build Coastguard Worker };
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker class ScopedSigaction {
194*6777b538SAndroid Build Coastguard Worker  public:
ScopedSigaction(int signal,struct sigaction * action,struct sigaction * original_action)195*6777b538SAndroid Build Coastguard Worker   ScopedSigaction(int signal,
196*6777b538SAndroid Build Coastguard Worker                   struct sigaction* action,
197*6777b538SAndroid Build Coastguard Worker                   struct sigaction* original_action)
198*6777b538SAndroid Build Coastguard Worker       : signal_(signal),
199*6777b538SAndroid Build Coastguard Worker         action_(action),
200*6777b538SAndroid Build Coastguard Worker         original_action_(original_action),
201*6777b538SAndroid Build Coastguard Worker         succeeded_(sigaction(signal, action, original_action) == 0) {}
202*6777b538SAndroid Build Coastguard Worker 
succeeded() const203*6777b538SAndroid Build Coastguard Worker   bool succeeded() const { return succeeded_; }
204*6777b538SAndroid Build Coastguard Worker 
~ScopedSigaction()205*6777b538SAndroid Build Coastguard Worker   ~ScopedSigaction() {
206*6777b538SAndroid Build Coastguard Worker     if (!succeeded_)
207*6777b538SAndroid Build Coastguard Worker       return;
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker     bool reset_succeeded = sigaction(signal_, original_action_, action_) == 0;
210*6777b538SAndroid Build Coastguard Worker     DCHECK(reset_succeeded);
211*6777b538SAndroid Build Coastguard Worker   }
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker  private:
214*6777b538SAndroid Build Coastguard Worker   const int signal_;
215*6777b538SAndroid Build Coastguard Worker   const raw_ptr<struct sigaction> action_;
216*6777b538SAndroid Build Coastguard Worker   const raw_ptr<struct sigaction> original_action_;
217*6777b538SAndroid Build Coastguard Worker   const bool succeeded_;
218*6777b538SAndroid Build Coastguard Worker };
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker }  // namespace
221*6777b538SAndroid Build Coastguard Worker 
StackCopierSignal(std::unique_ptr<ThreadDelegate> thread_delegate)222*6777b538SAndroid Build Coastguard Worker StackCopierSignal::StackCopierSignal(
223*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<ThreadDelegate> thread_delegate)
224*6777b538SAndroid Build Coastguard Worker     : thread_delegate_(std::move(thread_delegate)) {}
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker StackCopierSignal::~StackCopierSignal() = default;
227*6777b538SAndroid Build Coastguard Worker 
CopyStack(StackBuffer * stack_buffer,uintptr_t * stack_top,TimeTicks * timestamp,RegisterContext * thread_context,Delegate * delegate)228*6777b538SAndroid Build Coastguard Worker bool StackCopierSignal::CopyStack(StackBuffer* stack_buffer,
229*6777b538SAndroid Build Coastguard Worker                                   uintptr_t* stack_top,
230*6777b538SAndroid Build Coastguard Worker                                   TimeTicks* timestamp,
231*6777b538SAndroid Build Coastguard Worker                                   RegisterContext* thread_context,
232*6777b538SAndroid Build Coastguard Worker                                   Delegate* delegate) {
233*6777b538SAndroid Build Coastguard Worker   AsyncSafeWaitableEvent wait_event;
234*6777b538SAndroid Build Coastguard Worker   bool copied = false;
235*6777b538SAndroid Build Coastguard Worker   const uint8_t* stack_copy_bottom = nullptr;
236*6777b538SAndroid Build Coastguard Worker   const uintptr_t stack_base_address = thread_delegate_->GetStackBaseAddress();
237*6777b538SAndroid Build Coastguard Worker   std::optional<TimeTicks> maybe_timestamp;
238*6777b538SAndroid Build Coastguard Worker   HandlerParams params = {stack_base_address, &wait_event,  &copied,
239*6777b538SAndroid Build Coastguard Worker                           thread_context,     stack_buffer, &stack_copy_bottom,
240*6777b538SAndroid Build Coastguard Worker                           &maybe_timestamp,   delegate};
241*6777b538SAndroid Build Coastguard Worker   {
242*6777b538SAndroid Build Coastguard Worker     ScopedSetSignalHandlerParams scoped_handler_params(&params);
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker     // Set the signal handler for the thread to the stack copy function.
245*6777b538SAndroid Build Coastguard Worker     struct sigaction action;
246*6777b538SAndroid Build Coastguard Worker     struct sigaction original_action;
247*6777b538SAndroid Build Coastguard Worker     memset(&action, 0, sizeof(action));
248*6777b538SAndroid Build Coastguard Worker     action.sa_sigaction = CopyStackSignalHandler;
249*6777b538SAndroid Build Coastguard Worker     action.sa_flags = SA_RESTART | SA_SIGINFO;
250*6777b538SAndroid Build Coastguard Worker     sigemptyset(&action.sa_mask);
251*6777b538SAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug"),
252*6777b538SAndroid Build Coastguard Worker                        "StackCopierSignal copy stack");
253*6777b538SAndroid Build Coastguard Worker     // SIGURG is chosen here because we observe no crashes with this signal and
254*6777b538SAndroid Build Coastguard Worker     // neither Chrome or the AOSP sets up a special handler for this signal.
255*6777b538SAndroid Build Coastguard Worker     ScopedSigaction scoped_sigaction(SIGURG, &action, &original_action);
256*6777b538SAndroid Build Coastguard Worker     if (!scoped_sigaction.succeeded())
257*6777b538SAndroid Build Coastguard Worker       return false;
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker     if (syscall(SYS_tgkill, getpid(), thread_delegate_->GetThreadId(),
260*6777b538SAndroid Build Coastguard Worker                 SIGURG) != 0) {
261*6777b538SAndroid Build Coastguard Worker       NOTREACHED();
262*6777b538SAndroid Build Coastguard Worker       return false;
263*6777b538SAndroid Build Coastguard Worker     }
264*6777b538SAndroid Build Coastguard Worker     bool finished_waiting = wait_event.Wait();
265*6777b538SAndroid Build Coastguard Worker     TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug"),
266*6777b538SAndroid Build Coastguard Worker                      "StackCopierSignal copy stack");
267*6777b538SAndroid Build Coastguard Worker     if (!finished_waiting) {
268*6777b538SAndroid Build Coastguard Worker       NOTREACHED();
269*6777b538SAndroid Build Coastguard Worker       return false;
270*6777b538SAndroid Build Coastguard Worker     }
271*6777b538SAndroid Build Coastguard Worker     // Ideally, an accurate timestamp is captured while the sampled thread is
272*6777b538SAndroid Build Coastguard Worker     // paused. In rare cases, this may fail, in which case we resort to
273*6777b538SAndroid Build Coastguard Worker     // capturing an delayed timestamp here instead.
274*6777b538SAndroid Build Coastguard Worker     if (maybe_timestamp.has_value())
275*6777b538SAndroid Build Coastguard Worker       *timestamp = maybe_timestamp.value();
276*6777b538SAndroid Build Coastguard Worker     else {
277*6777b538SAndroid Build Coastguard Worker       TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cpu_profiler.debug"),
278*6777b538SAndroid Build Coastguard Worker                    "Fallback on TimeTicks::Now()");
279*6777b538SAndroid Build Coastguard Worker       *timestamp = TimeTicks::Now();
280*6777b538SAndroid Build Coastguard Worker     }
281*6777b538SAndroid Build Coastguard Worker   }
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   const uintptr_t bottom = RegisterContextStackPointer(params.context);
284*6777b538SAndroid Build Coastguard Worker   for (uintptr_t* reg :
285*6777b538SAndroid Build Coastguard Worker        thread_delegate_->GetRegistersToRewrite(thread_context)) {
286*6777b538SAndroid Build Coastguard Worker     *reg = StackCopierSignal::RewritePointerIfInOriginalStack(
287*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<uint8_t*>(bottom),
288*6777b538SAndroid Build Coastguard Worker         reinterpret_cast<uintptr_t*>(stack_base_address), stack_copy_bottom,
289*6777b538SAndroid Build Coastguard Worker         *reg);
290*6777b538SAndroid Build Coastguard Worker   }
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   *stack_top = reinterpret_cast<uintptr_t>(stack_copy_bottom) +
293*6777b538SAndroid Build Coastguard Worker                (stack_base_address - bottom);
294*6777b538SAndroid Build Coastguard Worker 
295*6777b538SAndroid Build Coastguard Worker   return copied;
296*6777b538SAndroid Build Coastguard Worker }
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker }  // namespace base
299