[compiler-rt] Symbolizer refactoring: Abstract SymbolizerProcess better

Reviewed at http://reviews.llvm.org/D7889

llvm-svn: 230749
This commit is contained in:
Kuba Brecka 2015-02-27 11:11:05 +00:00
parent 344c167436
commit 1cd77d4f13
2 changed files with 38 additions and 43 deletions

View File

@ -141,8 +141,8 @@ class ExternalSymbolizerInterface {
public:
// Can't declare pure virtual functions in sanitizer runtimes:
// __cxa_pure_virtual might be unavailable.
virtual char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) {
virtual const char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) {
UNIMPLEMENTED();
}
};
@ -150,26 +150,18 @@ class ExternalSymbolizerInterface {
// SymbolizerProcess encapsulates communication between the tool and
// external symbolizer program, running in a different subprocess.
// SymbolizerProcess may not be used from two threads simultaneously.
class SymbolizerProcess : public ExternalSymbolizerInterface {
class SymbolizerProcess {
public:
explicit SymbolizerProcess(const char *path);
char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) override;
const char *SendCommand(const char *command);
private:
bool Restart();
char *SendCommandImpl(bool is_data, const char *module_name,
uptr module_offset);
const char *SendCommandImpl(const char *command);
bool ReadFromSymbolizer(char *buffer, uptr max_length);
bool WriteToSymbolizer(const char *buffer, uptr length);
bool StartSymbolizerSubprocess();
virtual bool RenderInputCommand(char *buffer, uptr max_length, bool is_data,
const char *module_name,
uptr module_offset) const {
UNIMPLEMENTED();
}
virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const {
UNIMPLEMENTED();
}

View File

@ -105,11 +105,10 @@ SymbolizerProcess::SymbolizerProcess(const char *path)
CHECK_NE(path_[0], '\0');
}
char *SymbolizerProcess::SendCommand(bool is_data, const char *module_name,
uptr module_offset) {
const char *SymbolizerProcess::SendCommand(const char *command) {
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))
if (const char *res = SendCommandImpl(command))
return res;
Restart();
}
@ -128,15 +127,10 @@ bool SymbolizerProcess::Restart() {
return StartSymbolizerSubprocess();
}
char *SymbolizerProcess::SendCommandImpl(bool is_data, const char *module_name,
uptr module_offset) {
const char *SymbolizerProcess::SendCommandImpl(const char *command) {
if (input_fd_ == kInvalidFd || output_fd_ == kInvalidFd)
return 0;
CHECK(module_name);
if (!RenderInputCommand(buffer_, kBufferSize, is_data, module_name,
module_offset))
return 0;
if (!WriteToSymbolizer(buffer_, internal_strlen(buffer_)))
if (!WriteToSymbolizer(command, internal_strlen(command)))
return 0;
if (!ReadFromSymbolizer(buffer_, kBufferSize))
return 0;
@ -343,13 +337,6 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
explicit LLVMSymbolizerProcess(const char *path) : SymbolizerProcess(path) {}
private:
bool RenderInputCommand(char *buffer, uptr max_length, bool is_data,
const char *module_name, uptr module_offset) const {
internal_snprintf(buffer, max_length, "%s\"%s\" 0x%zx\n",
is_data ? "DATA " : "", module_name, module_offset);
return true;
}
bool ReachedEndOfOutput(const char *buffer, uptr length) const {
// Empty line marks the end of llvm-symbolizer output.
return length >= 2 && buffer[length - 1] == '\n' &&
@ -377,6 +364,25 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
}
};
class LLVMSymbolizer : public ExternalSymbolizerInterface {
public:
explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator)
: symbolizer_process_(new(*allocator) LLVMSymbolizerProcess(path)) {}
const char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) override {
CHECK(module_name);
internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n",
is_data ? "DATA " : "", module_name, module_offset);
return symbolizer_process_->SendCommand(buffer_);
}
private:
LLVMSymbolizerProcess *symbolizer_process_;
static const uptr kBufferSize = 16 * 1024;
char buffer_[kBufferSize];
};
class Addr2LineProcess : public SymbolizerProcess {
public:
Addr2LineProcess(const char *path, const char *module_name)
@ -385,15 +391,6 @@ class Addr2LineProcess : public SymbolizerProcess {
const char *module_name() const { return module_name_; }
private:
bool RenderInputCommand(char *buffer, uptr max_length, bool is_data,
const char *module_name, uptr module_offset) const {
if (is_data)
return false;
CHECK_EQ(0, internal_strcmp(module_name, module_name_));
internal_snprintf(buffer, max_length, "0x%zx\n", module_offset);
return true;
}
bool ReachedEndOfOutput(const char *buffer, uptr length) const {
// Output should consist of two lines.
int num_lines = 0;
@ -420,7 +417,8 @@ class Addr2LinePool : public ExternalSymbolizerInterface {
: addr2line_path_(addr2line_path), allocator_(allocator),
addr2line_pool_(16) {}
char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
const char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) override {
if (is_data)
return 0;
Addr2LineProcess *addr2line = 0;
@ -436,10 +434,14 @@ class Addr2LinePool : public ExternalSymbolizerInterface {
new(*allocator_) Addr2LineProcess(addr2line_path_, module_name);
addr2line_pool_.push_back(addr2line);
}
return addr2line->SendCommand(is_data, module_name, module_offset);
CHECK_EQ(0, internal_strcmp(module_name, addr2line->module_name()));
char buffer_[kBufferSize];
internal_snprintf(buffer_, kBufferSize, "0x%zx\n", module_offset);
return addr2line->SendCommand(buffer_);
}
private:
static const uptr kBufferSize = 32;
const char *addr2line_path_;
LowLevelAllocator *allocator_;
InternalMmapVector<Addr2LineProcess*> addr2line_pool_;
@ -628,7 +630,8 @@ class POSIXSymbolizer : public Symbolizer {
}
private:
char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
const char *SendCommand(bool is_data, const char *module_name,
uptr module_offset) {
mu_.CheckLocked();
// First, try to use internal symbolizer.
if (internal_symbolizer_) {
@ -721,7 +724,7 @@ Symbolizer *Symbolizer::PlatformInit() {
path_to_external = FindPathToBinary("llvm-symbolizer");
if (path_to_external) {
external_symbolizer = new(symbolizer_allocator_)
LLVMSymbolizerProcess(path_to_external);
LLVMSymbolizer(path_to_external, &symbolizer_allocator_);
} else if (common_flags()->allow_addr2line) {
// If llvm-symbolizer is not found, try to use addr2line.
if (const char *addr2line_path = FindPathToBinary("addr2line")) {