LLVM: lib/Support/Signals.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

17

19#include "llvm/Config/llvm-config.h"

32#include

33#include

34

35

36

37

38

39

40using namespace llvm;

41

42

45namespace {

46struct CreateDisableSymbolication {

47 static void *call() {

49 "disable-symbolication",

50 cl::desc("Disable symbolizing crash backtraces."),

52 }

53};

54struct CreateCrashDiagnosticsDir {

55 static void *call() {

58 cl::desc("Directory for crash diagnostic files."),

60 }

61};

62}

65 DisableSymbolication;

67 CrashDiagnosticsDir;

68 *DisableSymbolication;

69 *CrashDiagnosticsDir;

70}

71

75

76

77

78

83 std::atomic Flag;

84};

85

87

88

89

90static std::array<CallbackAndCookie, MaxSignalHandlerCallbacks> &

92 static std::array<CallbackAndCookie, MaxSignalHandlerCallbacks> callbacks;

93 return callbacks;

94}

95

96

101 if (!RunMe.Flag.compare_exchange_strong(Expected, Desired))

102 continue;

103 (*RunMe.Callback)(RunMe.Cookie);

104 RunMe.Callback = nullptr;

105 RunMe.Cookie = nullptr;

107 }

108}

109

110

112 void *Cookie) {

116 if (!SetMe.Flag.compare_exchange_strong(Expected, Desired))

117 continue;

118 SetMe.Callback = FnPtr;

119 SetMe.Cookie = Cookie;

121 return;

122 }

124}

125

127 const char **Modules, intptr_t *Offsets,

128 const char *MainExecutableName,

130

131

132

134

135 unsigned PtrWidth = 2 + 2 * sizeof(void *);

137}

138

139

140

141

142

143

144

145

146

147

148

149

150std::optional<SmallVector<std::pair<unsigned, std::string>, 0>>

152 const char *MainExecutableName,

153 const std::string &LLVMSymbolizerPath) {

159 Offsets.data(), MainExecutableName, StrPool))

160 return {};

161 int InputFD;

167

168 {

170 for (unsigned AddrIdx = 0; AddrIdx < AddressCount; AddrIdx++) {

171 if (Modules[AddrIdx])

172 Input << Modules[AddrIdx] << " " << (void *)Offsets[AddrIdx] << "\n";

173 }

174 }

175

176 std::optional Redirects[] = {InputFile.str(), OutputFile.str(),

178 StringRef Args[] = {"llvm-symbolizer", "--functions=linkage", "--inlining",

179#ifdef _WIN32

180

181

182

183 "--relative-address",

184#endif

185 "--demangle"};

186 int RunResult =

188 if (RunResult != 0)

189 return {};

190

193 if (!OutputBuf)

194 return {};

195 StringRef Output = OutputBuf.get()->getBuffer();

197 Output.split(Lines, "\n");

198 auto *CurLine = Lines.begin();

199

200

201

202

203

204

205

206

207

208 for (unsigned AddrIdx = 0; AddrIdx < AddressCount; AddrIdx++) {

209 if (!Modules[AddrIdx]) {

210 auto &SymbolizedFrame = Result.emplace_back(std::make_pair(AddrIdx, ""));

212 OS << format_ptr(AddressList[AddrIdx]);

213 continue;

214 }

215

216

217 for (;;) {

218 if (CurLine == Lines.end())

219 return {};

220 StringRef FunctionName = *CurLine++;

221 if (FunctionName.empty())

222 break;

223 auto &SymbolizedFrame = Result.emplace_back(std::make_pair(AddrIdx, ""));

225 OS << format_ptr(AddressList[AddrIdx]) << ' ';

227 OS << FunctionName << ' ';

228 if (CurLine == Lines.end())

229 return {};

230 StringRef FileLineInfo = *CurLine++;

232 OS << FileLineInfo;

233 } else {

234 OS << "(" << Modules[AddrIdx] << '+' << format_hex(Offsets[AddrIdx], 0)

235 << ")";

236 }

237 }

238 }

239 return Result;

240}

241

246 } else if (!Argv0.empty()) {

248 if (!Parent.empty())

249 LLVMSymbolizerPathOrErr =

251 }

252 if (!LLVMSymbolizerPathOrErr)

254 return LLVMSymbolizerPathOrErr;

255}

256

257

262 return false;

263

264

265 if (Argv0.contains("llvm-symbolizer"))

