mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2025-12-23 15:54:21 +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
|
|
@ -97,17 +97,6 @@ void Module::InlineOriginMap::SetReference(uint64_t offset,
|
|||
references_[offset] = specification_offset;
|
||||
}
|
||||
|
||||
void Module::InlineOriginMap::AssignFilesToInlineOrigins(
|
||||
const vector<uint64_t>& inline_origin_offsets,
|
||||
Module::File* file) {
|
||||
for (uint64_t offset : inline_origin_offsets)
|
||||
if (references_.find(offset) != references_.end()) {
|
||||
auto origin = inline_origins_.find(references_[offset]);
|
||||
if (origin != inline_origins_.end())
|
||||
origin->second->file = file;
|
||||
}
|
||||
}
|
||||
|
||||
Module::Module(const string& name, const string& os,
|
||||
const string& architecture, const string& id,
|
||||
const string& code_id /* = "" */) :
|
||||
|
|
@ -276,13 +265,18 @@ void Module::AssignSourceIds(
|
|||
line_it != func->lines.end(); ++line_it)
|
||||
line_it->file->source_id = 0;
|
||||
}
|
||||
// Also mark all files cited by inline functions by setting each one's source
|
||||
|
||||
// Also mark all files cited by inline callsite by setting each one's source
|
||||
// id to zero.
|
||||
for (InlineOrigin* origin : inline_origins)
|
||||
auto markInlineFiles = [](unique_ptr<Inline>& in) {
|
||||
// There are some artificial inline functions which don't belong to
|
||||
// any file. Those will have file id -1.
|
||||
if (origin->file)
|
||||
origin->file->source_id = 0;
|
||||
if (in->call_site_file)
|
||||
in->call_site_file->source_id = 0;
|
||||
};
|
||||
for (auto func : functions_) {
|
||||
Inline::InlineDFS(func->inlines, markInlineFiles);
|
||||
}
|
||||
|
||||
// Finally, assign source ids to those files that have been marked.
|
||||
// We could have just assigned source id numbers while traversing
|
||||
|
|
@ -296,15 +290,6 @@ void Module::AssignSourceIds(
|
|||
}
|
||||
}
|
||||
|
||||
static void InlineDFS(
|
||||
vector<unique_ptr<Module::Inline>>& inlines,
|
||||
std::function<void(unique_ptr<Module::Inline>&)> const& forEach) {
|
||||
for (unique_ptr<Module::Inline>& in : inlines) {
|
||||
forEach(in);
|
||||
InlineDFS(in->child_inlines, forEach);
|
||||
}
|
||||
}
|
||||
|
||||
void Module::CreateInlineOrigins(
|
||||
set<InlineOrigin*, InlineOriginCompare>& inline_origins) {
|
||||
// Only add origins that have file and deduplicate origins with same name and
|
||||
|
|
@ -317,7 +302,7 @@ void Module::CreateInlineOrigins(
|
|||
in->origin = *it;
|
||||
};
|
||||
for (Function* func : functions_)
|
||||
InlineDFS(func->inlines, addInlineOrigins);
|
||||
Module::Inline::InlineDFS(func->inlines, addInlineOrigins);
|
||||
int next_id = 0;
|
||||
for (InlineOrigin* origin : inline_origins) {
|
||||
origin->id = next_id++;
|
||||
|
|
@ -381,8 +366,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
|
|||
}
|
||||
// Write out inline origins.
|
||||
for (InlineOrigin* origin : inline_origins) {
|
||||
stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID()
|
||||
<< " " << origin->name << "\n";
|
||||
stream << "INLINE_ORIGIN " << origin->id << " " << origin->name << "\n";
|
||||
if (!stream.good())
|
||||
return ReportError();
|
||||
}
|
||||
|
|
@ -407,12 +391,12 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
|
|||
auto write_inline = [&](unique_ptr<Inline>& in) {
|
||||
stream << "INLINE ";
|
||||
stream << in->inline_nest_level << " " << in->call_site_line << " "
|
||||
<< in->origin->id << hex;
|
||||
<< in->getCallSiteFileID() << " " << in->origin->id << hex;
|
||||
for (const Range& r : in->ranges)
|
||||
stream << " " << (r.address - load_address_) << " " << r.size;
|
||||
stream << dec << "\n";
|
||||
};
|
||||
InlineDFS(func->inlines, write_inline);
|
||||
Module::Inline::InlineDFS(func->inlines, write_inline);
|
||||
if (!stream.good())
|
||||
return ReportError();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue