am c9c401e6: Merge "Move map data into backtrace data proper."

* commit 'c9c401e64ba00e8fa295cae30b2b0035fae1183a':
  Move map data into backtrace data proper.
This commit is contained in:
Christopher Ferris 2015-02-06 23:43:11 +00:00 committed by Android Git Automerger
commit e6ed63e610
11 changed files with 65 additions and 43 deletions

View file

@ -240,12 +240,13 @@ static void dump_stack_segment(
break; break;
} }
const backtrace_map_t* map = backtrace->FindMap(stack_content); backtrace_map_t map;
backtrace->FillInMap(stack_content, &map);
const char* map_name; const char* map_name;
if (!map) { if (BacktraceMap::IsValid(map)) {
map_name = ""; map_name = "";
} else { } else {
map_name = map->name.c_str(); map_name = map.name.c_str();
} }
uintptr_t offset = 0; uintptr_t offset = 0;
std::string func_name(backtrace->GetFunctionName(stack_content, &offset)); std::string func_name(backtrace->GetFunctionName(stack_content, &offset));

View file

@ -39,7 +39,7 @@ struct backtrace_frame_data_t {
uintptr_t pc; // The absolute pc. uintptr_t pc; // The absolute pc.
uintptr_t sp; // The top of the stack. uintptr_t sp; // The top of the stack.
size_t stack_size; // The size of the stack, zero indicate an unknown stack size. size_t stack_size; // The size of the stack, zero indicate an unknown stack size.
const backtrace_map_t* map; // The map associated with the given pc. backtrace_map_t map; // The map associated with the given pc.
std::string func_name; // The function name associated with this pc, NULL if not found. std::string func_name; // The function name associated with this pc, NULL if not found.
uintptr_t func_offset; // pc relative to the start of the function, only valid if func_name is not NULL. uintptr_t func_offset; // pc relative to the start of the function, only valid if func_name is not NULL.
}; };
@ -78,8 +78,8 @@ public:
// If the string is empty, then no valid function name was found. // If the string is empty, then no valid function name was found.
virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset); virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset);
// Find the map associated with the given pc. // Fill in the map data associated with the given pc.
virtual const backtrace_map_t* FindMap(uintptr_t pc); virtual void FillInMap(uintptr_t pc, backtrace_map_t* map);
// Read the data at a specific address. // Read the data at a specific address.
virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0; virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0;

View file

