Commit 8a5edc91 authored by Mike Wittman's avatar Mike Wittman Committed by Commit Bot

[Sampling profiler] Fix GetStackBaseAddress() logic

pthread_attr_getstack returns the lowest address in the stack allocation,
so the size must be added to get the base address.

Also adds logic to cache the main thread base address to avoid performance
overhead on Android. This is modeled after similar logic in GetStackEnd()
in base/debug/stack_trace.cc.

Bug: 988579
Change-Id: Ia31b85afafc98b61dc60eb2c0d0ab64ba70877c2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869831
Commit-Queue: Mike Wittman <wittman@chromium.org>
Reviewed-by: default avatarCharlie Andrews <charliea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709076}
parent c96d45b5
......@@ -4,6 +4,7 @@
#include <pthread.h>
#include "base/process/process_handle.h"
#include "base/profiler/thread_delegate_posix.h"
#include "build/build_config.h"
......@@ -12,13 +13,31 @@ namespace base {
namespace {
uintptr_t GetThreadStackBaseAddress(pthread_t pthread_id) {
uintptr_t GetThreadStackBaseAddressImpl(
SamplingProfilerThreadToken thread_token) {
pthread_attr_t attr;
pthread_getattr_np(pthread_id, &attr);
void* base_address;
pthread_getattr_np(thread_token.pthread_id, &attr);
// See crbug.com/617730 for limitations of this approach on Linux.
void* address;
size_t size;
pthread_attr_getstack(&attr, &base_address, &size);
return reinterpret_cast<uintptr_t>(base_address);
pthread_attr_getstack(&attr, &address, &size);
const uintptr_t base_address = reinterpret_cast<uintptr_t>(address) + size;
return base_address;
}
uintptr_t GetThreadStackBaseAddress(SamplingProfilerThreadToken thread_token) {
#if defined(OS_ANDROID)
// Caches the main thread base address on Android since Bionic has to read
// /proc/$PID/maps to obtain it. Other thread base addresses are sourced from
// pthread state so are cheap to get.
const bool is_main_thread = thread_token.id == GetCurrentProcId();
if (is_main_thread) {
static const uintptr_t main_thread_base_address =
GetThreadStackBaseAddressImpl(thread_token);
return main_thread_base_address;
}
#endif
return GetThreadStackBaseAddressImpl(thread_token);
}
} // namespace
......@@ -26,8 +45,7 @@ uintptr_t GetThreadStackBaseAddress(pthread_t pthread_id) {
ThreadDelegatePosix::ThreadDelegatePosix(
SamplingProfilerThreadToken thread_token)
: thread_id_(thread_token.id),
thread_stack_base_address_(
GetThreadStackBaseAddress(thread_token.pthread_id)) {}
thread_stack_base_address_(GetThreadStackBaseAddress(thread_token)) {}
PlatformThreadId ThreadDelegatePosix::GetThreadId() const {
return thread_id_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment