forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reland "Reland "Mac: use frame-pointer unwind for macOS 10.14+ and ARM""
This is a reland of 62de5d0 Previous reland didn't include https://chromium-review.googlesource.com/c/chromium/src/+/3465714 Original change's description: > Reland "Mac: use frame-pointer unwind for macOS 10.14+ and ARM" > > This is a reland of 1fe207f > > Fix in patchset 2 > > Original change's description: > > Mac: use frame-pointer unwind for macOS 10.14+ and ARM > > > > This change keeps NativeMacUnwinder for now. In a future change > > (possibly after this bakes), we can backport pthread_stack_frame_decode_np > > and remove it. > > > > For convenience, since I renamed the file, here's a separate diff > > of TryUnwind: https://gist.github.com/speednoisemovement/5545f236ebe674360528895d1ae5c0de > > > > Bug: 1101399, 1102197 > > Change-Id: Id2ca3f8e34d5f91d9adc668831a3f1ea7b46b1ad > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3336376 > > Reviewed-by: David Jean <djean@chromium.org> > > Reviewed-by: Mike Wittman <wittman@chromium.org> > > Reviewed-by: Eric Seckler <eseckler@chromium.org> > > Commit-Queue: Leonard Grey <lgrey@chromium.org> > > Cr-Commit-Position: refs/heads/main@{#971214} > > Bug: 1101399, 1102197 > Change-Id: If8446743a5b82cd54ca620f575c4d0ea4efeab42 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3466814 > Reviewed-by: Mike Wittman <wittman@chromium.org> > Reviewed-by: David Jean <djean@chromium.org> > Reviewed-by: Eric Seckler <eseckler@chromium.org> > Commit-Queue: Leonard Grey <lgrey@chromium.org> > Cr-Commit-Position: refs/heads/main@{#972478} Bug: 1101399, 1102197 Change-Id: Ie40d25a9e2ac67cfe5f314b8d2718f4fd1d23c7f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3472124 Auto-Submit: Leonard Grey <lgrey@chromium.org> Reviewed-by: Mike Wittman <wittman@chromium.org> Reviewed-by: Eric Seckler <eseckler@chromium.org> Commit-Queue: Eric Seckler <eseckler@chromium.org> Cr-Commit-Position: refs/heads/main@{#972861}
- Loading branch information
1 parent
c4f1b84
commit e5cab0e
Showing
15 changed files
with
491 additions
and
207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "base/profiler/native_unwinder_apple.h" | ||
|
||
#include <pthread/stack_np.h> | ||
|
||
#include "base/check_op.h" | ||
#include "base/notreached.h" | ||
#include "base/numerics/clamped_math.h" | ||
#include "base/profiler/module_cache.h" | ||
#include "base/profiler/native_unwinder.h" | ||
#include "build/build_config.h" | ||
|
||
namespace base { | ||
|
||
NativeUnwinderApple::NativeUnwinderApple() = default; | ||
|
||
bool NativeUnwinderApple::CanUnwindFrom(const Frame& current_frame) const { | ||
return current_frame.module && current_frame.module->IsNative(); | ||
} | ||
|
||
UnwindResult NativeUnwinderApple::TryUnwind(RegisterContext* thread_context, | ||
uintptr_t stack_top, | ||
std::vector<Frame>* stack) const { | ||
// We expect the frame corresponding to the |thread_context| register state to | ||
// exist within |stack|. | ||
DCHECK_GT(stack->size(), 0u); | ||
#if defined(ARCH_CPU_ARM64) | ||
constexpr uintptr_t align_mask = 0x1; | ||
#elif defined(ARCH_CPU_X86_64) | ||
constexpr uintptr_t align_mask = 0xf; | ||
#endif | ||
|
||
uintptr_t next_frame = RegisterContextFramePointer(thread_context); | ||
uintptr_t frame_lower_bound = RegisterContextStackPointer(thread_context); | ||
const auto is_fp_valid = [&](uintptr_t fp) { | ||
// Ensure there's space on the stack to read two values: the caller's | ||
// frame pointer and the return address. | ||
return next_frame >= frame_lower_bound && | ||
ClampAdd(next_frame, sizeof(uintptr_t) * 2) <= stack_top && | ||
(next_frame & align_mask) == 0; | ||
}; | ||
if (!is_fp_valid(next_frame)) | ||
return UnwindResult::kAborted; | ||
|
||
for (;;) { | ||
if (!stack->back().module) { | ||
return UnwindResult::kAborted; | ||
} | ||
if (!stack->back().module->IsNative()) { | ||
// This is a non-native module associated with the auxiliary unwinder | ||
// (e.g. corresponding to a frame in V8 generated code). Report as | ||
// UNRECOGNIZED_FRAME to allow that unwinder to unwind the frame. | ||
return UnwindResult::kUnrecognizedFrame; | ||
} | ||
uintptr_t retaddr; | ||
uintptr_t frame = next_frame; | ||
next_frame = pthread_stack_frame_decode_np(frame, &retaddr); | ||
frame_lower_bound = frame + 1; | ||
// If `next_frame` is 0, we've hit the root and `retaddr` isn't useful. | ||
// Bail without recording the frame. | ||
if (next_frame == 0) | ||
return UnwindResult::kCompleted; | ||
const ModuleCache::Module* module = | ||
module_cache()->GetModuleForAddress(retaddr); | ||
// V8 doesn't conform to the x86_64 ABI re: stack alignment. For V8 frames, | ||
// let the V8 unwinder determine whether the FP is valid or not. | ||
bool is_non_native_module = module && !module->IsNative(); | ||
// If the FP doesn't look correct, don't record this frame. | ||
if (!is_non_native_module && !is_fp_valid(next_frame)) | ||
return UnwindResult::kAborted; | ||
|
||
RegisterContextFramePointer(thread_context) = next_frame; | ||
RegisterContextInstructionPointer(thread_context) = retaddr; | ||
RegisterContextStackPointer(thread_context) = frame + sizeof(uintptr_t) * 2; | ||
stack->emplace_back(retaddr, module); | ||
} | ||
|
||
NOTREACHED(); | ||
return UnwindResult::kCompleted; | ||
} | ||
|
||
// Mac version is defined in NativeUnwinderMac | ||
#if BUILDFLAG(IS_IOS) | ||
std::unique_ptr<Unwinder> CreateNativeUnwinder(ModuleCache* module_cache) { | ||
return std::make_unique<NativeUnwinderApple>(); | ||
} | ||
#endif | ||
|
||
} // namespace base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2021 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef BASE_PROFILER_NATIVE_UNWINDER_APPLE_H_ | ||
#define BASE_PROFILER_NATIVE_UNWINDER_APPLE_H_ | ||
|
||
#include <vector> | ||
|
||
#include <os/availability.h> | ||
|
||
#include "base/base_export.h" | ||
#include "base/profiler/unwinder.h" | ||
|
||
namespace base { | ||
|
||
// Native unwinder implementation for iOS, ARM64 and X86_64, and macOS 10.14+. | ||
class BASE_EXPORT API_AVAILABLE(ios(12), macosx(10.14)) NativeUnwinderApple | ||
: public Unwinder { | ||
public: | ||
NativeUnwinderApple(); | ||
|
||
NativeUnwinderApple(const NativeUnwinderApple&) = delete; | ||
NativeUnwinderApple& operator=(const NativeUnwinderApple&) = delete; | ||
|
||
// Unwinder: | ||
bool CanUnwindFrom(const Frame& current_frame) const override; | ||
UnwindResult TryUnwind(RegisterContext* thread_context, | ||
uintptr_t stack_top, | ||
std::vector<Frame>* stack) const override; | ||
}; | ||
|
||
} // namespace base | ||
|
||
#endif // BASE_PROFILER_NATIVE_UNWINDER_APPLE_H_ |
Oops, something went wrong.