mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-29 02:35:31 +01:00
Fix incorrect source file name for inlined frames
Processor shows incorrect source file name if a frame have an inlined frame and their source files are different. Consider this example: FILE 0 /tmp/a.h FILE 1 /tmp/a.cpp INLINE_ORIGIN 0 0 foo() FUNC 1110 a 0 main INLINE 0 22 0 1110 7 1110 7 3 0 1117 3 23 1 When querying the address 0x1110, we know this line 0x1110 corresponds to /tmp/a.h line 3 and it's inside a inlined function foo() which is defined at /tmp/a.h and called at line 22. But we don't know at which file it's being called at line 22. So, we will get stacks like this: void foo() /tmp/a.h:3 int main() /tmp/a.h:22 The correct stacks should be this: void foo() /tmp/a.h:3 int main() /tmp/a.cpp:22 In this change: 1. Remove file_id field for INLINE_ORIGIN record. 2. Add call_site_file_id for INLINE record to represents the file where this call being inlined. After adding call_site_file_id to it (as third field), it looks like this: FILE 0 /tmp/a.h FILE 1 /tmp/a.cpp INLINE_ORIGIN 0 foo() FUNC 1110 a 0 main INLINE 0 22 1 0 1110 7 1110 7 3 0 1117 3 23 1 Bug: 1190878 Change-Id: Ibbb697d2f7e1b6ac3208cac6fae4353c8743198d Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3232838 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
71387fc200
commit
54d878abcb
18 changed files with 223 additions and 214 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#ifndef COMMON_LINUX_MODULE_H__
|
||||
#define COMMON_LINUX_MODULE_H__
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
|
|
@ -131,7 +132,7 @@ class Module {
|
|||
};
|
||||
|
||||
struct InlineOrigin {
|
||||
explicit InlineOrigin(StringView name): id(-1), name(name), file(nullptr) {}
|
||||
explicit InlineOrigin(StringView name) : id(-1), name(name) {}
|
||||
|
||||
// A unique id for each InlineOrigin object. INLINE records use the id to
|
||||
// refer to its INLINE_ORIGIN record.
|
||||
|
|
@ -139,10 +140,6 @@ class Module {
|
|||
|
||||
// The inlined function's name.
|
||||
StringView name;
|
||||
|
||||
File* file;
|
||||
|
||||
int getFileID() const { return file ? file->source_id : -1; }
|
||||
};
|
||||
|
||||
// A inlined call site.
|
||||
|
|
@ -150,11 +147,14 @@ class Module {
|
|||
Inline(InlineOrigin* origin,
|
||||
const vector<Range>& ranges,
|
||||
int call_site_line,
|
||||
int call_site_file_id,
|
||||
int inline_nest_level,
|
||||
vector<std::unique_ptr<Inline>> child_inlines)
|
||||
: origin(origin),
|
||||
ranges(ranges),
|
||||
call_site_line(call_site_line),
|
||||
call_site_file_id(call_site_file_id),
|
||||
call_site_file(nullptr),
|
||||
inline_nest_level(inline_nest_level),
|
||||
child_inlines(std::move(child_inlines)) {}
|
||||
|
||||
|
|
@ -165,10 +165,29 @@ class Module {
|
|||
|
||||
int call_site_line;
|
||||
|
||||
// The id is only meanful inside a CU. It's only used for looking up real
|
||||
// File* after scanning a CU.
|
||||
int call_site_file_id;
|
||||
|
||||
File* call_site_file;
|
||||
|
||||
int inline_nest_level;
|
||||
|
||||
// A list of inlines which are children of this inline.
|
||||
vector<std::unique_ptr<Inline>> child_inlines;
|
||||
|
||||
int getCallSiteFileID() const {
|
||||
return call_site_file ? call_site_file->source_id : -1;
|
||||
}
|
||||
|
||||
static void InlineDFS(
|
||||
vector<std::unique_ptr<Module::Inline>>& inlines,
|
||||
std::function<void(std::unique_ptr<Module::Inline>&)> const& forEach) {
|
||||
for (std::unique_ptr<Module::Inline>& in : inlines) {
|
||||
forEach(in);
|
||||
InlineDFS(in->child_inlines, forEach);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef map<uint64_t, InlineOrigin*> InlineOriginByOffset;
|
||||
|
|
@ -182,9 +201,7 @@ class Module {
|
|||
// value of its DW_AT_specification or equals to offset if
|
||||
// DW_AT_specification doesn't exist in that DIE.
|
||||
void SetReference(uint64_t offset, uint64_t specification_offset);
|
||||
void AssignFilesToInlineOrigins(
|
||||
const vector<uint64_t>& inline_origin_offsets,
|
||||
File* file);
|
||||
|
||||
~InlineOriginMap() {
|
||||
for (const auto& iter : inline_origins_) {
|
||||
delete iter.second;
|
||||
|
|
@ -261,10 +278,8 @@ class Module {
|
|||
};
|
||||
|
||||
struct InlineOriginCompare {
|
||||
bool operator() (const InlineOrigin* lhs, const InlineOrigin* rhs) const {
|
||||
if (lhs->getFileID() == rhs->getFileID())
|
||||
return lhs->name < rhs->name;
|
||||
return lhs->getFileID() < rhs->getFileID();
|
||||
bool operator()(const InlineOrigin* lhs, const InlineOrigin* rhs) const {
|
||||
return lhs->name < rhs->name;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue