diff options
author | Kuba Mracek <mracek@apple.com> | 2017-01-06 21:45:05 +0000 |
---|---|---|
committer | Kuba Mracek <mracek@apple.com> | 2017-01-06 21:45:05 +0000 |
commit | d46b929d4f2835873f6559eb213145ecc66c56ee (patch) | |
tree | 432623d639a2f6876a9917bf9330a06253f8a05b /lib | |
parent | f752e5f2ac44590a9379a9c0e2508499be894601 (diff) |
[sanitizer] Use architecture/slice information when symbolizing fat Mach-O files on Darwin
This patch starts passing architecture information about a module to llvm-symbolizer and into text reports. This fixes the longstanding x86_64/x86_64h mismatch issue on Darwin.
Differential Revision: https://reviews.llvm.org/D27390
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@291287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace_printer.cc | 17 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace_printer.h | 3 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.cc | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.h | 8 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_internal.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc | 50 | ||||
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc | 9 | ||||
-rw-r--r-- | lib/ubsan/ubsan_diag.cc | 2 |
8 files changed, 68 insertions, 29 deletions
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc index 6fba581bd..377f1ce75 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc @@ -93,7 +93,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, vs_style, strip_path_prefix); } else if (info.module) { RenderModuleLocation(buffer, info.module, info.module_offset, - strip_path_prefix); + info.module_arch, strip_path_prefix); } else { buffer->append("(<unknown module>)"); } @@ -103,8 +103,9 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, if (info.address & kExternalPCBit) {} // There PCs are not meaningful. else if (info.module) - buffer->append("(%s+%p)", StripModuleName(info.module), - (void *)info.module_offset); + // Always strip the module name for %M. + RenderModuleLocation(buffer, StripModuleName(info.module), + info.module_offset, info.module_arch, ""); else buffer->append("(%p)", (void *)info.address); break; @@ -165,9 +166,13 @@ void RenderSourceLocation(InternalScopedString *buffer, const char *file, } void RenderModuleLocation(InternalScopedString *buffer, const char *module, - uptr offset, const char *strip_path_prefix) { - buffer->append("(%s+0x%zx)", StripPathPrefix(module, strip_path_prefix), - offset); + uptr offset, ModuleArch arch, + const char *strip_path_prefix) { + buffer->append("(%s", StripPathPrefix(module, strip_path_prefix)); + if (arch != kModuleArchUnknown) { + buffer->append(":%s", ModuleArchToString(arch)); + } + buffer->append("+0x%zx)", offset); } } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/lib/sanitizer_common/sanitizer_stacktrace_printer.h index 7be1d1977..ce85bd7f2 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace_printer.h +++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.h @@ -57,7 +57,8 @@ void RenderSourceLocation(InternalScopedString *buffer, const char *file, const char *strip_path_prefix); void RenderModuleLocation(InternalScopedString *buffer, const char *module, - uptr offset, const char *strip_path_prefix); + uptr offset, ModuleArch arch, + const char *strip_path_prefix); // Same as RenderFrame, but for data section (global variables). // Accepts %s, %l from above. diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc index 534e55f57..1cd5b6ee2 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer.cc @@ -33,9 +33,11 @@ void AddressInfo::Clear() { function_offset = kUnknown; } -void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset) { +void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset, + ModuleArch mod_arch) { module = internal_strdup(mod_name); module_offset = mod_offset; + module_arch = mod_arch; } SymbolizedStack::SymbolizedStack() : next(nullptr), info() {} diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h index 572f1dd75..4fc7742a2 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/lib/sanitizer_common/sanitizer_symbolizer.h @@ -31,6 +31,7 @@ struct AddressInfo { char *module; uptr module_offset; + ModuleArch module_arch; static const uptr kUnknown = ~(uptr)0; char *function; @@ -43,7 +44,7 @@ struct AddressInfo { AddressInfo(); // Deletes all strings and resets all fields. void Clear(); - void FillModuleInfo(const char *mod_name, uptr mod_offset); + void FillModuleInfo(const char *mod_name, uptr mod_offset, ModuleArch arch); }; // Linked list of symbolized frames (each frame is described by AddressInfo). @@ -65,6 +66,8 @@ struct DataInfo { // (de)allocated using sanitizer internal allocator. char *module; uptr module_offset; + ModuleArch module_arch; + char *file; uptr line; char *name; @@ -143,7 +146,8 @@ class Symbolizer final { static Symbolizer *PlatformInit(); bool FindModuleNameAndOffsetForAddress(uptr address, const char **module_name, - uptr *module_offset); + uptr *module_offset, + ModuleArch *module_arch); ListOfModules modules_; // If stale, need to reload the modules before looking up addresses. bool modules_fresh_; diff --git a/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/lib/sanitizer_common/sanitizer_symbolizer_internal.h index ada059cd7..2ae42b338 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -124,8 +124,8 @@ class LLVMSymbolizer : public SymbolizerTool { bool SymbolizeData(uptr addr, DataInfo *info) override; private: - const char *SendCommand(bool is_data, const char *module_name, - uptr module_offset); + const char *FormatAndSendCommand(bool is_data, const char *module_name, + uptr module_offset, ModuleArch arch); LLVMSymbolizerProcess *symbolizer_process_; static const uptr kBufferSize = 16 * 1024; diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc index 31506fe5c..7c377a729 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -64,11 +64,13 @@ SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { BlockingMutexLock l(&mu_); const char *module_name; uptr module_offset; + ModuleArch arch; SymbolizedStack *res = SymbolizedStack::New(addr); - if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset, + &arch)) return res; // Always fill data about module name and offset. - res->info.FillModuleInfo(module_name, module_offset); + res->info.FillModuleInfo(module_name, module_offset, arch); for (auto &tool : tools_) { SymbolizerScope sym_scope(this); if (tool.SymbolizePC(addr, res)) { @@ -82,11 +84,14 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { BlockingMutexLock l(&mu_); const char *module_name; uptr module_offset; - if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset)) + ModuleArch arch; + if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset, + &arch)) return false; info->Clear(); info->module = internal_strdup(module_name); info->module_offset = module_offset; + info->module_arch = arch; for (auto &tool : tools_) { SymbolizerScope sym_scope(this); if (tool.SymbolizeData(addr, info)) { @@ -100,8 +105,9 @@ bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, uptr *module_address) { BlockingMutexLock l(&mu_); const char *internal_module_name = nullptr; + ModuleArch arch; if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name, - module_address)) + module_address, &arch)) return false; if (module_name) @@ -134,12 +140,14 @@ void Symbolizer::PrepareForSandboxing() { bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, const char **module_name, - uptr *module_offset) { + uptr *module_offset, + ModuleArch *module_arch) { const LoadedModule *module = FindModuleForAddress(address); if (module == nullptr) return false; *module_name = module->full_name(); *module_offset = address - module->base_address(); + *module_arch = module->arch(); return true; } @@ -197,6 +205,8 @@ class LLVMSymbolizerProcess : public SymbolizerProcess { buffer[length - 2] == '\n'; } + // When adding a new architecture, don't forget to also update + // script/asan_symbolize.py and sanitizer_common.h. void GetArgV(const char *path_to_binary, const char *(&argv)[kArgVMax]) const override { #if defined(__x86_64h__) @@ -284,7 +294,8 @@ void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) { top_frame = false; } else { cur = SymbolizedStack::New(res->info.address); - cur->info.FillModuleInfo(res->info.module, res->info.module_offset); + cur->info.FillModuleInfo(res->info.module, res->info.module_offset, + res->info.module_arch); last->next = cur; last = cur; } @@ -317,8 +328,10 @@ void ParseSymbolizeDataOutput(const char *str, DataInfo *info) { } bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { - if (const char *buf = SendCommand(/*is_data*/ false, stack->info.module, - stack->info.module_offset)) { + AddressInfo *info = &stack->info; + const char *buf = FormatAndSendCommand( + /*is_data*/ false, info->module, info->module_offset, info->module_arch); + if (buf) { ParseSymbolizePCOutput(buf, stack); return true; } @@ -326,8 +339,9 @@ bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { } bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { - if (const char *buf = - SendCommand(/*is_data*/ true, info->module, info->module_offset)) { + const char *buf = FormatAndSendCommand( + /*is_data*/ true, info->module, info->module_offset, info->module_arch); + if (buf) { ParseSymbolizeDataOutput(buf, info); info->start += (addr - info->module_offset); // Add the base address. return true; @@ -335,11 +349,19 @@ bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { return false; } -const char *LLVMSymbolizer::SendCommand(bool is_data, const char *module_name, - uptr module_offset) { +const char *LLVMSymbolizer::FormatAndSendCommand(bool is_data, + const char *module_name, + uptr module_offset, + ModuleArch arch) { CHECK(module_name); - internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", - is_data ? "DATA " : "", module_name, module_offset); + const char *is_data_str = is_data ? "DATA " : ""; + if (arch == kModuleArchUnknown) { + internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str, + module_name, module_offset); + } else { + internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n", is_data_str, + module_name, ModuleArchToString(arch), module_offset); + } return symbolizer_process_->SendCommand(buffer_); } diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc index 05796fcbf..405f8d86e 100644 --- a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc @@ -52,13 +52,18 @@ TEST(SanitizerStacktracePrinter, RenderSourceLocation) { TEST(SanitizerStacktracePrinter, RenderModuleLocation) { InternalScopedString str(128); - RenderModuleLocation(&str, "/dir/exe", 0x123, ""); + RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, ""); EXPECT_STREQ("(/dir/exe+0x123)", str.data()); // Check that we strip file prefix if necessary. str.clear(); - RenderModuleLocation(&str, "/dir/exe", 0x123, "/dir/"); + RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/"); EXPECT_STREQ("(exe+0x123)", str.data()); + + // Check that we render the arch. + str.clear(); + RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/"); + EXPECT_STREQ("(exe:x86_64h+0x123)", str.data()); } TEST(SanitizerStacktracePrinter, RenderFrame) { diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc index d842694aa..c531c5f77 100644 --- a/lib/ubsan/ubsan_diag.cc +++ b/lib/ubsan/ubsan_diag.cc @@ -157,7 +157,7 @@ static void RenderLocation(InternalScopedString *Buffer, Location Loc) { common_flags()->strip_path_prefix); else if (Info.module) RenderModuleLocation(Buffer, Info.module, Info.module_offset, - common_flags()->strip_path_prefix); + Info.module_arch, common_flags()->strip_path_prefix); else Buffer->append("%p", Info.address); return; |