[compiler-rt] r195771 - [Sanitizer] Improve external symbolizer behavior.
Alexey Samsonov
samsonov at google.com
Tue Nov 26 08:24:53 PST 2013
Author: samsonov
Date: Tue Nov 26 10:24:53 2013
New Revision: 195771
URL: http://llvm.org/viewvc/llvm-project?rev=195771&view=rev
Log:
[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.
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=195771&r1=195770&r2=195771&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Tue Nov 26 10:24:53 2013
@@ -21,7 +21,7 @@ namespace __sanitizer {
void SetCommonFlagDefaults() {
CommonFlags *f = common_flags();
f->symbolize = true;
- f->external_symbolizer_path = "";
+ f->external_symbolizer_path = 0;
f->strip_path_prefix = "";
f->fast_unwind_on_fatal = false;
f->fast_unwind_on_malloc = true;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=195771&r1=195770&r2=195771&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Tue Nov 26 10:24:53 2013
@@ -25,7 +25,8 @@ void ParseFlag(const char *env, const ch
struct CommonFlags {
// If set, use the online symbolizer from common sanitizer runtime.
bool symbolize;
- // Path to external symbolizer.
+ // Path to external symbolizer. If it is NULL, symbolizer will be looked for
+ // in PATH. If it is empty, external symbolizer will not be started.
const char *external_symbolizer_path;
// Strips this prefix from file paths in error reports.
const char *strip_path_prefix;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc?rev=195771&r1=195770&r2=195771&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Tue Nov 26 10:24:53 2013
@@ -205,19 +205,49 @@ static const char *ExtractUptr(const cha
// <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 Symbolize
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 Symbolize
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(con
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_)
More information about the llvm-commits
mailing list