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#include

35

36

37

38

39

40

41using namespace llvm;

42

43

46namespace {

47struct CreateDisableSymbolication {

48 static void *call() {

50 "disable-symbolication",

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

53 }

54};

55struct CreateCrashDiagnosticsDir {

56 static void *call() {

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

61 }

62};

63}

66 DisableSymbolication;

68 CrashDiagnosticsDir;

69 *DisableSymbolication;

70 *CrashDiagnosticsDir;

71}

72

76

77

78

79

84 std::atomic Flag;

85};

86

88

89

90

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

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

94 return callbacks;

95}

96

97

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

103 continue;

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

105 RunMe.Callback = nullptr;

106 RunMe.Cookie = nullptr;

108 }

109}

110

111

113 void *Cookie) {

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

118 continue;

119 SetMe.Callback = FnPtr;

120 SetMe.Cookie = Cookie;

122 return;

123 }

125}

126

128 const char **Modules, intptr_t *Offsets,

129 const char *MainExecutableName,

131

132

133

135

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

138}

139

140

145 return false;

146

147

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

149 return false;

150

151

152

153

154

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

160 if (!Parent.empty())

162 }

163 if (!LLVMSymbolizerPathOrErr)

165 if (!LLVMSymbolizerPathOrErr)

166 return false;

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

168

169

170

171 std::string MainExecutableName =

176 std::vector<const char *> Modules(Depth, nullptr);

177 std::vector<intptr_t> Offsets(Depth, 0);

179 MainExecutableName.c_str(), StrPool))

180 return false;

181 int InputFD;

187

188 {

190 for (int i = 0; i < Depth; i++) {

191 if (Modules[i])

192 Input << Modules[i] << " " << (void*)Offsets[i] << "\n";

193 }

194 }

195

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

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

199#ifdef _WIN32

200

201

202

203 "--relative-address",

204#endif

205 "--demangle"};

206 int RunResult =

208 if (RunResult != 0)

209 return false;

210

211

212

214 if (!OutputBuf)

215 return false;

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

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

219 auto CurLine = Lines.begin();

220 int frame_no = 0;

221 for (int i = 0; i < Depth; i++) {

222 auto PrintLineHeader = [&]() {

224 std::log10(Depth) + 2)

225 << ' ' << format_ptr(StackTrace[i]) << ' ';

226 };

227 if (!Modules[i]) {

228 PrintLineHeader();

229 OS << '\n';

230 continue;

231 }

232

233

234 for (;;) {

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

236 return false;

237 StringRef FunctionName = *CurLine++;

238 if (FunctionName.empty())

239 break;

240 PrintLineHeader();

242 OS << FunctionName << ' ';

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

244 return false;

245 StringRef FileLineInfo = *CurLine++;

247 OS << FileLineInfo;

248 else

249 OS << "(" << Modules[i] << '+' << format_hex(Offsets[i], 0) << ")";

250 OS << "\n";

251 }

252 }

253 return true;

254}

255

257

262 if (!Env || !*Env)

263 return false;

264

265 std::string MainExecutableName =

269 return false;

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

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

272 return true;

273}

274

275

276#ifdef LLVM_ON_UNIX

278#endif

279#ifdef _WIN32

281#endif

#define LLVM_ATTRIBUTE_USED

Provides ErrorOr 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

static constexpr size_t MaxSignalHandlerCallbacks

constexpr char LLVMSymbolizerPathEnv[]

static bool printMarkupContext(raw_ostream &OS, const char *MainExecutableName)

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[]

Allocate memory in an ever growing pool, as if by bump-pointer.

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.

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.

LocationClass< Ty > location(Ty &L)

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

bool exists(const basic_file_status &status)

Does file exist?

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.

StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

void(*)(void *) SignalHandlerCallback

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.

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

Find the first executable file Name in Paths.

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 report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

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.

sys::SignalHandlerCallback Callback

std::atomic< Status > Flag