LLVM 22.0.0git
BacktraceTools.cpp
Go to the documentation of this file.
1//===------- BacktraceTools.cpp - Backtrace symbolication tools ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/DenseMap.h"
11#include "llvm/ADT/StringMap.h"
16
17namespace llvm::orc {
18
19Expected<std::shared_ptr<SymbolTableDumpPlugin>>
21 std::error_code EC;
22 auto P = std::make_shared<SymbolTableDumpPlugin>(Path, EC);
23 if (EC)
24 return createFileError(Path, EC);
25 return P;
26}
27
29 std::error_code &EC)
30 : OutputStream(Path, EC) {}
31
35
36 Config.PostAllocationPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
37 std::scoped_lock<std::mutex> Lock(DumpMutex);
38
39 OutputStream << "\"" << G.getName() << "\"\n";
40 for (auto &Sec : G.sections()) {
41 // NoAlloc symbols don't exist in the executing process, so can't
42 // contribute to symbolication. (Note: We leave Finalize-liftime symbols
43 // in for now in case of crashes during finalization, but we should
44 // probably make this optional).
45 if (Sec.getMemLifetime() == MemLifetime::NoAlloc)
46 continue;
47
48 // Write out named symbols. Anonymous symbols are skipped, since they
49 // don't add any information for symbolication purposes.
50 for (auto *Sym : Sec.symbols()) {
51 if (Sym->hasName())
52 OutputStream << formatv("{0:x}", Sym->getAddress().getValue()) << " "
53 << Sym->getName() << "\n";
54 }
55 }
56
57 OutputStream.flush();
58 return Error::success();
59 });
60}
61
63 auto MB = MemoryBuffer::getFile(Path);
64 if (!MB)
65 return createFileError(Path, MB.getError());
66
67 return DumpedSymbolTable(std::move(*MB));
68}
69
70DumpedSymbolTable::DumpedSymbolTable(std::unique_ptr<MemoryBuffer> SymtabBuffer)
71 : SymtabBuffer(std::move(SymtabBuffer)) {
72 parseBuffer();
73}
74
75void DumpedSymbolTable::parseBuffer() {
76 // Read the symbol table file
78 SymtabBuffer->getBuffer().split(Rows, '\n');
79
80 StringRef CurGraph = "<unidentified>";
81 for (auto Row : Rows) {
82 Row = Row.trim();
83 if (Row.empty())
84 continue;
85
86 // Check for graph name line (enclosed in quotes)
87 if (Row.starts_with("\"") && Row.ends_with("\"")) {
88 CurGraph = Row.trim('"');
89 continue;
90 }
91
92 // Parse "address symbol_name" lines, ignoring malformed lines.
93 size_t SpacePos = Row.find(' ');
94 if (SpacePos == StringRef::npos)
95 continue;
96
97 StringRef AddrStr = Row.substr(0, SpacePos);
98 StringRef SymName = Row.substr(SpacePos + 1);
99
100 uint64_t Addr;
101 if (AddrStr.starts_with("0x"))
102 AddrStr = AddrStr.drop_front(2);
103 if (AddrStr.getAsInteger(16, Addr))
104 continue; // Skip malformed lines
105
106 SymbolInfos[Addr] = {SymName, CurGraph};
107 }
108}
109
111 // Symbolicate the backtrace by replacing rows with empty symbol names
112 SmallVector<StringRef, 0> BacktraceRows;
113 Backtrace.split(BacktraceRows, '\n');
114
115 std::string Result;
117 for (auto Row : BacktraceRows) {
118 // Look for a row ending with a hex number. If there's only one column, or
119 // if the last column is not a hex number, then just reproduce the input
120 // row.
121 auto [RowStart, AddrCol] = Row.rtrim().rsplit(' ');
122 auto AddrStr = AddrCol.starts_with("0x") ? AddrCol.drop_front(2) : AddrCol;
123
124 uint64_t Addr;
125 if (AddrStr.empty() || AddrStr.getAsInteger(16, Addr)) {
126 Out << Row << "\n";
127 continue;
128 }
129
130 // Search for the address
131 auto I = SymbolInfos.upper_bound(Addr);
132
133 // If no JIT symbol entry within 2Gb then skip.
134 if (I == SymbolInfos.begin() || (Addr - std::prev(I)->first >= 1U << 31)) {
135 Out << Row << "\n";
136 continue;
137 }
138
139 // Found a symbol. Output modified line.
140 auto &[SymAddr, SymInfo] = *std::prev(I);
141 Out << RowStart << " " << AddrCol << " " << SymInfo.SymName;
142 if (auto Delta = Addr - SymAddr)
143 Out << " + " << formatv("{0}", Delta);
144 Out << " (" << SymInfo.GraphName << ")\n";
145 }
146
147 return Result;
148}
149
150} // namespace llvm::orc
This file defines the StringMap class.
This file defines the DenseMap class.
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define P(N)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:712
static constexpr size_t npos
Definition StringRef.h:57
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition StringRef.h:826
LLVM_ABI std::string symbolicate(StringRef Backtrace)
Given a backtrace, try to symbolicate any unsymbolicated lines using the symbol addresses in the dump...
static Expected< DumpedSymbolTable > Create(StringRef Path)
Create a DumpedSymbolTable from the given path.
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition Core.h:593
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::PassConfiguration &Config) override
SymbolTableDumpPlugin(StringRef Path, std::error_code &EC)
Create a SymbolTableDumpPlugin.
static Expected< std::shared_ptr< SymbolTableDumpPlugin > > Create(StringRef Path)
Create a SymbolTableDumpPlugin that will append symbol information to the file at the given path.
A raw_ostream that writes to an std::string.
@ NoAlloc
NoAlloc memory should not be allocated by the JITLinkMemoryManager at all.
Definition MemoryFlags.h:88
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1399
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1915
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...