LLVM 24.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
13
14namespace llvm::orc {
15
16Expected<std::shared_ptr<SymbolTableDumpPlugin>>
18 std::error_code EC;
19 auto P = std::make_shared<SymbolTableDumpPlugin>(Path, EC);
20 if (EC)
21 return createFileError(Path, EC);
22 return P;
23}
24
26 std::error_code &EC)
27 : OutputStream(Path, EC) {}
28
32
33 Config.PostAllocationPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
34 std::scoped_lock<std::mutex> Lock(DumpMutex);
35
36 OutputStream << "\"" << G.getName() << "\"\n";
37 for (auto &Sec : G.sections()) {
38 // NoAlloc symbols don't exist in the executing process, so can't
39 // contribute to symbolication. (Note: We leave Finalize-liftime symbols
40 // in for now in case of crashes during finalization, but we should
41 // probably make this optional).
42 if (Sec.getMemLifetime() == MemLifetime::NoAlloc)
43 continue;
44
45 // Write out named symbols. Anonymous symbols are skipped, since they
46 // don't add any information for symbolication purposes.
47 for (auto *Sym : Sec.symbols()) {
48 if (Sym->hasName())
49 OutputStream << formatv("{0:x}", Sym->getAddress().getValue()) << " "
50 << Sym->getName() << "\n";
51 }
52 }
53
54 OutputStream.flush();
55 return Error::success();
56 });
57}
58
60 auto MB = MemoryBuffer::getFile(Path);
61 if (!MB)
62 return createFileError(Path, MB.getError());
63
64 return DumpedSymbolTable(std::move(*MB));
65}
66
67DumpedSymbolTable::DumpedSymbolTable(std::unique_ptr<MemoryBuffer> SymtabBuffer)
68 : SymtabBuffer(std::move(SymtabBuffer)) {
69 parseBuffer();
70}
71
72void DumpedSymbolTable::parseBuffer() {
73 // Read the symbol table file
75 SymtabBuffer->getBuffer().split(Rows, '\n');
76
77 StringRef CurGraph = "<unidentified>";
78 for (auto Row : Rows) {
79 Row = Row.trim();
80 if (Row.empty())
81 continue;
82
83 // Check for graph name line (enclosed in quotes)
84 if (Row.starts_with("\"") && Row.ends_with("\"")) {
85 CurGraph = Row.trim('"');
86 continue;
87 }
88
89 // Parse "address symbol_name" lines, ignoring malformed lines.
90 size_t SpacePos = Row.find(' ');
91 if (SpacePos == StringRef::npos)
92 continue;
93
94 StringRef AddrStr = Row.substr(0, SpacePos);
95 StringRef SymName = Row.substr(SpacePos + 1);
96
97 uint64_t Addr;
98 if (AddrStr.starts_with("0x"))
99 AddrStr = AddrStr.drop_front(2);
100 if (AddrStr.getAsInteger(16, Addr))
101 continue; // Skip malformed lines
102
103 SymbolInfos[Addr] = {SymName, CurGraph};
104 }
105}
106
108 // Symbolicate the backtrace by replacing rows with empty symbol names
109 SmallVector<StringRef, 0> BacktraceRows;
110 Backtrace.split(BacktraceRows, '\n');
111
112 std::string Result;
114 for (auto Row : BacktraceRows) {
115 // Look for a row ending with a hex number. If there's only one column, or
116 // if the last column is not a hex number, then just reproduce the input
117 // row.
118 auto [RowStart, AddrCol] = Row.rtrim().rsplit(' ');
119 auto AddrStr = AddrCol.starts_with("0x") ? AddrCol.drop_front(2) : AddrCol;
120
121 uint64_t Addr;
122 if (AddrStr.empty() || AddrStr.getAsInteger(16, Addr)) {
123 Out << Row << "\n";
124 continue;
125 }
126
127 // Search for the address
128 auto I = SymbolInfos.upper_bound(Addr);
129
130 // If no JIT symbol entry within 2Gb then skip.
131 if (I == SymbolInfos.begin() || (Addr - std::prev(I)->first >= 1U << 31)) {
132 Out << Row << "\n";
133 continue;
134 }
135
136 // Found a symbol. Output modified line.
137 auto &[SymAddr, SymInfo] = *std::prev(I);
138 Out << RowStart << " " << AddrCol << " " << SymInfo.SymName;
139 if (auto Delta = Addr - SymAddr)
140 Out << " + " << formatv("{0}", Delta);
141 Out << " (" << SymInfo.GraphName << ")\n";
142 }
143
144 return Result;
145}
146
147} // namespace llvm::orc
unsigned uint64_t
#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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
static constexpr size_t npos
Definition StringRef.h:58
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition StringRef.h:850
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:349
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:1415
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:1917
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
SymInfo contains information about symbol: it's address and section index which is -1LL for absolute ...