Index: lib/sanitizer_common/sanitizer_symbolizer.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer.h +++ lib/sanitizer_common/sanitizer_symbolizer.h @@ -141,8 +141,8 @@ 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 @@ // 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(); } Index: lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -105,11 +105,10 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ : 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 @@ 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 addr2line_pool_; @@ -628,7 +630,8 @@ } 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 @@ 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")) {