summaryrefslogtreecommitdiff
path: root/chromium/base/profiler
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-24 11:30:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-30 12:56:19 +0000
commit6036726eb981b6c4b42047513b9d3f4ac865daac (patch)
tree673593e70678e7789766d1f732eb51f613a2703b /chromium/base/profiler
parent466052c4e7c052268fd931888cd58961da94c586 (diff)
downloadqtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/base/profiler')
-rw-r--r--chromium/base/profiler/native_stack_sampler.h4
-rw-r--r--chromium/base/profiler/native_stack_sampler_mac.cc175
-rw-r--r--chromium/base/profiler/native_stack_sampler_win.cc103
-rw-r--r--chromium/base/profiler/stack_sampling_profiler.cc141
-rw-r--r--chromium/base/profiler/stack_sampling_profiler.h184
-rw-r--r--chromium/base/profiler/stack_sampling_profiler_unittest.cc99
-rw-r--r--chromium/base/profiler/win32_stack_frame_unwinder.cc2
7 files changed, 155 insertions, 553 deletions
diff --git a/chromium/base/profiler/native_stack_sampler.h b/chromium/base/profiler/native_stack_sampler.h
index 5d7e9b07715..381b5ef2d1c 100644
--- a/chromium/base/profiler/native_stack_sampler.h
+++ b/chromium/base/profiler/native_stack_sampler.h
@@ -62,8 +62,8 @@ class NativeStackSampler {
// Notifies the sampler that we're starting to record a new profile.
virtual void ProfileRecordingStarting() = 0;
- // Records a set of internal frames and returns them.
- virtual std::vector<StackSamplingProfiler::InternalFrame> RecordStackFrames(
+ // Records a set of frames and returns them.
+ virtual std::vector<StackSamplingProfiler::Frame> RecordStackFrames(
StackBuffer* stackbuffer,
StackSamplingProfiler::ProfileBuilder* profile_builder) = 0;
diff --git a/chromium/base/profiler/native_stack_sampler_mac.cc b/chromium/base/profiler/native_stack_sampler_mac.cc
index d45c7a8c836..e11f1bdd211 100644
--- a/chromium/base/profiler/native_stack_sampler_mac.cc
+++ b/chromium/base/profiler/native_stack_sampler_mac.cc
@@ -25,6 +25,7 @@
#include "base/mac/mach_logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/sampling_heap_profiler/module_cache.h"
#include "base/strings/string_number_conversions.h"
extern "C" {
@@ -34,94 +35,10 @@ void _sigtramp(int, int, struct sigset*);
namespace base {
using Frame = StackSamplingProfiler::Frame;
-using InternalFrame = StackSamplingProfiler::InternalFrame;
-using Module = StackSamplingProfiler::Module;
-using InternalModule = StackSamplingProfiler::InternalModule;
using ProfileBuilder = StackSamplingProfiler::ProfileBuilder;
namespace {
-// ModuleCacheEntry records a module's address range (half-open) in memory and
-// the module itself.
-struct ModuleCacheEntry {
- ModuleCacheEntry(uintptr_t start,
- uintptr_t end,
- InternalModule internal_module)
- : base_address(start),
- end_address(end),
- internal_module(std::move(internal_module)){};
-
- // Base address of the represented module.
- uintptr_t base_address;
-
- // First address off the end of the represented module.
- uintptr_t end_address;
-
- // Module information.
- InternalModule internal_module;
-};
-
-// Module identifiers ---------------------------------------------------------
-
-// Returns the unique build ID for a module loaded at |module_addr|. Returns the
-// empty string if the function fails to get the build ID.
-//
-// Build IDs are created by the concatenation of the module's GUID (Windows) /
-// UUID (Mac) and an "age" field that indicates how many times that GUID/UUID
-// has been reused. In Windows binaries, the "age" field is present in the
-// module header, but on the Mac, UUIDs are never reused and so the "age" value
-// appended to the UUID is always 0.
-std::string GetUniqueId(const void* module_addr) {
- const mach_header_64* mach_header =
- reinterpret_cast<const mach_header_64*>(module_addr);
- DCHECK_EQ(MH_MAGIC_64, mach_header->magic);
-
- size_t offset = sizeof(mach_header_64);
- size_t offset_limit = sizeof(mach_header_64) + mach_header->sizeofcmds;
-
- for (uint32_t i = 0; i < mach_header->ncmds; ++i) {
- if (offset + sizeof(load_command) >= offset_limit)
- return std::string();
-
- const load_command* current_cmd = reinterpret_cast<const load_command*>(
- reinterpret_cast<const uint8_t*>(mach_header) + offset);
-
- if (offset + current_cmd->cmdsize > offset_limit) {
- // This command runs off the end of the command list. This is malformed.
- return std::string();
- }
-
- if (current_cmd->cmd == LC_UUID) {
- if (current_cmd->cmdsize < sizeof(uuid_command)) {
- // This "UUID command" is too small. This is malformed.
- return std::string();
- }
-
- const uuid_command* uuid_cmd =
- reinterpret_cast<const uuid_command*>(current_cmd);
- static_assert(sizeof(uuid_cmd->uuid) == sizeof(uuid_t),
- "UUID field of UUID command should be 16 bytes.");
- // The ID is comprised of the UUID concatenated with the Mac's "age" value
- // which is always 0.
- return HexEncode(&uuid_cmd->uuid, sizeof(uuid_cmd->uuid)) + "0";
- }
- offset += current_cmd->cmdsize;
- }
- return std::string();
-}
-
-// Returns the size of the _TEXT segment of the module loaded at |module_addr|.
-size_t GetModuleTextSize(const void* module_addr) {
- const mach_header_64* mach_header =
- reinterpret_cast<const mach_header_64*>(module_addr);
- DCHECK_EQ(MH_MAGIC_64, mach_header->magic);
-
- unsigned long module_size;
- getsegmentdata(mach_header, SEG_TEXT, &module_size);
-
- return module_size;
-}
-
// Stack walking --------------------------------------------------------------
// Fills |state| with |target_thread|'s context.
@@ -210,6 +127,8 @@ uint32_t GetFrameOffset(int compact_unwind_info) {
(((1 << __builtin_popcount(UNWIND_X86_64_RBP_FRAME_OFFSET))) - 1));
}
+} // namespace
+
// True if the unwind from |leaf_frame_rip| may trigger a crash bug in
// unw_init_local. If so, the stack walk should be aborted at the leaf frame.
bool MayTriggerUnwInitLocalCrash(uint64_t leaf_frame_rip) {
@@ -238,11 +157,13 @@ bool MayTriggerUnwInitLocalCrash(uint64_t leaf_frame_rip) {
vm_size_t size = sizeof(unused);
return vm_read_overwrite(current_task(),
reinterpret_cast<vm_address_t>(info.dli_fbase) +
- GetModuleTextSize(info.dli_fbase),
+ ModuleCache::GetModuleTextSize(info.dli_fbase),
sizeof(unused),
reinterpret_cast<vm_address_t>(&unused), &size) != 0;
}
+namespace {
+
// Check if the cursor contains a valid-looking frame pointer for frame pointer
// unwinds. If the stack frame has a frame pointer, stepping the cursor will
// involve indexing memory access off of that pointer. In that case,
@@ -336,6 +257,8 @@ class ScopedSuspendThread {
DISALLOW_COPY_AND_ASSIGN(ScopedSuspendThread);
};
+} // namespace
+
// NativeStackSamplerMac ------------------------------------------------------
class NativeStackSamplerMac : public NativeStackSampler {
@@ -346,15 +269,11 @@ class NativeStackSamplerMac : public NativeStackSampler {
// StackSamplingProfiler::NativeStackSampler:
void ProfileRecordingStarting() override;
- std::vector<InternalFrame> RecordStackFrames(
+ std::vector<Frame> RecordStackFrames(
StackBuffer* stack_buffer,
ProfileBuilder* profile_builder) override;
private:
- // Returns the InternalModule containing |instruction_pointer|, adding it to
- // module_cache_entry_ if it's not already present.
- InternalModule GetInternalModule(uintptr_t instruction_pointer);
-
// Walks the stack represented by |unwind_context|, calling back to the
// provided lambda for each frame. Returns false if an error occurred,
// otherwise returns true.
@@ -380,7 +299,7 @@ class NativeStackSamplerMac : public NativeStackSampler {
const void* const thread_stack_base_address_;
// Maps a module's address range to the module.
- std::vector<ModuleCacheEntry> module_cache_entry_;
+ ModuleCache module_cache_;
// The address range of |_sigtramp|, the signal trampoline function.
uintptr_t sigtramp_start_;
@@ -408,15 +327,15 @@ NativeStackSamplerMac::NativeStackSamplerMac(
NativeStackSamplerMac::~NativeStackSamplerMac() {}
void NativeStackSamplerMac::ProfileRecordingStarting() {
- module_cache_entry_.clear();
+ module_cache_.Clear();
}
-std::vector<InternalFrame> NativeStackSamplerMac::RecordStackFrames(
+std::vector<Frame> NativeStackSamplerMac::RecordStackFrames(
StackBuffer* stack_buffer,
ProfileBuilder* profile_builder) {
x86_thread_state64_t thread_state;
- const std::vector<InternalFrame> empty_internal_frames;
+ const std::vector<Frame> empty_frames;
// Copy the stack.
@@ -428,19 +347,19 @@ std::vector<InternalFrame> NativeStackSamplerMac::RecordStackFrames(
// default heap acquired by the target thread before it was suspended.
ScopedSuspendThread suspend_thread(thread_port_);
if (!suspend_thread.was_successful())
- return empty_internal_frames;
+ return empty_frames;
if (!GetThreadState(thread_port_, &thread_state))
- return empty_internal_frames;
+ return empty_frames;
auto stack_top = reinterpret_cast<uintptr_t>(thread_stack_base_address_);
uintptr_t stack_bottom = thread_state.__rsp;
if (stack_bottom >= stack_top)
- return empty_internal_frames;
+ return empty_frames;
uintptr_t stack_size = stack_top - stack_bottom;
if (stack_size > stack_buffer->size())
- return empty_internal_frames;
+ return empty_frames;
profile_builder->RecordAnnotations();
@@ -460,16 +379,16 @@ std::vector<InternalFrame> NativeStackSamplerMac::RecordStackFrames(
// Reserve enough memory for most stacks, to avoid repeated allocations.
// Approximately 99.9% of recorded stacks are 128 frames or fewer.
- std::vector<InternalFrame> internal_frames;
- internal_frames.reserve(128);
+ std::vector<Frame> frames;
+ frames.reserve(128);
// Avoid an out-of-bounds read bug in libunwind that can crash us in some
// circumstances. If we're subject to that case, just record the first frame
// and bail. See MayTriggerUnwInitLocalCrash for details.
uintptr_t rip = thread_state.__rip;
if (MayTriggerUnwInitLocalCrash(rip)) {
- internal_frames.emplace_back(rip, GetInternalModule(rip));
- return internal_frames;
+ frames.emplace_back(rip, module_cache_.GetModuleForAddress(rip));
+ return frames;
}
const auto continue_predicate = [this,
@@ -488,43 +407,13 @@ std::vector<InternalFrame> NativeStackSamplerMac::RecordStackFrames(
return HasValidRbp(unwind_cursor, new_stack_top);
};
- WalkStack(
- thread_state,
- [&internal_frames](uintptr_t frame_ip, InternalModule internal_module) {
- internal_frames.emplace_back(frame_ip, std::move(internal_module));
- },
- continue_predicate);
+ WalkStack(thread_state,
+ [&frames](uintptr_t frame_ip, ModuleCache::Module module) {
+ frames.emplace_back(frame_ip, std::move(module));
+ },
+ continue_predicate);
- return internal_frames;
-}
-
-InternalModule NativeStackSamplerMac::GetInternalModule(
- uintptr_t instruction_pointer) {
- // Check if |instruction_pointer| is in the address range of a module we've
- // already seen.
- auto loc =
- std::find_if(module_cache_entry_.begin(), module_cache_entry_.end(),
- [instruction_pointer](const ModuleCacheEntry& entry) {
- return instruction_pointer >= entry.base_address &&
- instruction_pointer < entry.end_address;
- });
- if (loc != module_cache_entry_.end())
- return loc->internal_module;
-
- Dl_info inf;
- if (!dladdr(reinterpret_cast<const void*>(instruction_pointer), &inf))
- return InternalModule();
-
- auto base_module_address = reinterpret_cast<uintptr_t>(inf.dli_fbase);
-
- InternalModule internal_module(
- base_module_address, GetUniqueId(inf.dli_fbase), FilePath(inf.dli_fname));
-
- module_cache_entry_.emplace_back(
- base_module_address,
- base_module_address + GetModuleTextSize(inf.dli_fbase), internal_module);
-
- return internal_module;
+ return frames;
}
template <typename StackFrameCallback, typename ContinueUnwindPredicate>
@@ -553,11 +442,11 @@ bool NativeStackSamplerMac::WalkStackFromContext(
// libunwind adds the expected stack size, it will look for the return
// address in the wrong place. This check should ensure that we bail before
// trying to deref a bad IP obtained this way in the previous frame.
- InternalModule internal_module = GetInternalModule(rip);
- if (!internal_module.is_valid)
+ const ModuleCache::Module& module = module_cache_.GetModuleForAddress(rip);
+ if (!module.is_valid)
return false;
- callback(static_cast<uintptr_t>(rip), internal_module);
+ callback(static_cast<uintptr_t>(rip), module);
if (!continue_unwind(&unwind_cursor))
return false;
@@ -618,14 +507,16 @@ void NativeStackSamplerMac::WalkStack(
}
}
-} // namespace
+// NativeStackSampler ---------------------------------------------------------
+// static
std::unique_ptr<NativeStackSampler> NativeStackSampler::Create(
PlatformThreadId thread_id,
NativeStackSamplerTestDelegate* test_delegate) {
return std::make_unique<NativeStackSamplerMac>(thread_id, test_delegate);
}
+// static
size_t NativeStackSampler::GetStackBufferSize() {
// In platform_thread_mac's GetDefaultThreadStackSize(), RLIMIT_STACK is used
// for all stacks, not just the main thread's, so it is good for use here.
diff --git a/chromium/base/profiler/native_stack_sampler_win.cc b/chromium/base/profiler/native_stack_sampler_win.cc
index b9b1773e896..3a3fbcfd441 100644
--- a/chromium/base/profiler/native_stack_sampler_win.cc
+++ b/chromium/base/profiler/native_stack_sampler_win.cc
@@ -6,7 +6,6 @@
#include <windows.h>
-#include <objbase.h>
#include <stddef.h>
#include <winternl.h>
@@ -21,21 +20,13 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/profiler/win32_stack_frame_unwinder.h"
+#include "base/sampling_heap_profiler/module_cache.h"
#include "base/stl_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
-#include "base/win/pe_image.h"
-#include "base/win/scoped_handle.h"
namespace base {
using Frame = StackSamplingProfiler::Frame;
-using InternalFrame = StackSamplingProfiler::InternalFrame;
-using Module = StackSamplingProfiler::Module;
-using InternalModule = StackSamplingProfiler::InternalModule;
using ProfileBuilder = StackSamplingProfiler::ProfileBuilder;
// Stack recording functions --------------------------------------------------
@@ -203,34 +194,6 @@ void RecordStack(CONTEXT* context, std::vector<RecordedFrame>* stack) {
#endif
}
-// Gets the unique build ID for a module. Windows build IDs are created by a
-// concatenation of a GUID and AGE fields found in the headers of a module. The
-// GUID is stored in the first 16 bytes and the AGE is stored in the last 4
-// bytes. Returns the empty string if the function fails to get the build ID.
-//
-// Example:
-// dumpbin chrome.exe /headers | find "Format:"
-// ... Format: RSDS, {16B2A428-1DED-442E-9A36-FCE8CBD29726}, 10, ...
-//
-// The resulting buildID string of this instance of chrome.exe is
-// "16B2A4281DED442E9A36FCE8CBD2972610".
-//
-// Note that the AGE field is encoded in decimal, not hex.
-std::string GetBuildIDForModule(HMODULE module_handle) {
- GUID guid;
- DWORD age;
- win::PEImage(module_handle).GetDebugId(&guid, &age, /* pdb_file= */ nullptr);
- const int kGUIDSize = 39;
- string16 build_id;
- int result =
- ::StringFromGUID2(guid, WriteInto(&build_id, kGUIDSize), kGUIDSize);
- if (result != kGUIDSize)
- return std::string();
- RemoveChars(build_id, L"{}-", &build_id);
- build_id += StringPrintf(L"%d", age);
- return UTF16ToUTF8(build_id);
-}
-
// ScopedDisablePriorityBoost -------------------------------------------------
// Disables priority boost on a thread for the lifetime of the object.
@@ -382,6 +345,8 @@ void SuspendThreadAndRecordStack(
RecordStack(&thread_context, stack);
}
+} // namespace
+
// NativeStackSamplerWin ------------------------------------------------------
class NativeStackSamplerWin : public NativeStackSampler {
@@ -392,19 +357,13 @@ class NativeStackSamplerWin : public NativeStackSampler {
// StackSamplingProfiler::NativeStackSampler:
void ProfileRecordingStarting() override;
- std::vector<InternalFrame> RecordStackFrames(
+ std::vector<Frame> RecordStackFrames(
StackBuffer* stack_buffer,
ProfileBuilder* profile_builder) override;
private:
- // Attempts to query the module filename, base address, and id for
- // |module_handle|, and returns them in an InternalModule object.
- static InternalModule GetModuleForHandle(HMODULE module_handle);
-
- // Creates a set of internal frames with the information represented by
- // |stack|.
- std::vector<InternalFrame> CreateInternalFrames(
- const std::vector<RecordedFrame>& stack);
+ // Creates a set of frames with the information represented by |stack|.
+ std::vector<Frame> CreateFrames(const std::vector<RecordedFrame>& stack);
win::ScopedHandle thread_handle_;
@@ -413,8 +372,8 @@ class NativeStackSamplerWin : public NativeStackSampler {
// The stack base address corresponding to |thread_handle_|.
const void* const thread_stack_base_address_;
- // The internal module objects, indexed by the module handle.
- std::map<HMODULE, InternalModule> module_cache_;
+ // The module objects, indexed by the module handle.
+ std::map<HMODULE, ModuleCache::Module> module_cache_;
DISALLOW_COPY_AND_ASSIGN(NativeStackSamplerWin);
};
@@ -433,7 +392,7 @@ void NativeStackSamplerWin::ProfileRecordingStarting() {
module_cache_.clear();
}
-std::vector<InternalFrame> NativeStackSamplerWin::RecordStackFrames(
+std::vector<Frame> NativeStackSamplerWin::RecordStackFrames(
StackBuffer* stack_buffer,
ProfileBuilder* profile_builder) {
DCHECK(stack_buffer);
@@ -443,58 +402,43 @@ std::vector<InternalFrame> NativeStackSamplerWin::RecordStackFrames(
stack_buffer->buffer(), stack_buffer->size(),
&stack, profile_builder, test_delegate_);
- return CreateInternalFrames(stack);
-}
-
-// static
-InternalModule NativeStackSamplerWin::GetModuleForHandle(
- HMODULE module_handle) {
- wchar_t module_name[MAX_PATH];
- DWORD result_length =
- ::GetModuleFileName(module_handle, module_name, size(module_name));
- if (result_length == 0)
- return InternalModule();
-
- const std::string& module_id = GetBuildIDForModule(module_handle);
- if (module_id.empty())
- return InternalModule();
-
- return InternalModule(reinterpret_cast<uintptr_t>(module_handle), module_id,
- FilePath(module_name));
+ return CreateFrames(stack);
}
-std::vector<InternalFrame> NativeStackSamplerWin::CreateInternalFrames(
+std::vector<Frame> NativeStackSamplerWin::CreateFrames(
const std::vector<RecordedFrame>& stack) {
- std::vector<InternalFrame> internal_frames;
- internal_frames.reserve(stack.size());
+ std::vector<Frame> frames;
+ frames.reserve(stack.size());
for (const auto& frame : stack) {
auto frame_ip = reinterpret_cast<uintptr_t>(frame.instruction_pointer);
HMODULE module_handle = frame.module.Get();
if (!module_handle) {
- internal_frames.emplace_back(frame_ip, InternalModule());
+ frames.emplace_back(frame_ip, ModuleCache::Module());
continue;
}
auto loc = module_cache_.find(module_handle);
if (loc != module_cache_.end()) {
- internal_frames.emplace_back(frame_ip, loc->second);
+ frames.emplace_back(frame_ip, loc->second);
continue;
}
- InternalModule internal_module = GetModuleForHandle(module_handle);
- if (internal_module.is_valid)
- module_cache_.insert(std::make_pair(module_handle, internal_module));
+ ModuleCache::Module module =
+ ModuleCache::CreateModuleForHandle(module_handle);
+ if (module.is_valid)
+ module_cache_.insert(std::make_pair(module_handle, module));
- internal_frames.emplace_back(frame_ip, std::move(internal_module));
+ frames.emplace_back(frame_ip, std::move(module));
}
- return internal_frames;
+ return frames;
}
-} // namespace
+// NativeStackSampler ---------------------------------------------------------
+// static
std::unique_ptr<NativeStackSampler> NativeStackSampler::Create(
PlatformThreadId thread_id,
NativeStackSamplerTestDelegate* test_delegate) {
@@ -512,6 +456,7 @@ std::unique_ptr<NativeStackSampler> NativeStackSampler::Create(
return std::unique_ptr<NativeStackSampler>();
}
+// static
size_t NativeStackSampler::GetStackBufferSize() {
// The default Win32 reserved stack size is 1 MB and Chrome Windows threads
// currently always use the default, but this allows for expansion if it
diff --git a/chromium/base/profiler/stack_sampling_profiler.cc b/chromium/base/profiler/stack_sampling_profiler.cc
index 02df814f8cc..4f1ad1d92ba 100644
--- a/chromium/base/profiler/stack_sampling_profiler.cc
+++ b/chromium/base/profiler/stack_sampling_profiler.cc
@@ -5,6 +5,7 @@
#include "base/profiler/stack_sampling_profiler.h"
#include <algorithm>
+#include <map>
#include <utility>
#include "base/atomic_sequence_num.h"
@@ -25,8 +26,6 @@
namespace base {
-const size_t kUnknownModuleIndex = static_cast<size_t>(-1);
-
namespace {
// This value is used to initialize the WaitableEvent object. This MUST BE set
@@ -41,85 +40,14 @@ const int kNullProfilerId = -1;
} // namespace
-// StackSamplingProfiler::Module ----------------------------------------------
-
-StackSamplingProfiler::Module::Module() : base_address(0u) {}
-
-StackSamplingProfiler::Module::Module(uintptr_t base_address,
- const std::string& id,
- const FilePath& filename)
- : base_address(base_address), id(id), filename(filename) {}
-
-StackSamplingProfiler::Module::~Module() = default;
-
-// StackSamplingProfiler::InternalModule --------------------------------------
-
-StackSamplingProfiler::InternalModule::InternalModule() : is_valid(false) {}
-
-StackSamplingProfiler::InternalModule::InternalModule(uintptr_t base_address,
- const std::string& id,
- const FilePath& filename)
- : base_address(base_address), id(id), filename(filename), is_valid(true) {}
-
-StackSamplingProfiler::InternalModule::~InternalModule() = default;
-
-// StackSamplingProfiler::Frame -----------------------------------------------
+// StackSamplingProfiler::Frame -------------------------------------
StackSamplingProfiler::Frame::Frame(uintptr_t instruction_pointer,
- size_t module_index)
- : instruction_pointer(instruction_pointer), module_index(module_index) {}
+ ModuleCache::Module module)
+ : instruction_pointer(instruction_pointer), module(std::move(module)) {}
StackSamplingProfiler::Frame::~Frame() = default;
-StackSamplingProfiler::Frame::Frame()
- : instruction_pointer(0), module_index(kUnknownModuleIndex) {}
-
-// StackSamplingProfiler::InternalFrame -------------------------------------
-
-StackSamplingProfiler::InternalFrame::InternalFrame(
- uintptr_t instruction_pointer,
- InternalModule internal_module)
- : instruction_pointer(instruction_pointer),
- internal_module(std::move(internal_module)) {}
-
-StackSamplingProfiler::InternalFrame::~InternalFrame() = default;
-
-// StackSamplingProfiler::Sample ----------------------------------------------
-
-StackSamplingProfiler::Sample::Sample() = default;
-
-StackSamplingProfiler::Sample::Sample(const Sample& sample) = default;
-
-StackSamplingProfiler::Sample::~Sample() = default;
-
-StackSamplingProfiler::Sample::Sample(const Frame& frame) {
- frames.push_back(std::move(frame));
-}
-
-StackSamplingProfiler::Sample::Sample(const std::vector<Frame>& frames)
- : frames(frames) {}
-
-// StackSamplingProfiler::CallStackProfile ------------------------------------
-
-StackSamplingProfiler::CallStackProfile::CallStackProfile() = default;
-
-StackSamplingProfiler::CallStackProfile::CallStackProfile(
- CallStackProfile&& other) = default;
-
-StackSamplingProfiler::CallStackProfile::~CallStackProfile() = default;
-
-StackSamplingProfiler::CallStackProfile&
-StackSamplingProfiler::CallStackProfile::operator=(CallStackProfile&& other) =
- default;
-
-StackSamplingProfiler::CallStackProfile
-StackSamplingProfiler::CallStackProfile::CopyForTesting() const {
- return CallStackProfile(*this);
-}
-
-StackSamplingProfiler::CallStackProfile::CallStackProfile(
- const CallStackProfile& other) = default;
-
// StackSamplingProfiler::SamplingThread --------------------------------------
class StackSamplingProfiler::SamplingThread : public Thread {
@@ -698,9 +626,22 @@ StackSamplingProfiler::StackSamplingProfiler(
const SamplingParams& params,
std::unique_ptr<ProfileBuilder> profile_builder,
NativeStackSamplerTestDelegate* test_delegate)
+ : StackSamplingProfiler(thread_id,
+ params,
+ std::move(profile_builder),
+ nullptr,
+ test_delegate) {}
+
+StackSamplingProfiler::StackSamplingProfiler(
+ PlatformThreadId thread_id,
+ const SamplingParams& params,
+ std::unique_ptr<ProfileBuilder> profile_builder,
+ std::unique_ptr<NativeStackSampler> sampler,
+ NativeStackSamplerTestDelegate* test_delegate)
: thread_id_(thread_id),
params_(params),
profile_builder_(std::move(profile_builder)),
+ native_sampler_(std::move(sampler)),
// The event starts "signaled" so code knows it's safe to start thread
// and "manual" so that it can be waited in multiple places.
profiling_inactive_(kResetPolicy, WaitableEvent::InitialState::SIGNALED),
@@ -734,10 +675,10 @@ void StackSamplingProfiler::Start() {
// already.
DCHECK(profile_builder_);
- std::unique_ptr<NativeStackSampler> native_sampler =
- NativeStackSampler::Create(thread_id_, test_delegate_);
+ if (!native_sampler_)
+ native_sampler_ = NativeStackSampler::Create(thread_id_, test_delegate_);
- if (!native_sampler)
+ if (!native_sampler_)
return;
// The IsSignaled() check below requires that the WaitableEvent be manually
@@ -755,7 +696,7 @@ void StackSamplingProfiler::Start() {
DCHECK_EQ(kNullProfilerId, profiler_id_);
profiler_id_ = SamplingThread::GetInstance()->Add(
std::make_unique<SamplingThread::CollectionContext>(
- thread_id_, params_, &profiling_inactive_, std::move(native_sampler),
+ thread_id_, params_, &profiling_inactive_, std::move(native_sampler_),
std::move(profile_builder_)));
DCHECK_NE(kNullProfilerId, profiler_id_);
}
@@ -765,44 +706,4 @@ void StackSamplingProfiler::Stop() {
profiler_id_ = kNullProfilerId;
}
-// StackSamplingProfiler::Frame global functions ------------------------------
-
-bool operator==(const StackSamplingProfiler::Module& a,
- const StackSamplingProfiler::Module& b) {
- return a.base_address == b.base_address && a.id == b.id &&
- a.filename == b.filename;
-}
-
-bool operator==(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b) {
- return a.process_milestones == b.process_milestones && a.frames == b.frames;
-}
-
-bool operator!=(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b) {
- return !(a == b);
-}
-
-bool operator<(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b) {
- if (a.process_milestones != b.process_milestones)
- return a.process_milestones < b.process_milestones;
-
- return a.frames < b.frames;
-}
-
-bool operator==(const StackSamplingProfiler::Frame& a,
- const StackSamplingProfiler::Frame& b) {
- return a.instruction_pointer == b.instruction_pointer &&
- a.module_index == b.module_index;
-}
-
-bool operator<(const StackSamplingProfiler::Frame& a,
- const StackSamplingProfiler::Frame& b) {
- if (a.module_index != b.module_index)
- return a.module_index < b.module_index;
-
- return a.instruction_pointer < b.instruction_pointer;
-}
-
} // namespace base
diff --git a/chromium/base/profiler/stack_sampling_profiler.h b/chromium/base/profiler/stack_sampling_profiler.h
index e43349a8fe0..4020be84db2 100644
--- a/chromium/base/profiler/stack_sampling_profiler.h
+++ b/chromium/base/profiler/stack_sampling_profiler.h
@@ -5,26 +5,19 @@
#ifndef BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
#define BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
-#include <stddef.h>
-
-#include <map>
#include <memory>
-#include <string>
#include <vector>
#include "base/base_export.h"
-#include "base/files/file_path.h"
#include "base/macros.h"
-#include "base/strings/string16.h"
+#include "base/sampling_heap_profiler/module_cache.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
namespace base {
-// Identifies an unknown module.
-BASE_EXPORT extern const size_t kUnknownModuleIndex;
-
+class NativeStackSampler;
class NativeStackSamplerTestDelegate;
// StackSamplingProfiler periodically stops a thread to sample its stack, for
@@ -40,8 +33,11 @@ class NativeStackSamplerTestDelegate;
// // To process the profiles, use a custom ProfileBuilder subclass:
// class SubProfileBuilder :
// public base::StackSamplingProfiler::ProfileBuilder{...}
+//
+// // On Android the |sampler| is not implemented in base. So, client can pass
+// // in |sampler| to use while profiling.
// base::StackSamplingProfiler profiler(base::PlatformThread::CurrentId()),
-// params, std::make_unique<SubProfileBuilder>(...));
+// params, std::make_unique<SubProfileBuilder>(...), <optional> sampler);
//
// profiler.Start();
// // ... work being done on the target thread here ...
@@ -56,141 +52,20 @@ class NativeStackSamplerTestDelegate;
// by the profiler.
class BASE_EXPORT StackSamplingProfiler {
public:
- // Module represents the module (DLL or exe) corresponding to a stack frame.
- struct BASE_EXPORT Module {
- Module();
- Module(uintptr_t base_address,
- const std::string& id,
- const FilePath& filename);
- ~Module();
-
- // Points to the base address of the module.
- uintptr_t base_address;
-
- // An opaque binary string that uniquely identifies a particular program
- // version with high probability. This is parsed from headers of the loaded
- // module.
- // For binaries generated by GNU tools:
- // Contents of the .note.gnu.build-id field.
- // On Windows:
- // GUID + AGE in the debug image headers of a module.
- std::string id;
-
- // The filename of the module.
- FilePath filename;
- };
-
- // InternalModule represents the module (DLL or exe) and its validness state.
- // Different from Module, it has an additional field "is_valid".
+ // Frame represents an individual sampled stack frame with full module
+ // information.
//
// This struct is only used for sampling data transfer from NativeStackSampler
// to ProfileBuilder.
- struct BASE_EXPORT InternalModule {
- InternalModule();
- InternalModule(uintptr_t base_address,
- const std::string& id,
- const FilePath& filename);
- ~InternalModule();
-
- // Points to the base address of the module.
- uintptr_t base_address;
-
- // An opaque binary string that uniquely identifies a particular program
- // version with high probability. This is parsed from headers of the loaded
- // module.
- // For binaries generated by GNU tools:
- // Contents of the .note.gnu.build-id field.
- // On Windows:
- // GUID + AGE in the debug image headers of a module.
- std::string id;
-
- // The filename of the module.
- FilePath filename;
-
- // The validness of the module.
- bool is_valid;
- };
-
- // Frame represents an individual sampled stack frame with module information.
struct BASE_EXPORT Frame {
- Frame(uintptr_t instruction_pointer, size_t module_index);
+ Frame(uintptr_t instruction_pointer, ModuleCache::Module module);
~Frame();
- // Default constructor to satisfy IPC macros. Do not use explicitly.
- Frame();
-
- // The sampled instruction pointer within the function.
- uintptr_t instruction_pointer;
-
- // Index of the module in CallStackProfile::modules. We don't represent
- // module state directly here to save space.
- size_t module_index;
- };
-
- // InternalFrame represents an individual sampled stack frame with full module
- // information. This is different from Frame which only contains module index.
- //
- // This struct is only used for sampling data transfer from NativeStackSampler
- // to ProfileBuilder.
- struct BASE_EXPORT InternalFrame {
- InternalFrame(uintptr_t instruction_pointer,
- InternalModule internal_module);
- ~InternalFrame();
-
// The sampled instruction pointer within the function.
uintptr_t instruction_pointer;
// The module information.
- InternalModule internal_module;
- };
-
- // Sample represents a set of stack frames with some extra information.
- struct BASE_EXPORT Sample {
- Sample();
- Sample(const Sample& sample);
- ~Sample();
-
- // These constructors are used only during testing.
- Sample(const Frame& frame);
- Sample(const std::vector<Frame>& frames);
-
- // The entire stack frame when the sample is taken.
- std::vector<Frame> frames;
-
- // A bit-field indicating which process milestones have passed. This can be
- // used to tell where in the process lifetime the samples are taken. Just
- // as a "lifetime" can only move forward, these bits mark the milestones of
- // the processes life as they occur. Bits can be set but never reset. The
- // actual definition of the individual bits is left to the user of this
- // module.
- uint32_t process_milestones = 0;
- };
-
- // CallStackProfile represents a set of samples.
- struct BASE_EXPORT CallStackProfile {
- CallStackProfile();
- CallStackProfile(CallStackProfile&& other);
- ~CallStackProfile();
-
- CallStackProfile& operator=(CallStackProfile&& other);
-
- CallStackProfile CopyForTesting() const;
-
- std::vector<Module> modules;
- std::vector<Sample> samples;
-
- // Duration of this profile.
- TimeDelta profile_duration;
-
- // Time between samples.
- TimeDelta sampling_period;
-
- private:
- // Copying is possible but expensive so disallow it except for internal use
- // (i.e. CopyForTesting); use std::move instead.
- CallStackProfile(const CallStackProfile& other);
-
- DISALLOW_ASSIGN(CallStackProfile);
+ ModuleCache::Module module;
};
// Represents parameters that configure the sampling.
@@ -251,10 +126,8 @@ class BASE_EXPORT StackSamplingProfiler {
// deadlock.
virtual void RecordAnnotations() = 0;
- // Records a new set of internal frames. Invoked when sampling a sample
- // completes.
- virtual void OnSampleCompleted(
- std::vector<InternalFrame> internal_frames) = 0;
+ // Records a new set of frames. Invoked when sampling a sample completes.
+ virtual void OnSampleCompleted(std::vector<Frame> frames) = 0;
// Finishes the profile construction with |profile_duration| and
// |sampling_period|. Invoked when sampling a profile completes.
@@ -284,6 +157,15 @@ class BASE_EXPORT StackSamplingProfiler {
std::unique_ptr<ProfileBuilder> profile_builder,
NativeStackSamplerTestDelegate* test_delegate = nullptr);
+ // Same as above function, with custom |sampler| implementation. The sampler
+ // on Android is not implemented in base.
+ StackSamplingProfiler(
+ PlatformThreadId thread_id,
+ const SamplingParams& params,
+ std::unique_ptr<ProfileBuilder> profile_builder,
+ std::unique_ptr<NativeStackSampler> sampler,
+ NativeStackSamplerTestDelegate* test_delegate = nullptr);
+
// Stops any profiling currently taking place before destroying the profiler.
// This will block until profile_builder_'s OnProfileCompleted function has
// executed if profiling has started but not already finished.
@@ -314,11 +196,16 @@ class BASE_EXPORT StackSamplingProfiler {
const SamplingParams params_;
- // Receives the sampling data and builds a CallStackProfile. The ownership of
- // this object will be transferred to the sampling thread when thread sampling
+ // Receives the sampling data and builds a profile. The ownership of this
+ // object will be transferred to the sampling thread when thread sampling
// starts.
std::unique_ptr<ProfileBuilder> profile_builder_;
+ // Stack sampler which stops the thread and collects stack frames. The
+ // ownership of this object will be transferred to the sampling thread when
+ // thread sampling starts.
+ std::unique_ptr<NativeStackSampler> native_sampler_;
+
// This starts "signaled", is reset when sampling begins, and is signaled
// when that sampling is complete and the profile_builder_'s
// OnProfileCompleted function has executed.
@@ -334,21 +221,6 @@ class BASE_EXPORT StackSamplingProfiler {
DISALLOW_COPY_AND_ASSIGN(StackSamplingProfiler);
};
-// These operators permit types to be compared and used in a map of Samples, as
-// done in tests and by the metrics provider code.
-BASE_EXPORT bool operator==(const StackSamplingProfiler::Module& a,
- const StackSamplingProfiler::Module& b);
-BASE_EXPORT bool operator==(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b);
-BASE_EXPORT bool operator!=(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b);
-BASE_EXPORT bool operator<(const StackSamplingProfiler::Sample& a,
- const StackSamplingProfiler::Sample& b);
-BASE_EXPORT bool operator==(const StackSamplingProfiler::Frame& a,
- const StackSamplingProfiler::Frame& b);
-BASE_EXPORT bool operator<(const StackSamplingProfiler::Frame& a,
- const StackSamplingProfiler::Frame& b);
-
} // namespace base
#endif // BASE_PROFILER_STACK_SAMPLING_PROFILER_H_
diff --git a/chromium/base/profiler/stack_sampling_profiler_unittest.cc b/chromium/base/profiler/stack_sampling_profiler_unittest.cc
index b0f883624f6..b19b9dcf21c 100644
--- a/chromium/base/profiler/stack_sampling_profiler_unittest.cc
+++ b/chromium/base/profiler/stack_sampling_profiler_unittest.cc
@@ -65,12 +65,7 @@ namespace base {
using SamplingParams = StackSamplingProfiler::SamplingParams;
using Frame = StackSamplingProfiler::Frame;
using Frames = std::vector<Frame>;
-using InternalFrame = StackSamplingProfiler::InternalFrame;
-using InternalFrames = std::vector<InternalFrame>;
-using InternalFrameSets = std::vector<std::vector<InternalFrame>>;
-using Module = StackSamplingProfiler::Module;
-using InternalModule = StackSamplingProfiler::InternalModule;
-using Sample = StackSamplingProfiler::Sample;
+using FrameSets = std::vector<std::vector<Frame>>;
namespace {
@@ -280,12 +275,11 @@ NOINLINE const void* TargetThread::GetProgramCounter() {
#endif
}
-// Profile consists of a set of internal frame sets and other sampling
-// information.
+// Profile consists of a set of frame sets and other sampling information.
struct Profile {
Profile() = default;
Profile(Profile&& other) = default;
- Profile(const InternalFrameSets& frame_sets,
+ Profile(const FrameSets& frame_sets,
int annotation_count,
TimeDelta profile_duration,
TimeDelta sampling_period);
@@ -294,8 +288,8 @@ struct Profile {
Profile& operator=(Profile&& other) = default;
- // The collected internal frame sets.
- InternalFrameSets frame_sets;
+ // The collected frame sets.
+ FrameSets frame_sets;
// The number of invocations of RecordAnnotations().
int annotation_count;
@@ -307,7 +301,7 @@ struct Profile {
TimeDelta sampling_period;
};
-Profile::Profile(const InternalFrameSets& frame_sets,
+Profile::Profile(const FrameSets& frame_sets,
int annotation_count,
TimeDelta profile_duration,
TimeDelta sampling_period)
@@ -321,7 +315,7 @@ Profile::Profile(const InternalFrameSets& frame_sets,
// this should run as quickly as possible.
using ProfileCompletedCallback = Callback<void(Profile)>;
-// TestProfileBuilder collects internal frames produced by the profiler.
+// TestProfileBuilder collects frames produced by the profiler.
class TestProfileBuilder : public StackSamplingProfiler::ProfileBuilder {
public:
TestProfileBuilder(const ProfileCompletedCallback& callback);
@@ -330,13 +324,13 @@ class TestProfileBuilder : public StackSamplingProfiler::ProfileBuilder {
// StackSamplingProfiler::ProfileBuilder:
void RecordAnnotations() override;
- void OnSampleCompleted(InternalFrames internal_frames) override;
+ void OnSampleCompleted(Frames frames) override;
void OnProfileCompleted(TimeDelta profile_duration,
TimeDelta sampling_period) override;
private:
- // The sets of internal frames recorded.
- std::vector<InternalFrames> frame_sets_;
+ // The sets of frames recorded.
+ std::vector<Frames> frame_sets_;
// The number of invocations of RecordAnnotations().
int annotation_count_ = 0;
@@ -356,8 +350,8 @@ void TestProfileBuilder::RecordAnnotations() {
++annotation_count_;
}
-void TestProfileBuilder::OnSampleCompleted(InternalFrames internal_frames) {
- frame_sets_.push_back(std::move(internal_frames));
+void TestProfileBuilder::OnSampleCompleted(Frames frames) {
+ frame_sets_.push_back(std::move(frames));
}
void TestProfileBuilder::OnProfileCompleted(TimeDelta profile_duration,
@@ -476,11 +470,11 @@ std::vector<std::unique_ptr<TestProfilerInfo>> CreateProfilers(
return profilers;
}
-// Captures internal frames as specified by |params| on the TargetThread, and
-// returns them. Waits up to |profiler_wait_time| for the profiler to complete.
-InternalFrameSets CaptureFrameSets(const SamplingParams& params,
- TimeDelta profiler_wait_time) {
- InternalFrameSets frame_sets;
+// Captures frames as specified by |params| on the TargetThread, and returns
+// them. Waits up to |profiler_wait_time| for the profiler to complete.
+FrameSets CaptureFrameSets(const SamplingParams& params,
+ TimeDelta profiler_wait_time) {
+ FrameSets frame_sets;
WithTargetThread([&params, &frame_sets,
profiler_wait_time](PlatformThreadId target_thread_id) {
TestProfilerInfo info(target_thread_id, params);
@@ -533,8 +527,8 @@ const void* MaybeFixupFunctionAddressForILT(const void* function_address) {
// Searches through the frames in |sample|, returning an iterator to the first
// frame that has an instruction pointer within |target_function|. Returns
// sample.end() if no such frames are found.
-InternalFrames::const_iterator FindFirstFrameWithinFunction(
- const InternalFrames& frames,
+Frames::const_iterator FindFirstFrameWithinFunction(
+ const Frames& frames,
TargetFunction target_function) {
uintptr_t function_start =
reinterpret_cast<uintptr_t>(MaybeFixupFunctionAddressForILT(
@@ -551,12 +545,12 @@ InternalFrames::const_iterator FindFirstFrameWithinFunction(
}
// Formats a sample into a string that can be output for test diagnostics.
-std::string FormatSampleForDiagnosticOutput(const InternalFrames& frames) {
+std::string FormatSampleForDiagnosticOutput(const Frames& frames) {
std::string output;
for (const auto& frame : frames) {
output += StringPrintf(
"0x%p %s\n", reinterpret_cast<const void*>(frame.instruction_pointer),
- frame.internal_module.filename.AsUTF8Unsafe().c_str());
+ frame.module.filename.AsUTF8Unsafe().c_str());
}
return output;
}
@@ -653,11 +647,11 @@ void TestLibraryUnload(bool wait_until_unloaded) {
// Look up the frames.
ASSERT_EQ(1u, profile.frame_sets.size());
- const InternalFrames& frames = profile.frame_sets[0];
+ const Frames& frames = profile.frame_sets[0];
// Check that the stack contains a frame for
// TargetThread::SignalAndWaitUntilSignaled().
- InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction(
+ Frames::const_iterator end_frame = FindFirstFrameWithinFunction(
frames, &TargetThread::SignalAndWaitUntilSignaled);
ASSERT_TRUE(end_frame != frames.end())
<< "Function at "
@@ -690,9 +684,8 @@ void TestLibraryUnload(bool wait_until_unloaded) {
// Check that the stack contains a frame for
// TargetThread::CallThroughOtherLibrary().
- InternalFrames::const_iterator other_library_frame =
- FindFirstFrameWithinFunction(frames,
- &TargetThread::CallThroughOtherLibrary);
+ Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction(
+ frames, &TargetThread::CallThroughOtherLibrary);
ASSERT_TRUE(other_library_frame != frames.end())
<< "Function at "
<< MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
@@ -735,8 +728,7 @@ class StackSamplingProfilerTest : public testing::Test {
} // namespace
-// Checks that the basic expected information is present in sampled internal
-// frames.
+// Checks that the basic expected information is present in sampled frames.
//
// macOS ASAN is not yet supported - crbug.com/718628.
#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX))
@@ -749,19 +741,19 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Basic) {
params.sampling_interval = TimeDelta::FromMilliseconds(0);
params.samples_per_profile = 1;
- InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+ FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
// Check that the size of the frame sets are correct.
ASSERT_EQ(1u, frame_sets.size());
- const InternalFrames& frames = frame_sets[0];
+ const Frames& frames = frame_sets[0];
// Check that all the modules are valid.
for (const auto& frame : frames)
- EXPECT_TRUE(frame.internal_module.is_valid);
+ EXPECT_TRUE(frame.module.is_valid);
// Check that the stack contains a frame for
// TargetThread::SignalAndWaitUntilSignaled().
- InternalFrames::const_iterator loc = FindFirstFrameWithinFunction(
+ Frames::const_iterator loc = FindFirstFrameWithinFunction(
frames, &TargetThread::SignalAndWaitUntilSignaled);
ASSERT_TRUE(loc != frames.end())
<< "Function at "
@@ -804,11 +796,11 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
// Look up the frames.
ASSERT_EQ(1u, profile.frame_sets.size());
- const InternalFrames& frames = profile.frame_sets[0];
+ const Frames& frames = profile.frame_sets[0];
// Check that the stack contains a frame for
// TargetThread::SignalAndWaitUntilSignaled().
- InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction(
+ Frames::const_iterator end_frame = FindFirstFrameWithinFunction(
frames, &TargetThread::SignalAndWaitUntilSignaled);
ASSERT_TRUE(end_frame != frames.end())
<< "Function at "
@@ -818,7 +810,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) {
<< FormatSampleForDiagnosticOutput(frames);
// Check that the stack contains a frame for TargetThread::CallWithAlloca().
- InternalFrames::const_iterator alloca_frame =
+ Frames::const_iterator alloca_frame =
FindFirstFrameWithinFunction(frames, &TargetThread::CallWithAlloca);
ASSERT_TRUE(alloca_frame != frames.end())
<< "Function at "
@@ -932,20 +924,20 @@ PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) {
});
}
-// Checks that no internal frames are captured if the profiling is stopped
-// during the initial delay.
+// Checks that no frames are captured if the profiling is stopped during the
+// initial delay.
PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInitialDelay) {
SamplingParams params;
params.initial_delay = TimeDelta::FromSeconds(60);
- InternalFrameSets frame_sets =
+ FrameSets frame_sets =
CaptureFrameSets(params, TimeDelta::FromMilliseconds(0));
EXPECT_TRUE(frame_sets.empty());
}
-// Checks that tasks can be stopped before completion and incomplete internal
-// frames are captured.
+// Checks that tasks can be stopped before completion and incomplete frames are
+// captured.
PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) {
// Test delegate that counts samples.
class SampleRecordedEvent : public NativeStackSamplerTestDelegate {
@@ -1013,7 +1005,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) {
params.sampling_interval = TimeDelta::FromMilliseconds(0);
params.samples_per_profile = 1;
- InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+ FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
ASSERT_EQ(1u, frame_sets.size());
frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
@@ -1075,7 +1067,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, SamplerIdleShutdown) {
params.sampling_interval = TimeDelta::FromMilliseconds(0);
params.samples_per_profile = 1;
- InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+ FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
ASSERT_EQ(1u, frame_sets.size());
// Capture thread should still be running at this point.
@@ -1100,7 +1092,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest,
params.sampling_interval = TimeDelta::FromMilliseconds(0);
params.samples_per_profile = 1;
- InternalFrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
+ FrameSets frame_sets = CaptureFrameSets(params, AVeryLongTimeDelta());
ASSERT_EQ(1u, frame_sets.size());
// Capture thread should still be running at this point.
@@ -1318,13 +1310,12 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
// Look up the frames.
ASSERT_EQ(1u, profile.frame_sets.size());
- const InternalFrames& frames = profile.frame_sets[0];
+ const Frames& frames = profile.frame_sets[0];
// Check that the stack contains a frame for
// TargetThread::CallThroughOtherLibrary().
- InternalFrames::const_iterator other_library_frame =
- FindFirstFrameWithinFunction(frames,
- &TargetThread::CallThroughOtherLibrary);
+ Frames::const_iterator other_library_frame = FindFirstFrameWithinFunction(
+ frames, &TargetThread::CallThroughOtherLibrary);
ASSERT_TRUE(other_library_frame != frames.end())
<< "Function at "
<< MaybeFixupFunctionAddressForILT(reinterpret_cast<const void*>(
@@ -1334,7 +1325,7 @@ PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
// Check that the stack contains a frame for
// TargetThread::SignalAndWaitUntilSignaled().
- InternalFrames::const_iterator end_frame = FindFirstFrameWithinFunction(
+ Frames::const_iterator end_frame = FindFirstFrameWithinFunction(
frames, &TargetThread::SignalAndWaitUntilSignaled);
ASSERT_TRUE(end_frame != frames.end())
<< "Function at "
diff --git a/chromium/base/profiler/win32_stack_frame_unwinder.cc b/chromium/base/profiler/win32_stack_frame_unwinder.cc
index a3f5f74b853..a337c160d59 100644
--- a/chromium/base/profiler/win32_stack_frame_unwinder.cc
+++ b/chromium/base/profiler/win32_stack_frame_unwinder.cc
@@ -119,6 +119,8 @@ Win32StackFrameUnwinder::~Win32StackFrameUnwinder() {}
bool Win32StackFrameUnwinder::TryUnwind(CONTEXT* context,
ScopedModuleHandle* module) {
#ifdef _WIN64
+ // TODO(chengx): update base::ModuleCache to return a ScopedModuleHandle and
+ // use it for this module lookup.
ScopedModuleHandle frame_module =
unwind_functions_->GetModuleForProgramCounter(context->Rip);
if (!frame_module.IsValid()) {