@ -33,6 +33,8 @@
#include <string> #include <string>
struct backtrace_map_t { struct backtrace_map_t {
backtrace_map_t(): start(0), end(0), flags(0) {}
uintptr_t start; uintptr_t start;
uintptr_t end; uintptr_t end;
int flags; int flags;
@ -48,15 +50,16 @@ public:
virtual ~BacktraceMap(); virtual ~BacktraceMap();
// Get the map data structure for the given address. // Fill in the map data structure for the given address.
virtual const backtrace_map_t* Find(uintptr_t addr); virtual void FillIn(uintptr_t addr, backtrace_map_t* map);
// The flags returned are the same flags as used by the mmap call. // The flags returned are the same flags as used by the mmap call.
// The values are PROT_*. // The values are PROT_*.
int GetFlags(uintptr_t pc) { int GetFlags(uintptr_t pc) {
const backtrace_map_t* map = Find(pc); backtrace_map_t map;
if (map) { FillIn(pc, &map);
return map->flags; if (IsValid(map)) {
return map.flags;
} }
return PROT_NONE; return PROT_NONE;
} }
@ -75,6 +78,10 @@ public:
virtual bool Build(); virtual bool Build();
static inline bool IsValid(const backtrace_map_t& map) {
return map.end > 0;
}
protected: protected:
BacktraceMap(pid_t pid); BacktraceMap(pid_t pid);

View file

@ -99,15 +99,15 @@ std::string Backtrace::FormatFrameData(size_t frame_num) {
std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
const char* map_name; const char* map_name;
if (frame->map && !frame->map->name.empty()) { if (BacktraceMap::IsValid(frame->map) && !frame->map.name.empty()) {
map_name = frame->map->name.c_str(); map_name = frame->map.name.c_str();
} else { } else {
map_name = "<unknown>"; map_name = "<unknown>";
} }
uintptr_t relative_pc; uintptr_t relative_pc;
if (frame->map) { if (BacktraceMap::IsValid(frame->map)) {
relative_pc = frame->pc - frame->map->start; relative_pc = frame->pc - frame->map.start;
} else { } else {
relative_pc = frame->pc; relative_pc = frame->pc;
} }
@ -128,8 +128,8 @@ std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) {
return buf; return buf;
} }
const backtrace_map_t* Backtrace::FindMap(uintptr_t pc) { void Backtrace::FillInMap(uintptr_t pc, backtrace_map_t* map) {
return map_->Find(pc); map_->FillIn(pc, map);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -147,8 +147,9 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) {
return false; return false;
} }
const backtrace_map_t* map = FindMap(ptr); backtrace_map_t map;
if (map && map->flags & PROT_READ) { FillInMap(ptr, &map);
if (BacktraceMap::IsValid(map) && map.flags & PROT_READ) {
*out_value = *reinterpret_cast<word_t*>(ptr); *out_value = *reinterpret_cast<word_t*>(ptr);
return true; return true;
} else { } else {

View file

@ -37,8 +37,8 @@ public:
inline pid_t Pid() { return backtrace_obj_->Pid(); } inline pid_t Pid() { return backtrace_obj_->Pid(); }
inline pid_t Tid() { return backtrace_obj_->Tid(); } inline pid_t Tid() { return backtrace_obj_->Tid(); }
inline const backtrace_map_t* FindMap(uintptr_t addr) { inline void FillInMap(uintptr_t addr, backtrace_map_t* map) {
return backtrace_obj_->FindMap(addr); backtrace_obj_->FillInMap(addr, map);
} }
inline std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) { inline std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) {
return backtrace_obj_->GetFunctionName(pc, offset); return backtrace_obj_->GetFunctionName(pc, offset);

View file

@ -37,14 +37,15 @@ BacktraceMap::BacktraceMap(pid_t pid) : pid_(pid) {
BacktraceMap::~BacktraceMap() { BacktraceMap::~BacktraceMap() {
} }
const backtrace_map_t* BacktraceMap::Find(uintptr_t addr) { void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) {
for (BacktraceMap::const_iterator it = begin(); for (BacktraceMap::const_iterator it = begin();
it != end(); ++it) { it != end(); ++it) {
if (addr >= it->start && addr < it->end) { if (addr >= it->start && addr < it->end) {
return &*it; *map = *it;
return;
} }
} }
return NULL; *map = {};
} }
bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) { bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) {

View file

@ -137,9 +137,8 @@ bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, bool within_hand
if (!within_handler) { if (!within_handler) {
frame->func_name = GetFunctionName(frame->pc, &frame->func_offset); frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
frame->map = FindMap(frame->pc); FillInMap(frame->pc, &frame->map);
} else { } else {
frame->map = NULL;
frame->func_offset = 0; frame->func_offset = 0;
} }
num_frames++; num_frames++;

View file

@ -113,18 +113,17 @@ bool UnwindMapLocal::Build() {
return (map_created_ = (unw_map_local_create() == 0)) && GenerateMap();; return (map_created_ = (unw_map_local_create() == 0)) && GenerateMap();;
} }
const backtrace_map_t* UnwindMapLocal::Find(uintptr_t addr) { void UnwindMapLocal::FillIn(uintptr_t addr, backtrace_map_t* map) {
const backtrace_map_t* map = BacktraceMap::Find(addr); BacktraceMap::FillIn(addr, map);
if (!map) { if (!IsValid(*map)) {
// Check to see if the underlying map changed and regenerate the map // Check to see if the underlying map changed and regenerate the map
// if it did. // if it did.
if (unw_map_local_cursor_valid(&map_cursor_) < 0) { if (unw_map_local_cursor_valid(&map_cursor_) < 0) {
if (GenerateMap()) { if (GenerateMap()) {
map = BacktraceMap::Find(addr); BacktraceMap::FillIn(addr, map);
} }
} }
} }
return map;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

View file

@ -45,7 +45,7 @@ public:
virtual bool Build(); virtual bool Build();
virtual const backtrace_map_t* Find(uintptr_t addr); virtual void FillIn(uintptr_t addr, backtrace_map_t* map);
protected: protected:
virtual bool GenerateMap(); virtual bool GenerateMap();

View file

@ -106,7 +106,7 @@ bool UnwindPtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
frame->func_name = GetFunctionName(frame->pc, &frame->func_offset); frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
frame->map = FindMap(frame->pc); FillInMap(frame->pc, &frame->map);
num_frames++; num_frames++;
} else { } else {

View file

@ -688,6 +688,25 @@ TEST(libbacktrace, simultaneous_maps) {
delete map3; delete map3;
} }
TEST(libbacktrace, fillin_erases) {
BacktraceMap* back_map = BacktraceMap::Create(getpid());
backtrace_map_t map;
map.start = 1;
map.end = 3;
map.flags = 1;
map.name = "Initialized";
back_map->FillIn(0, &map);
delete back_map;
ASSERT_FALSE(BacktraceMap::IsValid(map));
ASSERT_EQ(static_cast<uintptr_t>(0), map.start);
ASSERT_EQ(static_cast<uintptr_t>(0), map.end);
ASSERT_EQ(0, map.flags);
ASSERT_EQ("", map.name);
}
TEST(libbacktrace, format_test) { TEST(libbacktrace, format_test) {
UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD)); UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), BACKTRACE_CURRENT_THREAD));
ASSERT_TRUE(backtrace.get() != NULL); ASSERT_TRUE(backtrace.get() != NULL);
@ -697,13 +716,8 @@ TEST(libbacktrace, format_test) {
frame.pc = 2; frame.pc = 2;
frame.sp = 0; frame.sp = 0;
frame.stack_size = 0; frame.stack_size = 0;
frame.map = NULL;
frame.func_offset = 0; frame.func_offset = 0;
backtrace_map_t map;
map.start = 0;
map.end = 0;
// Check no map set. // Check no map set.
frame.num = 1; frame.num = 1;
#if defined(__LP64__) #if defined(__LP64__)
@ -714,8 +728,8 @@ TEST(libbacktrace, format_test) {
backtrace->FormatFrameData(&frame)); backtrace->FormatFrameData(&frame));
// Check map name empty, but exists. // Check map name empty, but exists.
frame.map = &map; frame.map.start = 1;
map.start = 1; frame.map.end = 1;
#if defined(__LP64__) #if defined(__LP64__)
EXPECT_EQ("#01 pc 0000000000000001 <unknown>", EXPECT_EQ("#01 pc 0000000000000001 <unknown>",
#else #else
@ -726,9 +740,9 @@ TEST(libbacktrace, format_test) {
// Check relative pc is set and map name is set. // Check relative pc is set and map name is set.
frame.pc = 0x12345679; frame.pc = 0x12345679;
frame.map = &map; frame.map.name = "MapFake";
map.name = "MapFake"; frame.map.start = 1;
map.start = 1; frame.map.end = 1;
#if defined(__LP64__) #if defined(__LP64__)
EXPECT_EQ("#01 pc 0000000012345678 MapFake", EXPECT_EQ("#01 pc 0000000012345678 MapFake",
#else #else