19#include "llvm/Config/llvm-config.h"
47struct CreateDisableSymbolication {
50 "disable-symbolication",
51 cl::desc(
"Disable symbolizing crash backtraces."),
55struct CreateCrashDiagnosticsDir {
59 cl::desc(
"Directory for crash diagnostic files."),
69 *DisableSymbolication;
91static std::array<CallbackAndCookie, MaxSignalHandlerCallbacks> &
93 static std::array<CallbackAndCookie, MaxSignalHandlerCallbacks> callbacks;
105 if (!RunMe.Flag.compare_exchange_strong(
Expected, Desired))
107 (*RunMe.Callback)(RunMe.Cookie);
108 RunMe.Callback =
nullptr;
109 RunMe.Cookie =
nullptr;
120 if (!SetMe.Flag.compare_exchange_strong(
Expected, Desired))
122 SetMe.Callback = FnPtr;
123 SetMe.Cookie = Cookie;
131 const char **Modules, intptr_t *Offsets,
132 const char *MainExecutableName,
139 unsigned PtrWidth = 2 + 2 *
sizeof(
void *);
154std::optional<SmallVector<std::pair<unsigned, std::string>, 0>>
156 const char *MainExecutableName,
157 const std::string &LLVMSymbolizerPath) {
163 Offsets.data(), MainExecutableName, StrPool))
174 for (
unsigned AddrIdx = 0; AddrIdx < AddressCount; AddrIdx++) {
175 if (Modules[AddrIdx])
176 Input << Modules[AddrIdx] <<
" " << (
void *)Offsets[AddrIdx] <<
"\n";
180 std::optional<StringRef> Redirects[] = {InputFile.
str(), OutputFile.
str(),
182 StringRef Args[] = {
"llvm-symbolizer",
"--functions=linkage",
"--inlining",
187 "--relative-address",
199 StringRef Output = OutputBuf.get()->getBuffer();
201 Output.
split(Lines,
"\n");
202 auto *CurLine = Lines.begin();
212 for (
unsigned AddrIdx = 0; AddrIdx < AddressCount; AddrIdx++) {
213 if (!Modules[AddrIdx]) {
214 auto &SymbolizedFrame = Result.emplace_back(std::make_pair(AddrIdx,
""));
222 if (CurLine == Lines.end())
225 if (FunctionName.
empty())
227 auto &SymbolizedFrame = Result.emplace_back(std::make_pair(AddrIdx,
""));
229 OS <<
format_ptr(AddressList[AddrIdx]) <<
' ';
231 OS << FunctionName <<
' ';
232 if (CurLine == Lines.end())
238 OS <<
"(" << Modules[AddrIdx] <<
'+' <<
format_hex(Offsets[AddrIdx], 0)
250 }
else if (!Argv0.empty()) {
253 LLVMSymbolizerPathOrErr =
256 if (!LLVMSymbolizerPathOrErr)
258 return LLVMSymbolizerPathOrErr;
269 if (Argv0.
contains(
"llvm-symbolizer"))
277 if (!LLVMSymbolizerPathOrErr)
279 const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
283 std::string MainExecutableName =
288 StackTrace,
Depth, MainExecutableName.c_str(), LLVMSymbolizerPath);
289 if (!SymbolizedAddressesOpt)
291 for (
unsigned FrameNo = 0; FrameNo < SymbolizedAddressesOpt->size();
294 <<
' ' << (*SymbolizedAddressesOpt)[FrameNo].second <<
'\n';
299#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
300void sys::symbolizeAddresses(AddressSet &Addresses,
301 SymbolizedAddressMap &SymbolizedAddresses) {
303 "Debugify origin stacktraces require symbolization to be enabled.");
311 if (AddressList.empty())
318 if (!LLVMSymbolizerPathOrErr)
320 const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
326 auto SymbolizedAddressesOpt =
328 MainExecutableName.c_str(), LLVMSymbolizerPath);
329 if (!SymbolizedAddressesOpt)
331 for (
auto SymbolizedFrame : *SymbolizedAddressesOpt) {
333 SymbolizedAddresses[AddressList[SymbolizedFrame.first]];
334 SymbolizedAddrs.
push_back(SymbolizedFrame.second);
349 std::string MainExecutableName =
355 OS <<
format(
"{{{bt:%d:%#016x}}}\n",
I, StackTrace[
I]);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ATTRIBUTE_USED
Provides ErrorOr<T> smart pointer.
static FormattedNumber format_ptr(void *PC)
Format a pointer value as hexadecimal.
constexpr char DisableSymbolizationEnv[]
static LLVM_ATTRIBUTE_USED bool printSymbolizedStackTrace(StringRef Argv0, void **StackTrace, int Depth, llvm::raw_ostream &OS)
Helper that launches llvm-symbolizer and symbolizes a backtrace.
static std::array< CallbackAndCookie, MaxSignalHandlerCallbacks > & CallBacksToRun()
static bool findModulesAndOffsets(void **StackTrace, int Depth, const char **Modules, intptr_t *Offsets, const char *MainExecutableName, StringSaver &StrPool)
static bool DisableSymbolicationFlag
static ManagedStatic< std::string > CrashDiagnosticsDirectory
ErrorOr< std::string > getLLVMSymbolizerPath(StringRef Argv0={})
static constexpr size_t MaxSignalHandlerCallbacks
constexpr char LLVMSymbolizerPathEnv[]
static bool printMarkupContext(raw_ostream &OS, const char *MainExecutableName)
std::optional< SmallVector< std::pair< unsigned, std::string >, 0 > > collectAddressSymbols(void **AddressList, unsigned AddressCount, const char *MainExecutableName, const std::string &LLVMSymbolizerPath)
Reads a file Filename written by llvm-symbolizer containing function names and source locations for t...
static LLVM_ATTRIBUTE_USED bool printMarkupStackTrace(StringRef Argv0, void **StackTrace, int Depth, raw_ostream &OS)
static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)
constexpr char EnableSymbolizerMarkupEnv[]
Represents either an error or a value T.
Tagged union holding either a T or a Error.
FileRemover - This class is a simple object meant to be stack allocated.
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
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,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
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.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
A raw_ostream that writes to a file descriptor.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
LocationClass< Ty > location(Ty &L)
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI std::string getMainExecutable(const char *argv0, void *MainExecAddr)
Return the path to the main executable, given the value of argv[0] from program startup and the addre...
LLVM_ABI std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
ScopedSetting scopedDisable()
LLVM_ABI ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
LLVM_ABI void RunSignalHandlers()
LLVM_ABI int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, std::optional< ArrayRef< StringRef > > Env=std::nullopt, ArrayRef< std::optional< StringRef > > Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, std::optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
void(*)(void *) SignalHandlerCallback
This is an optimization pass for GlobalISel generic memory operations.
FormattedString right_justify(StringRef Str, unsigned Width)
right_justify - add spaces before string so total output is Width characters.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
void initSignalsOptions()
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
sys::SignalHandlerCallback Callback
std::atomic< Status > Flag