diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-11-26 16:24:53 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-11-26 16:24:53 +0000 |
commit | e35e2dd579831ab2daa250f579e37ec9a2ed8324 (patch) | |
tree | 0e43b4900039160dc83cbbb5c0cb56faea740ddb /lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc | |
parent | 9393039efcd294eaa7c96923e9c74835fcc5f57e (diff) |
[Sanitizer] Improve external symbolizer behavior.
1) Don't start external symbolizer subprocess until we actually try to
symbolize anything.
2) Allow to turn off external symbolizer by providing empty ?SAN_SYMBOLIZER_PATH
environment variable.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@195771 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc | 99 |
1 files changed, 45 insertions, 54 deletions
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc index de1183287..69c62a644 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -205,19 +205,49 @@ static const char *ExtractUptr(const char *str, const char *delims, // <file_name>:<line_number>:<column_number> // ... // <empty line> +// ExternalSymbolizer may not be used from two threads simultaneously. class ExternalSymbolizer { public: - ExternalSymbolizer(const char *path, int input_fd, int output_fd) + explicit ExternalSymbolizer(const char *path) : path_(path), - input_fd_(input_fd), - output_fd_(output_fd), - times_restarted_(0) { + input_fd_(kInvalidFd), + output_fd_(kInvalidFd), + times_restarted_(0), + failed_to_start_(false) { CHECK(path_); - CHECK_NE(input_fd_, kInvalidFd); - CHECK_NE(output_fd_, kInvalidFd); + CHECK_NE(path[0], '\0'); } char *SendCommand(bool is_data, const char *module_name, uptr module_offset) { + for (; times_restarted_ < kMaxTimesRestarted; times_restarted_++) { + // Start or restart symbolizer if we failed to send command to it. + if (char *res = SendCommandImpl(is_data, module_name, module_offset)) + return res; + Restart(); + } + if (!failed_to_start_) { + Report("WARNING: Failed to use and restart external symbolizer!\n"); + failed_to_start_ = true; + } + return 0; + } + + void Flush() { + } + + private: + bool Restart() { + if (input_fd_ != kInvalidFd) + internal_close(input_fd_); + if (output_fd_ != kInvalidFd) + internal_close(output_fd_); + return StartSymbolizerSubprocess(path_, &input_fd_, &output_fd_); + } + + char *SendCommandImpl(bool is_data, const char *module_name, + uptr module_offset) { + if (input_fd_ == kInvalidFd || output_fd_ == kInvalidFd) + return 0; CHECK(module_name); internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data ? "DATA " : "", module_name, module_offset); @@ -228,18 +258,6 @@ class ExternalSymbolizer { return buffer_; } - bool Restart() { - if (times_restarted_ >= kMaxTimesRestarted) return false; - times_restarted_++; - internal_close(input_fd_); - internal_close(output_fd_); - return StartSymbolizerSubprocess(path_, &input_fd_, &output_fd_); - } - - void Flush() { - } - - private: bool readFromSymbolizer(char *buffer, uptr max_length) { if (max_length == 0) return true; @@ -283,6 +301,7 @@ class ExternalSymbolizer { static const uptr kMaxTimesRestarted = 5; uptr times_restarted_; + bool failed_to_start_; }; #if SANITIZER_SUPPORTS_WEAK_HOOKS @@ -500,26 +519,11 @@ class POSIXSymbolizer : public Symbolizer { module_offset); } // Otherwise, fall back to external symbolizer. - if (external_symbolizer_ == 0) { - ReportExternalSymbolizerError( - "WARNING: Trying to symbolize code, but external " - "symbolizer is not initialized!\n"); - return 0; - } - for (;;) { - char *reply = external_symbolizer_->SendCommand(is_data, module_name, - module_offset); - if (reply) - return reply; - // Try to restart symbolizer subprocess. If we don't succeed, forget - // about it and don't try to use it later. - if (!external_symbolizer_->Restart()) { - ReportExternalSymbolizerError( - "WARNING: Failed to use and restart external symbolizer!\n"); - external_symbolizer_ = 0; - return 0; - } + if (external_symbolizer_) { + return external_symbolizer_->SendCommand(is_data, module_name, + module_offset); } + return 0; } LoadedModule *FindModuleForAddress(uptr address) { @@ -553,16 +557,6 @@ class POSIXSymbolizer : public Symbolizer { return 0; } - void ReportExternalSymbolizerError(const char *msg) { - // Don't use atomics here for now, as SymbolizeCode can't be called - // from multiple threads anyway. - static bool reported; - if (!reported) { - Report(msg); - reported = true; - } - } - // 16K loaded modules should be enough for everyone. static const uptr kMaxNumberOfModuleContexts = 1 << 14; LoadedModule *modules_; // Array of module descriptions is leaked. @@ -581,15 +575,12 @@ Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) { ExternalSymbolizer *external_symbolizer = 0; if (!internal_symbolizer) { - if (!path_to_external || path_to_external[0] == '\0') + // Find path to llvm-symbolizer if it's not provided. + if (!path_to_external) path_to_external = FindPathToBinary("llvm-symbolizer"); - - int input_fd, output_fd; - if (path_to_external && - StartSymbolizerSubprocess(path_to_external, &input_fd, &output_fd)) { + if (path_to_external && path_to_external[0] != '\0') external_symbolizer = new(symbolizer_allocator_) - ExternalSymbolizer(path_to_external, input_fd, output_fd); - } + ExternalSymbolizer(path_to_external); } return new(symbolizer_allocator_) |