sanitizer_symbolizer_posix_libcdep.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. //===-- sanitizer_symbolizer_posix_libcdep.cpp ----------------------------===//
  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. //
  9. // This file is shared between AddressSanitizer and ThreadSanitizer
  10. // run-time libraries.
  11. // POSIX-specific implementation of symbolizer parts.
  12. //===----------------------------------------------------------------------===//
  13. #include "sanitizer_platform.h"
  14. #include "sanitizer_symbolizer_markup.h"
  15. #if SANITIZER_POSIX
  16. # include <dlfcn.h> // for dlsym()
  17. # include <errno.h>
  18. # include <stdint.h>
  19. # include <stdlib.h>
  20. # include <sys/wait.h>
  21. # include <unistd.h>
  22. # include "sanitizer_allocator_internal.h"
  23. # include "sanitizer_common.h"
  24. # include "sanitizer_file.h"
  25. # include "sanitizer_flags.h"
  26. # include "sanitizer_internal_defs.h"
  27. # include "sanitizer_linux.h"
  28. # include "sanitizer_placement_new.h"
  29. # include "sanitizer_posix.h"
  30. # include "sanitizer_procmaps.h"
  31. # include "sanitizer_symbolizer_internal.h"
  32. # include "sanitizer_symbolizer_libbacktrace.h"
  33. # include "sanitizer_symbolizer_mac.h"
  34. // C++ demangling function, as required by Itanium C++ ABI. This is weak,
  35. // because we do not require a C++ ABI library to be linked to a program
  36. // using sanitizers; if it's not present, we'll just use the mangled name.
  37. namespace __cxxabiv1 {
  38. extern "C" SANITIZER_WEAK_ATTRIBUTE
  39. char *__cxa_demangle(const char *mangled, char *buffer,
  40. size_t *length, int *status);
  41. }
  42. namespace __sanitizer {
  43. // Attempts to demangle the name via __cxa_demangle from __cxxabiv1.
  44. const char *DemangleCXXABI(const char *name) {
  45. // FIXME: __cxa_demangle aggressively insists on allocating memory.
  46. // There's not much we can do about that, short of providing our
  47. // own demangler (libc++abi's implementation could be adapted so that
  48. // it does not allocate). For now, we just call it anyway, and we leak
  49. // the returned value.
  50. if (&__cxxabiv1::__cxa_demangle)
  51. if (const char *demangled_name =
  52. __cxxabiv1::__cxa_demangle(name, 0, 0, 0))
  53. return demangled_name;
  54. return nullptr;
  55. }
  56. // As of now, there are no headers for the Swift runtime. Once they are
  57. // present, we will weakly link since we do not require Swift runtime to be
  58. // linked.
  59. typedef char *(*swift_demangle_ft)(const char *mangledName,
  60. size_t mangledNameLength, char *outputBuffer,
  61. size_t *outputBufferSize, uint32_t flags);
  62. static swift_demangle_ft swift_demangle_f;
  63. // This must not happen lazily at symbolication time, because dlsym uses
  64. // malloc and thread-local storage, which is not a good thing to do during
  65. // symbolication.
  66. static void InitializeSwiftDemangler() {
  67. swift_demangle_f = (swift_demangle_ft)dlsym(RTLD_DEFAULT, "swift_demangle");
  68. }
  69. // Attempts to demangle a Swift name. The demangler will return nullptr if a
  70. // non-Swift name is passed in.
  71. const char *DemangleSwift(const char *name) {
  72. if (swift_demangle_f)
  73. return swift_demangle_f(name, internal_strlen(name), 0, 0, 0);
  74. return nullptr;
  75. }
  76. const char *DemangleSwiftAndCXX(const char *name) {
  77. if (!name) return nullptr;
  78. if (const char *swift_demangled_name = DemangleSwift(name))
  79. return swift_demangled_name;
  80. return DemangleCXXABI(name);
  81. }
  82. static bool CreateTwoHighNumberedPipes(int *infd_, int *outfd_) {
  83. int *infd = NULL;
  84. int *outfd = NULL;
  85. // The client program may close its stdin and/or stdout and/or stderr
  86. // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
  87. // In this case the communication between the forked processes may be
  88. // broken if either the parent or the child tries to close or duplicate
  89. // these descriptors. The loop below produces two pairs of file
  90. // descriptors, each greater than 2 (stderr).
  91. int sock_pair[5][2];
  92. for (int i = 0; i < 5; i++) {
  93. if (pipe(sock_pair[i]) == -1) {
  94. for (int j = 0; j < i; j++) {
  95. internal_close(sock_pair[j][0]);
  96. internal_close(sock_pair[j][1]);
  97. }
  98. return false;
  99. } else if (sock_pair[i][0] > 2 && sock_pair[i][1] > 2) {
  100. if (infd == NULL) {
  101. infd = sock_pair[i];
  102. } else {
  103. outfd = sock_pair[i];
  104. for (int j = 0; j < i; j++) {
  105. if (sock_pair[j] == infd) continue;
  106. internal_close(sock_pair[j][0]);
  107. internal_close(sock_pair[j][1]);
  108. }
  109. break;
  110. }
  111. }
  112. }
  113. CHECK(infd);
  114. CHECK(outfd);
  115. infd_[0] = infd[0];
  116. infd_[1] = infd[1];
  117. outfd_[0] = outfd[0];
  118. outfd_[1] = outfd[1];
  119. return true;
  120. }
  121. bool SymbolizerProcess::StartSymbolizerSubprocess() {
  122. if (!FileExists(path_)) {
  123. if (!reported_invalid_path_) {
  124. Report("WARNING: invalid path to external symbolizer!\n");
  125. reported_invalid_path_ = true;
  126. }
  127. return false;
  128. }
  129. const char *argv[kArgVMax];
  130. GetArgV(path_, argv);
  131. pid_t pid;
  132. // Report how symbolizer is being launched for debugging purposes.
  133. if (Verbosity() >= 3) {
  134. // Only use `Report` for first line so subsequent prints don't get prefixed
  135. // with current PID.
  136. Report("Launching Symbolizer process: ");
  137. for (unsigned index = 0; index < kArgVMax && argv[index]; ++index)
  138. Printf("%s ", argv[index]);
  139. Printf("\n");
  140. }
  141. if (use_posix_spawn_) {
  142. #if SANITIZER_APPLE
  143. fd_t fd = internal_spawn(argv, const_cast<const char **>(GetEnvP()), &pid);
  144. if (fd == kInvalidFd) {
  145. Report("WARNING: failed to spawn external symbolizer (errno: %d)\n",
  146. errno);
  147. return false;
  148. }
  149. input_fd_ = fd;
  150. output_fd_ = fd;
  151. #else // SANITIZER_APPLE
  152. UNIMPLEMENTED();
  153. #endif // SANITIZER_APPLE
  154. } else {
  155. fd_t infd[2] = {}, outfd[2] = {};
  156. if (!CreateTwoHighNumberedPipes(infd, outfd)) {
  157. Report("WARNING: Can't create a socket pair to start "
  158. "external symbolizer (errno: %d)\n", errno);
  159. return false;
  160. }
  161. pid = StartSubprocess(path_, argv, GetEnvP(), /* stdin */ outfd[0],
  162. /* stdout */ infd[1]);
  163. if (pid < 0) {
  164. internal_close(infd[0]);
  165. internal_close(outfd[1]);
  166. return false;
  167. }
  168. input_fd_ = infd[0];
  169. output_fd_ = outfd[1];
  170. }
  171. CHECK_GT(pid, 0);
  172. // Check that symbolizer subprocess started successfully.
  173. SleepForMillis(kSymbolizerStartupTimeMillis);
  174. if (!IsProcessRunning(pid)) {
  175. // Either waitpid failed, or child has already exited.
  176. Report("WARNING: external symbolizer didn't start up correctly!\n");
  177. return false;
  178. }
  179. return true;
  180. }
  181. class Addr2LineProcess final : public SymbolizerProcess {
  182. public:
  183. Addr2LineProcess(const char *path, const char *module_name)
  184. : SymbolizerProcess(path), module_name_(internal_strdup(module_name)) {}
  185. const char *module_name() const { return module_name_; }
  186. private:
  187. void GetArgV(const char *path_to_binary,
  188. const char *(&argv)[kArgVMax]) const override {
  189. int i = 0;
  190. argv[i++] = path_to_binary;
  191. if (common_flags()->demangle)
  192. argv[i++] = "-C";
  193. if (common_flags()->symbolize_inline_frames)
  194. argv[i++] = "-i";
  195. argv[i++] = "-fe";
  196. argv[i++] = module_name_;
  197. argv[i++] = nullptr;
  198. CHECK_LE(i, kArgVMax);
  199. }
  200. bool ReachedEndOfOutput(const char *buffer, uptr length) const override;
  201. bool ReadFromSymbolizer() override {
  202. if (!SymbolizerProcess::ReadFromSymbolizer())
  203. return false;
  204. auto &buff = GetBuff();
  205. // We should cut out output_terminator_ at the end of given buffer,
  206. // appended by addr2line to mark the end of its meaningful output.
  207. // We cannot scan buffer from it's beginning, because it is legal for it
  208. // to start with output_terminator_ in case given offset is invalid. So,
  209. // scanning from second character.
  210. char *garbage = internal_strstr(buff.data() + 1, output_terminator_);
  211. // This should never be NULL since buffer must end up with
  212. // output_terminator_.
  213. CHECK(garbage);
  214. // Trim the buffer.
  215. uintptr_t new_size = garbage - buff.data();
  216. GetBuff().resize(new_size);
  217. GetBuff().push_back('\0');
  218. return true;
  219. }
  220. const char *module_name_; // Owned, leaked.
  221. static const char output_terminator_[];
  222. };
  223. const char Addr2LineProcess::output_terminator_[] = "??\n??:0\n";
  224. bool Addr2LineProcess::ReachedEndOfOutput(const char *buffer,
  225. uptr length) const {
  226. const size_t kTerminatorLen = sizeof(output_terminator_) - 1;
  227. // Skip, if we read just kTerminatorLen bytes, because Addr2Line output
  228. // should consist at least of two pairs of lines:
  229. // 1. First one, corresponding to given offset to be symbolized
  230. // (may be equal to output_terminator_, if offset is not valid).
  231. // 2. Second one for output_terminator_, itself to mark the end of output.
  232. if (length <= kTerminatorLen) return false;
  233. // Addr2Line output should end up with output_terminator_.
  234. return !internal_memcmp(buffer + length - kTerminatorLen,
  235. output_terminator_, kTerminatorLen);
  236. }
  237. class Addr2LinePool final : public SymbolizerTool {
  238. public:
  239. explicit Addr2LinePool(const char *addr2line_path,
  240. LowLevelAllocator *allocator)
  241. : addr2line_path_(addr2line_path), allocator_(allocator) {
  242. addr2line_pool_.reserve(16);
  243. }
  244. bool SymbolizePC(uptr addr, SymbolizedStack *stack) override {
  245. if (const char *buf =
  246. SendCommand(stack->info.module, stack->info.module_offset)) {
  247. ParseSymbolizePCOutput(buf, stack);
  248. return true;
  249. }
  250. return false;
  251. }
  252. bool SymbolizeData(uptr addr, DataInfo *info) override {
  253. return false;
  254. }
  255. private:
  256. const char *SendCommand(const char *module_name, uptr module_offset) {
  257. Addr2LineProcess *addr2line = 0;
  258. for (uptr i = 0; i < addr2line_pool_.size(); ++i) {
  259. if (0 ==
  260. internal_strcmp(module_name, addr2line_pool_[i]->module_name())) {
  261. addr2line = addr2line_pool_[i];
  262. break;
  263. }
  264. }
  265. if (!addr2line) {
  266. addr2line =
  267. new(*allocator_) Addr2LineProcess(addr2line_path_, module_name);
  268. addr2line_pool_.push_back(addr2line);
  269. }
  270. CHECK_EQ(0, internal_strcmp(module_name, addr2line->module_name()));
  271. char buffer[kBufferSize];
  272. internal_snprintf(buffer, kBufferSize, "0x%zx\n0x%zx\n",
  273. module_offset, dummy_address_);
  274. return addr2line->SendCommand(buffer);
  275. }
  276. static const uptr kBufferSize = 64;
  277. const char *addr2line_path_;
  278. LowLevelAllocator *allocator_;
  279. InternalMmapVector<Addr2LineProcess*> addr2line_pool_;
  280. static const uptr dummy_address_ =
  281. FIRST_32_SECOND_64(UINT32_MAX, UINT64_MAX);
  282. };
  283. # if SANITIZER_SUPPORTS_WEAK_HOOKS
  284. extern "C" {
  285. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  286. __sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset,
  287. char *Buffer, int MaxLength);
  288. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  289. __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset,
  290. char *Buffer, int MaxLength);
  291. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  292. __sanitizer_symbolize_frame(const char *ModuleName, u64 ModuleOffset,
  293. char *Buffer, int MaxLength);
  294. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
  295. __sanitizer_symbolize_flush();
  296. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  297. __sanitizer_symbolize_demangle(const char *Name, char *Buffer, int MaxLength);
  298. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  299. __sanitizer_symbolize_set_demangle(bool Demangle);
  300. SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE bool
  301. __sanitizer_symbolize_set_inline_frames(bool InlineFrames);
  302. } // extern "C"
  303. class InternalSymbolizer final : public SymbolizerTool {
  304. public:
  305. static InternalSymbolizer *get(LowLevelAllocator *alloc) {
  306. // These one is the most used one, so we will use it to detect a presence of
  307. // internal symbolizer.
  308. if (&__sanitizer_symbolize_code == nullptr)
  309. return nullptr;
  310. CHECK(__sanitizer_symbolize_set_demangle(common_flags()->demangle));
  311. CHECK(__sanitizer_symbolize_set_inline_frames(
  312. common_flags()->symbolize_inline_frames));
  313. return new (*alloc) InternalSymbolizer();
  314. }
  315. bool SymbolizePC(uptr addr, SymbolizedStack *stack) override {
  316. bool result = __sanitizer_symbolize_code(
  317. stack->info.module, stack->info.module_offset, buffer_, sizeof(buffer_));
  318. if (result)
  319. ParseSymbolizePCOutput(buffer_, stack);
  320. return result;
  321. }
  322. bool SymbolizeData(uptr addr, DataInfo *info) override {
  323. bool result = __sanitizer_symbolize_data(info->module, info->module_offset,
  324. buffer_, sizeof(buffer_));
  325. if (result) {
  326. ParseSymbolizeDataOutput(buffer_, info);
  327. info->start += (addr - info->module_offset); // Add the base address.
  328. }
  329. return result;
  330. }
  331. bool SymbolizeFrame(uptr addr, FrameInfo *info) override {
  332. bool result = __sanitizer_symbolize_frame(info->module, info->module_offset,
  333. buffer_, sizeof(buffer_));
  334. if (result)
  335. ParseSymbolizeFrameOutput(buffer_, &info->locals);
  336. return result;
  337. }
  338. void Flush() override { __sanitizer_symbolize_flush(); }
  339. const char *Demangle(const char *name) override {
  340. if (__sanitizer_symbolize_demangle(name, buffer_, sizeof(buffer_))) {
  341. char *res_buff = nullptr;
  342. ExtractToken(buffer_, "", &res_buff);
  343. return res_buff;
  344. }
  345. return nullptr;
  346. }
  347. private:
  348. InternalSymbolizer() {}
  349. char buffer_[16 * 1024];
  350. };
  351. # else // SANITIZER_SUPPORTS_WEAK_HOOKS
  352. class InternalSymbolizer final : public SymbolizerTool {
  353. public:
  354. static InternalSymbolizer *get(LowLevelAllocator *alloc) { return 0; }
  355. };
  356. # endif // SANITIZER_SUPPORTS_WEAK_HOOKS
  357. const char *Symbolizer::PlatformDemangle(const char *name) {
  358. return DemangleSwiftAndCXX(name);
  359. }
  360. static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
  361. const char *path = common_flags()->external_symbolizer_path;
  362. if (path && internal_strchr(path, '%')) {
  363. char *new_path = (char *)InternalAlloc(kMaxPathLength);
  364. SubstituteForFlagValue(path, new_path, kMaxPathLength);
  365. path = new_path;
  366. }
  367. const char *binary_name = path ? StripModuleName(path) : "";
  368. static const char kLLVMSymbolizerPrefix[] = "llvm-symbolizer";
  369. if (path && path[0] == '\0') {
  370. VReport(2, "External symbolizer is explicitly disabled.\n");
  371. return nullptr;
  372. } else if (!internal_strncmp(binary_name, kLLVMSymbolizerPrefix,
  373. internal_strlen(kLLVMSymbolizerPrefix))) {
  374. VReport(2, "Using llvm-symbolizer at user-specified path: %s\n", path);
  375. return new(*allocator) LLVMSymbolizer(path, allocator);
  376. } else if (!internal_strcmp(binary_name, "atos")) {
  377. #if SANITIZER_APPLE
  378. VReport(2, "Using atos at user-specified path: %s\n", path);
  379. return new(*allocator) AtosSymbolizer(path, allocator);
  380. #else // SANITIZER_APPLE
  381. Report("ERROR: Using `atos` is only supported on Darwin.\n");
  382. Die();
  383. #endif // SANITIZER_APPLE
  384. } else if (!internal_strcmp(binary_name, "addr2line")) {
  385. VReport(2, "Using addr2line at user-specified path: %s\n", path);
  386. return new(*allocator) Addr2LinePool(path, allocator);
  387. } else if (path) {
  388. Report("ERROR: External symbolizer path is set to '%s' which isn't "
  389. "a known symbolizer. Please set the path to the llvm-symbolizer "
  390. "binary or other known tool.\n", path);
  391. Die();
  392. }
  393. // Otherwise symbolizer program is unknown, let's search $PATH
  394. CHECK(path == nullptr);
  395. #if SANITIZER_APPLE
  396. if (const char *found_path = FindPathToBinary("atos")) {
  397. VReport(2, "Using atos found at: %s\n", found_path);
  398. return new(*allocator) AtosSymbolizer(found_path, allocator);
  399. }
  400. #endif // SANITIZER_APPLE
  401. if (const char *found_path = FindPathToBinary("llvm-symbolizer")) {
  402. VReport(2, "Using llvm-symbolizer found at: %s\n", found_path);
  403. return new(*allocator) LLVMSymbolizer(found_path, allocator);
  404. }
  405. if (common_flags()->allow_addr2line) {
  406. if (const char *found_path = FindPathToBinary("addr2line")) {
  407. VReport(2, "Using addr2line found at: %s\n", found_path);
  408. return new(*allocator) Addr2LinePool(found_path, allocator);
  409. }
  410. }
  411. return nullptr;
  412. }
  413. static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
  414. LowLevelAllocator *allocator) {
  415. if (!common_flags()->symbolize) {
  416. VReport(2, "Symbolizer is disabled.\n");
  417. return;
  418. }
  419. if (common_flags()->enable_symbolizer_markup) {
  420. VReport(2, "Using symbolizer markup");
  421. SymbolizerTool *tool = new (*allocator) MarkupSymbolizerTool();
  422. CHECK(tool);
  423. list->push_back(tool);
  424. }
  425. if (IsAllocatorOutOfMemory()) {
  426. VReport(2, "Cannot use internal symbolizer: out of memory\n");
  427. } else if (SymbolizerTool *tool = InternalSymbolizer::get(allocator)) {
  428. VReport(2, "Using internal symbolizer.\n");
  429. list->push_back(tool);
  430. return;
  431. }
  432. if (SymbolizerTool *tool = LibbacktraceSymbolizer::get(allocator)) {
  433. VReport(2, "Using libbacktrace symbolizer.\n");
  434. list->push_back(tool);
  435. return;
  436. }
  437. if (SymbolizerTool *tool = ChooseExternalSymbolizer(allocator)) {
  438. list->push_back(tool);
  439. }
  440. #if SANITIZER_APPLE
  441. VReport(2, "Using dladdr symbolizer.\n");
  442. list->push_back(new(*allocator) DlAddrSymbolizer());
  443. #endif // SANITIZER_APPLE
  444. }
  445. Symbolizer *Symbolizer::PlatformInit() {
  446. IntrusiveList<SymbolizerTool> list;
  447. list.clear();
  448. ChooseSymbolizerTools(&list, &symbolizer_allocator_);
  449. return new(symbolizer_allocator_) Symbolizer(list);
  450. }
  451. void Symbolizer::LateInitialize() {
  452. Symbolizer::GetOrInit();
  453. InitializeSwiftDemangler();
  454. }
  455. } // namespace __sanitizer
  456. #endif // SANITIZER_POSIX