Revert "[ios] Added stack_sample_profiler iOS flavor (x86_64 and ARM64)"
This reverts commit d281d7561e
.
Reason for revert: Cronet failures
Original change's description:
> [ios] Added stack_sample_profiler iOS flavor (x86_64 and ARM64)
>
> Added iOS version of stack unwinder that relies on frames
> using pthread_stack_frame_decode_np.
>
> Bug: 1199722
> Change-Id: Ifce3fdccc20bb5104eb1516ae30d714eb7ba1f79
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2831597
> Reviewed-by: Mike Wittman <wittman@chromium.org>
> Commit-Queue: David Jean <djean@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#892015}
Bug: 1199722
Change-Id: I9290505fcf24e49b3bc51893d23f1bbfc41a8e8e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2961109
Owners-Override: Adam Trudeau-Arcaro <adamta@google.com>
Reviewed-by: Adam Trudeau-Arcaro <adamta@google.com>
Reviewed-by: Justin Cohen <justincohen@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#892091}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
547364d2eb
commit
7f930032a3
@ -1195,11 +1195,7 @@ component("base") {
|
|||||||
"process/launch_ios.cc",
|
"process/launch_ios.cc",
|
||||||
"process/process_metrics_ios.cc",
|
"process/process_metrics_ios.cc",
|
||||||
"profiler/module_cache_mac.cc",
|
"profiler/module_cache_mac.cc",
|
||||||
"profiler/native_unwinder_ios.cc",
|
|
||||||
"profiler/native_unwinder_ios.h",
|
|
||||||
"profiler/stack_sampler_ios.cc",
|
"profiler/stack_sampler_ios.cc",
|
||||||
"profiler/suspendable_thread_delegate_mac.cc",
|
|
||||||
"profiler/suspendable_thread_delegate_mac.h",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
// 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_ios.h"
|
|
||||||
|
|
||||||
#include <pthread/stack_np.h>
|
|
||||||
|
|
||||||
#include "base/check_op.h"
|
|
||||||
#include "base/notreached.h"
|
|
||||||
#include "base/profiler/module_cache.h"
|
|
||||||
#include "base/profiler/native_unwinder.h"
|
|
||||||
#include "build/build_config.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
|
|
||||||
NativeUnwinderIOS::NativeUnwinderIOS() {}
|
|
||||||
|
|
||||||
bool NativeUnwinderIOS::CanUnwindFrom(const Frame& current_frame) const {
|
|
||||||
return current_frame.module && current_frame.module->IsNative();
|
|
||||||
}
|
|
||||||
|
|
||||||
UnwindResult NativeUnwinderIOS::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)
|
|
||||||
const uintptr_t align_mask = 0x1;
|
|
||||||
const uintptr_t stack_bottom = thread_context->__sp;
|
|
||||||
uintptr_t next_frame = thread_context->__fp;
|
|
||||||
#elif defined(ARCH_CPU_X86_64)
|
|
||||||
const uintptr_t align_mask = 0xf;
|
|
||||||
const uintptr_t stack_bottom = thread_context->__rsp;
|
|
||||||
uintptr_t next_frame = thread_context->__rbp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
uintptr_t retaddr;
|
|
||||||
uintptr_t frame = next_frame;
|
|
||||||
next_frame = pthread_stack_frame_decode_np(frame, &retaddr);
|
|
||||||
|
|
||||||
if (frame < stack_bottom || frame > stack_top ||
|
|
||||||
(frame & align_mask) != 0 || next_frame <= frame) {
|
|
||||||
return UnwindResult::COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack->emplace_back(retaddr, module_cache()->GetModuleForAddress(retaddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
NOTREACHED();
|
|
||||||
return UnwindResult::COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Unwinder> CreateNativeUnwinder(ModuleCache* module_cache) {
|
|
||||||
return std::make_unique<NativeUnwinderIOS>();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace base
|
|
@ -1,29 +0,0 @@
|
|||||||
// 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_IOS_H_
|
|
||||||
#define BASE_PROFILER_NATIVE_UNWINDER_IOS_H_
|
|
||||||
|
|
||||||
#include "base/profiler/unwinder.h"
|
|
||||||
|
|
||||||
namespace base {
|
|
||||||
|
|
||||||
// Native unwinder implementation for iOS, ARM64 and X86_64.
|
|
||||||
class NativeUnwinderIOS : public Unwinder {
|
|
||||||
public:
|
|
||||||
NativeUnwinderIOS();
|
|
||||||
|
|
||||||
NativeUnwinderIOS(const NativeUnwinderIOS&) = delete;
|
|
||||||
NativeUnwinderIOS& operator=(const NativeUnwinderIOS&) = 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_IOS_H_
|
|
@ -69,7 +69,7 @@ inline uintptr_t& RegisterContextInstructionPointer(::CONTEXT* context) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(OS_MAC) || defined(OS_IOS) // #if defined(OS_WIN)
|
#elif defined(OS_MAC) // #if defined(OS_WIN)
|
||||||
|
|
||||||
#if defined(ARCH_CPU_X86_64)
|
#if defined(ARCH_CPU_X86_64)
|
||||||
using RegisterContext = x86_thread_state64_t;
|
using RegisterContext = x86_thread_state64_t;
|
||||||
|
@ -1,29 +1,14 @@
|
|||||||
// Copyright 2021 The Chromium Authors. All rights reserved.
|
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
// Placeholder functions for the StackSampler on iOS, which is not currently
|
||||||
|
// supported.
|
||||||
|
|
||||||
#include "base/profiler/stack_sampler.h"
|
#include "base/profiler/stack_sampler.h"
|
||||||
|
|
||||||
#include "base/bind.h"
|
|
||||||
#include "base/check.h"
|
|
||||||
#include "base/profiler/native_unwinder_ios.h"
|
|
||||||
#include "base/profiler/stack_copier_suspend.h"
|
|
||||||
#include "base/profiler/stack_sampler_impl.h"
|
|
||||||
#include "base/profiler/suspendable_thread_delegate_mac.h"
|
|
||||||
#include "build/build_config.h"
|
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Unwinder>> CreateUnwinders() {
|
|
||||||
std::vector<std::unique_ptr<Unwinder>> unwinders;
|
|
||||||
unwinders.push_back(std::make_unique<NativeUnwinderIOS>());
|
|
||||||
return unwinders;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
std::unique_ptr<StackSampler> StackSampler::Create(
|
std::unique_ptr<StackSampler> StackSampler::Create(
|
||||||
SamplingProfilerThreadToken thread_token,
|
SamplingProfilerThreadToken thread_token,
|
||||||
@ -31,21 +16,12 @@ std::unique_ptr<StackSampler> StackSampler::Create(
|
|||||||
UnwindersFactory core_unwinders_factory,
|
UnwindersFactory core_unwinders_factory,
|
||||||
RepeatingClosure record_sample_callback,
|
RepeatingClosure record_sample_callback,
|
||||||
StackSamplerTestDelegate* test_delegate) {
|
StackSamplerTestDelegate* test_delegate) {
|
||||||
DCHECK(!core_unwinders_factory);
|
return nullptr;
|
||||||
return std::make_unique<StackSamplerImpl>(
|
|
||||||
std::make_unique<StackCopierSuspend>(
|
|
||||||
std::make_unique<SuspendableThreadDelegateMac>(thread_token)),
|
|
||||||
BindOnce(&CreateUnwinders), module_cache,
|
|
||||||
std::move(record_sample_callback), test_delegate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
size_t StackSampler::GetStackBufferSize() {
|
size_t StackSampler::GetStackBufferSize() {
|
||||||
size_t stack_size = PlatformThread::GetDefaultThreadStackSize();
|
return 0;
|
||||||
|
|
||||||
// If getrlimit somehow fails, return the default iOS main thread stack size
|
|
||||||
// of 1 MB with extra wiggle room.
|
|
||||||
return stack_size > 0 ? stack_size : 1536 * 1024;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
|
|
||||||
// STACK_SAMPLING_PROFILER_SUPPORTED is used to conditionally enable the tests
|
// STACK_SAMPLING_PROFILER_SUPPORTED is used to conditionally enable the tests
|
||||||
// below for supported platforms (currently Win x64 and Mac x64).
|
// below for supported platforms (currently Win x64 and Mac x64).
|
||||||
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
|
#if (defined(OS_WIN) && defined(ARCH_CPU_X86_64)) || \
|
||||||
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || (defined(OS_IOS)) || \
|
(defined(OS_MAC) && defined(ARCH_CPU_X86_64)) || \
|
||||||
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
|
(defined(OS_ANDROID) && BUILDFLAG(ENABLE_ARM_CFI_TABLE))
|
||||||
#define STACK_SAMPLING_PROFILER_SUPPORTED 1
|
#define STACK_SAMPLING_PROFILER_SUPPORTED 1
|
||||||
#endif
|
#endif
|
||||||
@ -507,13 +507,12 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
|
|||||||
// Checks that a stack that runs through another library produces a stack with
|
// Checks that a stack that runs through another library produces a stack with
|
||||||
// the expected functions.
|
// the expected functions.
|
||||||
// macOS ASAN is not yet supported - crbug.com/718628.
|
// macOS ASAN is not yet supported - crbug.com/718628.
|
||||||
// iOS chrome doesn't support loading native libraries.
|
|
||||||
// Android is not supported when EXCLUDE_UNWIND_TABLES |other_library| doesn't
|
// Android is not supported when EXCLUDE_UNWIND_TABLES |other_library| doesn't
|
||||||
// have unwind tables.
|
// have unwind tables.
|
||||||
// TODO(https://crbug.com/1100175): Enable this test again for Android with
|
// TODO(https://crbug.com/1100175): Enable this test again for Android with
|
||||||
// ASAN. This is now disabled because the android-asan bot fails.
|
// ASAN. This is now disabled because the android-asan bot fails.
|
||||||
#if (defined(ADDRESS_SANITIZER) && defined(OS_APPLE)) || defined(OS_IOS) || \
|
#if (defined(ADDRESS_SANITIZER) && defined(OS_APPLE)) || \
|
||||||
(defined(OS_ANDROID) && BUILDFLAG(EXCLUDE_UNWIND_TABLES)) || \
|
(defined(OS_ANDROID) && BUILDFLAG(EXCLUDE_UNWIND_TABLES)) || \
|
||||||
(defined(OS_ANDROID) && defined(ADDRESS_SANITIZER))
|
(defined(OS_ANDROID) && defined(ADDRESS_SANITIZER))
|
||||||
#define MAYBE_OtherLibrary DISABLED_OtherLibrary
|
#define MAYBE_OtherLibrary DISABLED_OtherLibrary
|
||||||
#else
|
#else
|
||||||
@ -553,8 +552,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) {
|
|||||||
// produces a stack, and doesn't crash.
|
// produces a stack, and doesn't crash.
|
||||||
// macOS ASAN is not yet supported - crbug.com/718628.
|
// macOS ASAN is not yet supported - crbug.com/718628.
|
||||||
// Android is not supported since modules are found before unwinding.
|
// Android is not supported since modules are found before unwinding.
|
||||||
#if (defined(ADDRESS_SANITIZER) && defined(OS_APPLE)) || \
|
#if (defined(ADDRESS_SANITIZER) && defined(OS_APPLE)) || defined(OS_ANDROID)
|
||||||
defined(OS_ANDROID) || defined(OS_IOS)
|
|
||||||
#define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
|
#define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
|
||||||
#else
|
#else
|
||||||
#define MAYBE_UnloadedLibrary UnloadedLibrary
|
#define MAYBE_UnloadedLibrary UnloadedLibrary
|
||||||
|
@ -24,22 +24,17 @@ namespace base {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#if defined(ARCH_CPU_X86_64)
|
|
||||||
constexpr mach_msg_type_number_t kThreadStateCount = x86_THREAD_STATE64_COUNT;
|
|
||||||
constexpr thread_state_flavor_t kThreadStateFlavor = x86_THREAD_STATE64;
|
|
||||||
#elif defined(ARCH_CPU_ARM64)
|
|
||||||
constexpr mach_msg_type_number_t kThreadStateCount = ARM_THREAD_STATE64_COUNT;
|
|
||||||
constexpr thread_state_flavor_t kThreadStateFlavor = ARM_THREAD_STATE64;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Fills |state| with |target_thread|'s context. NO HEAP ALLOCATIONS.
|
// Fills |state| with |target_thread|'s context. NO HEAP ALLOCATIONS.
|
||||||
bool GetThreadContextImpl(thread_act_t target_thread, RegisterContext* state) {
|
bool GetThreadContextImpl(thread_act_t target_thread, RegisterContext* state) {
|
||||||
auto count = kThreadStateCount;
|
// TODO(wittman): Implement the unwinder for Mac arm.
|
||||||
return thread_get_state(target_thread, kThreadStateFlavor,
|
#if !defined(ARCH_CPU_ARM64)
|
||||||
|
auto count = static_cast<mach_msg_type_number_t>(x86_THREAD_STATE64_COUNT);
|
||||||
|
return thread_get_state(target_thread, x86_THREAD_STATE64,
|
||||||
reinterpret_cast<thread_state_t>(state),
|
reinterpret_cast<thread_state_t>(state),
|
||||||
&count) == KERN_SUCCESS;
|
&count) == KERN_SUCCESS;
|
||||||
|
#else // !defined(ARCH_CPU_ARM64)
|
||||||
return false;
|
return false;
|
||||||
|
#endif // !defined(ARCH_CPU_ARM64)
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -112,28 +107,15 @@ bool SuspendableThreadDelegateMac::CanCopyStack(uintptr_t stack_pointer) {
|
|||||||
|
|
||||||
std::vector<uintptr_t*> SuspendableThreadDelegateMac::GetRegistersToRewrite(
|
std::vector<uintptr_t*> SuspendableThreadDelegateMac::GetRegistersToRewrite(
|
||||||
RegisterContext* thread_context) {
|
RegisterContext* thread_context) {
|
||||||
#if defined(ARCH_CPU_X86_64)
|
#if !defined(ARCH_CPU_ARM64)
|
||||||
return {
|
return {
|
||||||
&AsUintPtr(&thread_context->__rbx), &AsUintPtr(&thread_context->__rbp),
|
&AsUintPtr(&thread_context->__rbx), &AsUintPtr(&thread_context->__rbp),
|
||||||
&AsUintPtr(&thread_context->__rsp), &AsUintPtr(&thread_context->__r12),
|
&AsUintPtr(&thread_context->__rsp), &AsUintPtr(&thread_context->__r12),
|
||||||
&AsUintPtr(&thread_context->__r13), &AsUintPtr(&thread_context->__r14),
|
&AsUintPtr(&thread_context->__r13), &AsUintPtr(&thread_context->__r14),
|
||||||
&AsUintPtr(&thread_context->__r15)};
|
&AsUintPtr(&thread_context->__r15)};
|
||||||
#elif defined(ARCH_CPU_ARM64) // defined(ARCH_CPU_X86_64)
|
#else // !defined(ARCH_CPU_ARM64)
|
||||||
return {
|
return {};
|
||||||
&AsUintPtr(&thread_context->__fp),
|
#endif // !defined(ARCH_CPU_ARM64)
|
||||||
&AsUintPtr(&thread_context->__sp),
|
|
||||||
&AsUintPtr(&thread_context->__x[19]),
|
|
||||||
&AsUintPtr(&thread_context->__x[20]),
|
|
||||||
&AsUintPtr(&thread_context->__x[21]),
|
|
||||||
&AsUintPtr(&thread_context->__x[22]),
|
|
||||||
&AsUintPtr(&thread_context->__x[23]),
|
|
||||||
&AsUintPtr(&thread_context->__x[24]),
|
|
||||||
&AsUintPtr(&thread_context->__x[25]),
|
|
||||||
&AsUintPtr(&thread_context->__x[26]),
|
|
||||||
&AsUintPtr(&thread_context->__x[27]),
|
|
||||||
&AsUintPtr(&thread_context->__x[28]),
|
|
||||||
};
|
|
||||||
#endif // defined(ARCH_CPU_ARM64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
// Platform- and thread-specific implementation in support of stack sampling on
|
// Platform- and thread-specific implementation in support of stack sampling on
|
||||||
// Mac (X86_64) and iOS (X86_64 and ARM64).
|
// Mac.
|
||||||
class BASE_EXPORT SuspendableThreadDelegateMac
|
class BASE_EXPORT SuspendableThreadDelegateMac
|
||||||
: public SuspendableThreadDelegate {
|
: public SuspendableThreadDelegate {
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user