266 return false;

267

268

269

270

271

273 if (!LLVMSymbolizerPathOrErr)

274 return false;

275 const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;

276

277

278

279 std::string MainExecutableName =

282

284 StackTrace, Depth, MainExecutableName.c_str(), LLVMSymbolizerPath);

285 if (!SymbolizedAddressesOpt)

286 return false;

287 for (unsigned FrameNo = 0; FrameNo < SymbolizedAddressesOpt->size();

288 ++FrameNo) {

290 << ' ' << (*SymbolizedAddressesOpt)[FrameNo].second << '\n';

291 }

292 return true;

293}

294

295#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN

296void sys::symbolizeAddresses(AddressSet &Addresses,

297 SymbolizedAddressMap &SymbolizedAddresses) {

299 "Debugify origin stacktraces require symbolization to be enabled.");

300

301

303 if (AddressList.empty())

304 return;

306

307

308

310 if (!LLVMSymbolizerPathOrErr)

311 report_fatal_error("Debugify origin stacktraces require llvm-symbolizer");

312 const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;

313

314

315

317

318 auto SymbolizedAddressesOpt =

320 MainExecutableName.c_str(), LLVMSymbolizerPath);

321 if (!SymbolizedAddressesOpt)

322 return;

323 for (auto SymbolizedFrame : *SymbolizedAddressesOpt) {

325 SymbolizedAddresses[AddressList[SymbolizedFrame.first]];

326 SymbolizedAddrs.push_back(SymbolizedFrame.second);

327 }

328 return;

329}

330#endif

331

333

338 if (!Env || !*Env)

339 return false;

340

341 std::string MainExecutableName =

345 return false;

346 for (int I = 0; I < Depth; I++)

347 OS << format("{{{bt:%d:%#016x}}}\n", I, StackTrace[I]);

348 return true;

349}

350

351

352#ifdef LLVM_ON_UNIX

354#endif

355#ifdef _WIN32

357#endif

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

#define LLVM_ATTRIBUTE_USED

Provides ErrorOr smart pointer.

static FormattedNumber format_ptr(void *PC)

Format a pointer value as hexadecimal.

Definition Signals.cpp:133

constexpr char DisableSymbolizationEnv[]

Definition Signals.cpp:72

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.

Definition Signals.cpp:259

static std::array< CallbackAndCookie, MaxSignalHandlerCallbacks > & CallBacksToRun()

Definition Signals.cpp:91

static bool findModulesAndOffsets(void **StackTrace, int Depth, const char **Modules, intptr_t *Offsets, const char *MainExecutableName, StringSaver &StrPool)

static bool DisableSymbolicationFlag

Definition Signals.cpp:43

static ManagedStatic< std::string > CrashDiagnosticsDirectory

Definition Signals.cpp:44

ErrorOr< std::string > getLLVMSymbolizerPath(StringRef Argv0={})

Definition Signals.cpp:242

static constexpr size_t MaxSignalHandlerCallbacks

Definition Signals.cpp:86

constexpr char LLVMSymbolizerPathEnv[]

Definition Signals.cpp:73

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...

Definition Signals.cpp:151

static LLVM_ATTRIBUTE_USED bool printMarkupStackTrace(StringRef Argv0, void **StackTrace, int Depth, raw_ostream &OS)

Definition Signals.cpp:335

static void insertSignalHandler(sys::SignalHandlerCallback FnPtr, void *Cookie)

Definition Signals.cpp:111

constexpr char EnableSymbolizerMarkupEnv[]

Definition Signals.cpp:74

The Input class is used to parse a yaml document into in-memory structs and vectors.

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.

This is a helper class used for format_hex() and format_decimal().

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.

StringRef - 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

empty - 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.

LLVM_ABI ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})

Find the first executable file Name in Paths.

LLVM_ABI void RunSignalHandlers()

Definition Signals.cpp:97

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()

Definition Signals.cpp:63

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.

Definition Signals.cpp:79

sys::SignalHandlerCallback Callback

Definition Signals.cpp:80

std::atomic< Status > Flag

Definition Signals.cpp:83

void * Cookie

Definition Signals.cpp:81

Status

Definition Signals.cpp:82

@ Initializing

Definition Signals.cpp:82

@ Initialized

Definition Signals.cpp:82

@ Executing

Definition Signals.cpp:82

@ Empty

Definition Signals.cpp:82