diff options
author | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-23 11:41:33 +0000 |
---|---|---|
committer | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-23 11:41:33 +0000 |
commit | 4a2c1ffc3bc03c1f519fe1ef62cafeda13481fe2 (patch) | |
tree | 80989bd161e60d01560788cb7427eb644b227884 /libsanitizer/sanitizer_common/sanitizer_symbolizer.cc | |
parent | bc5663df31f641cce031d61b31540dd88a473cb5 (diff) | |
download | gcc-4a2c1ffc3bc03c1f519fe1ef62cafeda13481fe2.tar.gz |
libsanitizer merge from upstream r173241
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195404 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_symbolizer.cc')
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_symbolizer.cc | 190 |
1 files changed, 102 insertions, 88 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc index 11393e44503..f62acf35f8f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc @@ -66,7 +66,18 @@ static const char *ExtractInt(const char *str, const char *delims, char *buff; const char *ret = ExtractToken(str, delims, &buff); if (buff != 0) { - *result = internal_atoll(buff); + *result = (int)internal_atoll(buff); + } + InternalFree(buff); + return ret; +} + +static const char *ExtractUptr(const char *str, const char *delims, + uptr *result) { + char *buff; + const char *ret = ExtractToken(str, delims, &buff); + if (buff != 0) { + *result = (uptr)internal_atoll(buff); } InternalFree(buff); return ret; @@ -96,66 +107,15 @@ class ExternalSymbolizer { CHECK_NE(output_fd_, kInvalidFd); } - // Returns the number of frames for a given address, or zero if - // symbolization failed. - uptr SymbolizeCode(uptr addr, const char *module_name, uptr module_offset, - AddressInfo *frames, uptr max_frames) { + char *SendCommand(bool is_data, const char *module_name, uptr module_offset) { CHECK(module_name); - // FIXME: Make sure this buffer always has sufficient size to hold - // large debug info. - static const int kMaxBufferSize = 4096; - InternalScopedBuffer<char> buffer(kMaxBufferSize); - char *buffer_data = buffer.data(); - internal_snprintf(buffer_data, kMaxBufferSize, "%s 0x%zx\n", - module_name, module_offset); - if (!writeToSymbolizer(buffer_data, internal_strlen(buffer_data))) + internal_snprintf(buffer_, kBufferSize, "%s%s 0x%zx\n", + is_data ? "DATA " : "", module_name, module_offset); + if (!writeToSymbolizer(buffer_, internal_strlen(buffer_))) return 0; - - if (!readFromSymbolizer(buffer_data, kMaxBufferSize)) + if (!readFromSymbolizer(buffer_, kBufferSize)) return 0; - const char *str = buffer_data; - uptr frame_id; - CHECK_GT(max_frames, 0); - for (frame_id = 0; frame_id < max_frames; frame_id++) { - AddressInfo *info = &frames[frame_id]; - char *function_name = 0; - str = ExtractToken(str, "\n", &function_name); - CHECK(function_name); - if (function_name[0] == '\0') { - // There are no more frames. - break; - } - info->Clear(); - info->FillAddressAndModuleInfo(addr, module_name, module_offset); - info->function = function_name; - // Parse <file>:<line>:<column> buffer. - char *file_line_info = 0; - str = ExtractToken(str, "\n", &file_line_info); - CHECK(file_line_info); - const char *line_info = ExtractToken(file_line_info, ":", &info->file); - line_info = ExtractInt(line_info, ":", &info->line); - line_info = ExtractInt(line_info, "", &info->column); - InternalFree(file_line_info); - - // Functions and filenames can be "??", in which case we write 0 - // to address info to mark that names are unknown. - if (0 == internal_strcmp(info->function, "??")) { - InternalFree(info->function); - info->function = 0; - } - if (0 == internal_strcmp(info->file, "??")) { - InternalFree(info->file); - info->file = 0; - } - } - if (frame_id == 0) { - // Make sure we return at least one frame. - AddressInfo *info = &frames[0]; - info->Clear(); - info->FillAddressAndModuleInfo(addr, module_name, module_offset); - frame_id = 1; - } - return frame_id; + return buffer_; } bool Restart() { @@ -189,6 +149,7 @@ class ExternalSymbolizer { } return true; } + bool writeToSymbolizer(const char *buffer, uptr length) { if (length == 0) return true; @@ -204,6 +165,9 @@ class ExternalSymbolizer { int input_fd_; int output_fd_; + static const uptr kBufferSize = 16 * 1024; + char buffer_[kBufferSize]; + static const uptr kMaxTimesRestarted = 5; uptr times_restarted_; }; @@ -220,30 +184,8 @@ class Symbolizer { return 0; const char *module_name = module->full_name(); uptr module_offset = addr - module->base_address(); - uptr actual_frames = 0; - if (external_symbolizer_ == 0) { - ReportExternalSymbolizerError( - "WARNING: Trying to symbolize code, but external " - "symbolizer is not initialized!\n"); - } else { - while (true) { - actual_frames = external_symbolizer_->SymbolizeCode( - addr, module_name, module_offset, frames, max_frames); - if (actual_frames > 0) { - // Symbolization was successful. - break; - } - // 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; - break; - } - } - } - if (external_symbolizer_ == 0) { + const char *str = SendCommand(false, module_name, module_offset); + if (str == 0) { // External symbolizer was not initialized or failed. Fill only data // about module name and offset. AddressInfo *info = &frames[0]; @@ -251,17 +193,66 @@ class Symbolizer { info->FillAddressAndModuleInfo(addr, module_name, module_offset); return 1; } - // Otherwise, the data was filled by external symbolizer. - return actual_frames; + uptr frame_id = 0; + for (frame_id = 0; frame_id < max_frames; frame_id++) { + AddressInfo *info = &frames[frame_id]; + char *function_name = 0; + str = ExtractToken(str, "\n", &function_name); + CHECK(function_name); + if (function_name[0] == '\0') { + // There are no more frames. + break; + } + info->Clear(); + info->FillAddressAndModuleInfo(addr, module_name, module_offset); + info->function = function_name; + // Parse <file>:<line>:<column> buffer. + char *file_line_info = 0; + str = ExtractToken(str, "\n", &file_line_info); + CHECK(file_line_info); + const char *line_info = ExtractToken(file_line_info, ":", &info->file); + line_info = ExtractInt(line_info, ":", &info->line); + line_info = ExtractInt(line_info, "", &info->column); + InternalFree(file_line_info); + + // Functions and filenames can be "??", in which case we write 0 + // to address info to mark that names are unknown. + if (0 == internal_strcmp(info->function, "??")) { + InternalFree(info->function); + info->function = 0; + } + if (0 == internal_strcmp(info->file, "??")) { + InternalFree(info->file); + info->file = 0; + } + } + if (frame_id == 0) { + // Make sure we return at least one frame. + AddressInfo *info = &frames[0]; + info->Clear(); + info->FillAddressAndModuleInfo(addr, module_name, module_offset); + frame_id = 1; + } + return frame_id; } - bool SymbolizeData(uptr addr, AddressInfo *frame) { + bool SymbolizeData(uptr addr, DataInfo *info) { LoadedModule *module = FindModuleForAddress(addr); if (module == 0) return false; const char *module_name = module->full_name(); uptr module_offset = addr - module->base_address(); - frame->FillAddressAndModuleInfo(addr, module_name, module_offset); + internal_memset(info, 0, sizeof(*info)); + info->address = addr; + info->module = internal_strdup(module_name); + info->module_offset = module_offset; + const char *str = SendCommand(true, module_name, module_offset); + if (str == 0) + return true; + str = ExtractToken(str, "\n", &info->name); + str = ExtractUptr(str, " ", &info->start); + str = ExtractUptr(str, "\n", &info->size); + info->start += module->base_address(); return true; } @@ -276,6 +267,29 @@ class Symbolizer { } private: + char *SendCommand(bool is_data, const char *module_name, uptr module_offset) { + 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; + } + } + } + LoadedModule *FindModuleForAddress(uptr address) { if (modules_ == 0) { modules_ = (LoadedModule*)(symbolizer_allocator.Allocate( @@ -316,8 +330,8 @@ uptr SymbolizeCode(uptr address, AddressInfo *frames, uptr max_frames) { return symbolizer.SymbolizeCode(address, frames, max_frames); } -bool SymbolizeData(uptr address, AddressInfo *frame) { - return symbolizer.SymbolizeData(address, frame); +bool SymbolizeData(uptr address, DataInfo *info) { + return symbolizer.SymbolizeData(address, info); } bool InitializeExternalSymbolizer(const char *path_to_symbolizer) { |