aboutsummaryrefslogtreecommitdiff
path: root/src/processor/fast_source_line_resolver.cc
diff options
context:
space:
mode:
authorZequan Wu <zequanwu@google.com>2021-11-30 16:29:00 -0800
committerJoshua Peraza <jperaza@chromium.org>2021-12-01 00:31:39 +0000
commit0ae29c99d1a0abed797ad78e5e061f4e2cb9c1cb (patch)
tree788056bdbe838728bf5346e1f1ae36c8d166c7c0 /src/processor/fast_source_line_resolver.cc
parentc472afe0643b96d09157f92fd0bb699ef5d752b9 (diff)
downloadgoogle-breakpad-0ae29c99d1a0abed797ad78e5e061f4e2cb9c1cb.tar.gz
Add serialization of inlines and inline origins for FastSourceLineResolver so that it can construct inlined frames later.
Bug: 1190878 Change-Id: Ie3b0f2f44e04e790501ea54680fe223974c750ab Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3294126 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Diffstat (limited to 'src/processor/fast_source_line_resolver.cc')
-rw-r--r--src/processor/fast_source_line_resolver.cc73
1 files changed, 69 insertions, 4 deletions
diff --git a/src/processor/fast_source_line_resolver.cc b/src/processor/fast_source_line_resolver.cc
index 31786460..374b06cf 100644
--- a/src/processor/fast_source_line_resolver.cc
+++ b/src/processor/fast_source_line_resolver.cc
@@ -49,9 +49,8 @@
#include "processor/module_factory.h"
#include "processor/simple_serializer-inl.h"
-using std::map;
-using std::make_pair;
-using std::vector;
+using std::deque;
+using std::unique_ptr;
namespace google_breakpad {
@@ -101,6 +100,10 @@ void FastSourceLineResolver::Module::LookupAddress(
frame->source_line = line->line;
frame->source_line_base = frame->module->base_address() + line_base;
}
+ // Check if this is inlined function call.
+ if (inlined_frames) {
+ ConstructInlineFrames(frame, address, func->inlines, inlined_frames);
+ }
} else if (public_symbols_.Retrieve(address,
public_symbol_ptr, &public_address) &&
(!func_ptr || public_address > function_base)) {
@@ -110,6 +113,68 @@ void FastSourceLineResolver::Module::LookupAddress(
}
}
+void FastSourceLineResolver::Module::ConstructInlineFrames(
+ StackFrame* frame,
+ MemAddr address,
+ const StaticContainedRangeMap<MemAddr, char>& inline_map,
+ std::deque<std::unique_ptr<StackFrame>>* inlined_frames) const {
+ std::vector<const char*> inline_ptrs;
+ if (!inline_map.RetrieveRanges(address, inline_ptrs)) {
+ return;
+ }
+
+ for (const char* inline_ptr : inline_ptrs) {
+ scoped_ptr<Inline> in(new Inline);
+ in.get()->CopyFrom(inline_ptr);
+ unique_ptr<StackFrame> new_frame =
+ unique_ptr<StackFrame>(new StackFrame(*frame));
+ auto origin_iter = inline_origins_.find(in->origin_id);
+ if (origin_iter != inline_origins_.end()) {
+ scoped_ptr<InlineOrigin> origin(new InlineOrigin);
+ origin.get()->CopyFrom(origin_iter.GetValuePtr());
+ new_frame->function_name = origin->name;
+ } else {
+ new_frame->function_name = "<name omitted>";
+ }
+
+ // Store call site file and line in current frame, which will be updated
+ // later.
+ new_frame->source_line = in->call_site_line;
+ if (in->has_call_site_file_id) {
+ auto file_iter = files_.find(in->call_site_file_id);
+ if (file_iter != files_.end()) {
+ new_frame->source_file_name = file_iter.GetValuePtr();
+ }
+ }
+
+ // Use the starting adress of the inlined range as inlined function base.
+ new_frame->function_base = new_frame->module->base_address();
+ for (const auto& range : in->inline_ranges) {
+ if (address >= range.first && address < range.first + range.second) {
+ new_frame->function_base += range.first;
+ break;
+ }
+ }
+ new_frame->trust = StackFrame::FRAME_TRUST_INLINE;
+
+ // The inlines vector has an order from innermost entry to outermost entry.
+ // By push_back, we will have inlined_frames with the same order.
+ inlined_frames->push_back(std::move(new_frame));
+ }
+
+ // Update the source file and source line for each inlined frame.
+ if (!inlined_frames->empty()) {
+ string parent_frame_source_file_name = frame->source_file_name;
+ int parent_frame_source_line = frame->source_line;
+ frame->source_file_name = inlined_frames->back()->source_file_name;
+ frame->source_line = inlined_frames->back()->source_line;
+ for (unique_ptr<StackFrame>& inlined_frame : *inlined_frames) {
+ std::swap(inlined_frame->source_file_name, parent_frame_source_file_name);
+ std::swap(inlined_frame->source_line, parent_frame_source_line);
+ }
+ }
+}
+
// WFI: WindowsFrameInfo.
// Returns a WFI object reading from a raw memory chunk of data
WindowsFrameInfo FastSourceLineResolver::CopyWFI(const char* raw) {
@@ -184,7 +249,7 @@ bool FastSourceLineResolver::Module::LoadMapFromMemory(
cfi_initial_rules_ =
StaticRangeMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
cfi_delta_rules_ = StaticMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
-
+ inline_origins_ = StaticMap<int, char>(mem_buffer + offsets[map_id++]);
return true;
}