mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-02-19 16:49:40 +00:00
Add support to process INLINE records in symbol files
This adds the support to process INLINE and INLINE_ORIGIN records in symbol files and to generate inlined frames using those records if possible. Bug: 1190878 Change-Id: Ia0b6d56c9de37cf818d9bb6842d58c9b68f235b2 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3024690 Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/using_std_string.h"
|
||||
#include "google_breakpad/processor/source_line_resolver_base.h"
|
||||
@@ -84,6 +85,8 @@ class BasicSourceLineResolver : public SourceLineResolverBase {
|
||||
// Helper class, containing useful methods for parsing of Breakpad symbol files.
|
||||
class SymbolParseHelper {
|
||||
public:
|
||||
using MemAddr = SourceLineResolverInterface::MemAddr;
|
||||
|
||||
// Parses a |file_line| declaration. Returns true on success.
|
||||
// Format: FILE <id> <filename>.
|
||||
// Notice, that this method modifies the input |file_line| which is why it
|
||||
@@ -94,6 +97,32 @@ class SymbolParseHelper {
|
||||
long* index, // out
|
||||
char** filename); // out
|
||||
|
||||
// Parses a |inline_origin_line| declaration. Returns true on success.
|
||||
// Format: INLINE_ORIGIN <origin_id> <file_id> <name>.
|
||||
// Notice, that this method modifies the input |inline_origin_line| which is
|
||||
// why it can't be const. On success, <origin_id>, <file_id> and <name> are
|
||||
// stored in |*origin_id|, |*file_id|, and |*name|. No allocation is
|
||||
// done, |*name| simply points inside |inline_origin_line|.
|
||||
static bool ParseInlineOrigin(char* inline_origin_line, // in
|
||||
long* origin_id, // out
|
||||
long* file_id, // out
|
||||
char** name); // out
|
||||
|
||||
// Parses a |inline| declaration. Returns true on success.
|
||||
// Format: INLINE <inline_nest_level> <call_site_line> <origin_id> <address>
|
||||
// <size> ....
|
||||
// Notice, that this method modifies the input |inline|
|
||||
// which is why it can't be const. On success, <inline_nest_level>,
|
||||
// <call_site_line> and <origin_id> are stored in |*inline_nest_level|,
|
||||
// |*call_site_line|, and |*origin_id|, and all pairs of (<address>, <size>)
|
||||
// are added into ranges .
|
||||
static bool ParseInline(
|
||||
char* inline_line, // in
|
||||
long* inline_nest_level, // out
|
||||
long* call_site_line, // out
|
||||
long* origin_id, // out
|
||||
std::vector<std::pair<MemAddr, MemAddr>>* ranges); // out
|
||||
|
||||
// Parses a |function_line| declaration. Returns true on success.
|
||||
// Format: FUNC [<multiple>] <address> <size> <stack_param_size> <name>.
|
||||
// Notice, that this method modifies the input |function_line| which is why it
|
||||
|
||||
@@ -84,11 +84,15 @@ class SourceLineResolverBase : public SourceLineResolverInterface {
|
||||
virtual void UnloadModule(const CodeModule* module);
|
||||
virtual bool HasModule(const CodeModule* module);
|
||||
virtual bool IsModuleCorrupt(const CodeModule* module);
|
||||
virtual void FillSourceLineInfo(StackFrame* frame);
|
||||
virtual void FillSourceLineInfo(
|
||||
StackFrame* frame,
|
||||
std::vector<std::unique_ptr<StackFrame>>* inlined_frames);
|
||||
virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame);
|
||||
virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame);
|
||||
|
||||
// Nested structs and classes.
|
||||
struct InlineOrigin;
|
||||
struct Inline;
|
||||
struct Line;
|
||||
struct Function;
|
||||
struct PublicSymbol;
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
#ifndef GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__
|
||||
#define GOOGLE_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H__
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/using_std_string.h"
|
||||
#include "google_breakpad/common/breakpad_types.h"
|
||||
@@ -91,8 +93,12 @@ class SourceLineResolverInterface {
|
||||
|
||||
// Fills in the function_base, function_name, source_file_name,
|
||||
// and source_line fields of the StackFrame. The instruction and
|
||||
// module_name fields must already be filled in.
|
||||
virtual void FillSourceLineInfo(StackFrame* frame) = 0;
|
||||
// module_name fields must already be filled in. If inlined_frames is not
|
||||
// nullptr, it will try to construct inlined frames by adding them into
|
||||
// inlined_frames in an order from outermost frame to inner most frame.
|
||||
virtual void FillSourceLineInfo(
|
||||
StackFrame* frame,
|
||||
std::vector<std::unique_ptr<StackFrame>>* inlined_frames) = 0;
|
||||
|
||||
// If Windows stack walking information is available covering
|
||||
// FRAME's instruction address, return a WindowsFrameInfo structure
|
||||
|
||||
@@ -51,7 +51,8 @@ struct StackFrame {
|
||||
FRAME_TRUST_FP, // Derived from frame pointer
|
||||
FRAME_TRUST_CFI, // Derived from call frame info
|
||||
FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker.
|
||||
FRAME_TRUST_CONTEXT // Given as instruction pointer in a context
|
||||
FRAME_TRUST_CONTEXT, // Given as instruction pointer in a context
|
||||
FRAME_TRUST_INLINE // Found by inline records in symbol files.
|
||||
};
|
||||
|
||||
StackFrame()
|
||||
@@ -60,9 +61,9 @@ struct StackFrame {
|
||||
function_name(),
|
||||
function_base(),
|
||||
source_file_name(),
|
||||
source_line(),
|
||||
source_line(0),
|
||||
source_line_base(),
|
||||
trust(FRAME_TRUST_NONE) {}
|
||||
trust(FRAME_TRUST_NONE){}
|
||||
virtual ~StackFrame() {}
|
||||
|
||||
// Return a string describing how this stack frame was found
|
||||
@@ -81,6 +82,8 @@ struct StackFrame {
|
||||
return "previous frame's frame pointer";
|
||||
case StackFrame::FRAME_TRUST_SCAN:
|
||||
return "stack scanning";
|
||||
case StackFrame::FRAME_TRUST_INLINE:
|
||||
return "inline record";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@@ -35,8 +35,10 @@
|
||||
#ifndef GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__
|
||||
#define GOOGLE_BREAKPAD_PROCESSOR_STACK_FRAME_SYMBOLIZER_H__
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/using_std_string.h"
|
||||
#include "google_breakpad/common/breakpad_types.h"
|
||||
@@ -79,7 +81,8 @@ class StackFrameSymbolizer {
|
||||
const CodeModules* modules,
|
||||
const CodeModules* unloaded_modules,
|
||||
const SystemInfo* system_info,
|
||||
StackFrame* stack_frame);
|
||||
StackFrame* stack_frame,
|
||||
std::vector<std::unique_ptr<StackFrame>>* inlined_frames);
|
||||
|
||||
virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user