Merge "Add an interface for stopping in certain maps."
am: 3adedf9895
Change-Id: I4e7a08cb71592441f0b3ace4ced1d7cb17985695
This commit is contained in:
commit
4e9a5eec5d
5 changed files with 27 additions and 16 deletions
|
|
@ -45,12 +45,12 @@
|
||||||
|
|
||||||
bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
|
bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
|
||||||
std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
|
std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
|
||||||
static std::set<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
|
static std::vector<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"};
|
||||||
UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
|
UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
|
||||||
auto process_memory = stack_map->process_memory();
|
auto process_memory = stack_map->process_memory();
|
||||||
unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
|
unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
|
||||||
regs, stack_map->process_memory());
|
regs, stack_map->process_memory());
|
||||||
unwinder.Unwind(&skip_names);
|
unwinder.Unwind(&skip_names, &stack_map->GetSuffixesToIgnore());
|
||||||
|
|
||||||
if (num_ignore_frames >= unwinder.NumFrames()) {
|
if (num_ignore_frames >= unwinder.NumFrames()) {
|
||||||
frames->resize(0);
|
frames->resize(0);
|
||||||
|
|
|
||||||
|
|
@ -107,13 +107,20 @@ public:
|
||||||
return map.end > 0;
|
return map.end > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
void SetSuffixesToIgnore(std::vector<std::string> suffixes) {
|
||||||
|
suffixes_to_ignore_.insert(suffixes_to_ignore_.end(), suffixes.begin(), suffixes.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& GetSuffixesToIgnore() { return suffixes_to_ignore_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
BacktraceMap(pid_t pid);
|
BacktraceMap(pid_t pid);
|
||||||
|
|
||||||
virtual bool ParseLine(const char* line, backtrace_map_t* map);
|
virtual bool ParseLine(const char* line, backtrace_map_t* map);
|
||||||
|
|
||||||
std::deque<backtrace_map_t> maps_;
|
|
||||||
pid_t pid_;
|
pid_t pid_;
|
||||||
|
std::deque<backtrace_map_t> maps_;
|
||||||
|
std::vector<std::string> suffixes_to_ignore_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScopedBacktraceMapIteratorLock {
|
class ScopedBacktraceMapIteratorLock {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
|
|
||||||
#include <unwindstack/Elf.h>
|
#include <unwindstack/Elf.h>
|
||||||
|
|
@ -64,7 +66,8 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, bool ad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldStop(const std::set<std::string>* map_suffixes_to_ignore, std::string& map_name) {
|
static bool ShouldStop(const std::vector<std::string>* map_suffixes_to_ignore,
|
||||||
|
std::string& map_name) {
|
||||||
if (map_suffixes_to_ignore == nullptr) {
|
if (map_suffixes_to_ignore == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -72,11 +75,13 @@ static bool ShouldStop(const std::set<std::string>* map_suffixes_to_ignore, std:
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return map_suffixes_to_ignore->find(map_name.substr(pos + 1)) != map_suffixes_to_ignore->end();
|
|
||||||
|
return std::find(map_suffixes_to_ignore->begin(), map_suffixes_to_ignore->end(),
|
||||||
|
map_name.substr(pos + 1)) != map_suffixes_to_ignore->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unwinder::Unwind(const std::set<std::string>* initial_map_names_to_skip,
|
void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
|
||||||
const std::set<std::string>* map_suffixes_to_ignore) {
|
const std::vector<std::string>* map_suffixes_to_ignore) {
|
||||||
frames_.clear();
|
frames_.clear();
|
||||||
|
|
||||||
bool return_address_attempt = false;
|
bool return_address_attempt = false;
|
||||||
|
|
@ -97,8 +102,8 @@ void Unwinder::Unwind(const std::set<std::string>* initial_map_names_to_skip,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map_info == nullptr || initial_map_names_to_skip == nullptr ||
|
if (map_info == nullptr || initial_map_names_to_skip == nullptr ||
|
||||||
initial_map_names_to_skip->find(basename(map_info->name.c_str())) ==
|
std::find(initial_map_names_to_skip->begin(), initial_map_names_to_skip->end(),
|
||||||
initial_map_names_to_skip->end()) {
|
basename(map_info->name.c_str())) == initial_map_names_to_skip->end()) {
|
||||||
FillInFrame(map_info, elf, rel_pc, adjust_pc);
|
FillInFrame(map_info, elf, rel_pc, adjust_pc);
|
||||||
// Once a frame is added, stop skipping frames.
|
// Once a frame is added, stop skipping frames.
|
||||||
initial_map_names_to_skip = nullptr;
|
initial_map_names_to_skip = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -60,8 +59,8 @@ class Unwinder {
|
||||||
}
|
}
|
||||||
~Unwinder() = default;
|
~Unwinder() = default;
|
||||||
|
|
||||||
void Unwind(const std::set<std::string>* initial_map_names_to_skip = nullptr,
|
void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
|
||||||
const std::set<std::string>* map_suffixes_to_ignore = nullptr);
|
const std::vector<std::string>* map_suffixes_to_ignore = nullptr);
|
||||||
|
|
||||||
size_t NumFrames() { return frames_.size(); }
|
size_t NumFrames() { return frames_.size(); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -308,8 +308,8 @@ TEST_F(UnwinderTest, verify_frames_skipped) {
|
||||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||||
|
|
||||||
Unwinder unwinder(64, &maps_, ®s_, process_memory_);
|
Unwinder unwinder(64, &maps_, ®s_, process_memory_);
|
||||||
std::set<std::string> skip_set{"libunwind.so", "libanother.so"};
|
std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
|
||||||
unwinder.Unwind(&skip_set);
|
unwinder.Unwind(&skip_libs);
|
||||||
|
|
||||||
ASSERT_EQ(3U, unwinder.NumFrames());
|
ASSERT_EQ(3U, unwinder.NumFrames());
|
||||||
|
|
||||||
|
|
@ -572,7 +572,7 @@ TEST_F(UnwinderTest, map_ignore_suffixes) {
|
||||||
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
ElfInterfaceFake::FakePushStepData(StepData(0, 0, true));
|
||||||
|
|
||||||
Unwinder unwinder(64, &maps_, ®s_, process_memory_);
|
Unwinder unwinder(64, &maps_, ®s_, process_memory_);
|
||||||
std::set<std::string> suffixes{"oat"};
|
std::vector<std::string> suffixes{"oat"};
|
||||||
unwinder.Unwind(nullptr, &suffixes);
|
unwinder.Unwind(nullptr, &suffixes);
|
||||||
|
|
||||||
ASSERT_EQ(2U, unwinder.NumFrames());
|
ASSERT_EQ(2U, unwinder.NumFrames());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue