[compiler-rt] r231478 - Symbolizer refactoring: Make WinSymbolizer use SymbolizerTool interface
Alexey Samsonov
vonosmas at gmail.com
Fri Mar 6 16:36:31 PST 2015
Please add sanitizer_symbolizer_win.h to SANITIZER_HEADERS in CMakeLists.txt
On Fri, Mar 6, 2015 at 6:33 AM, Kuba Brecka <kuba.brecka at gmail.com> wrote:
> Author: kuba.brecka
> Date: Fri Mar 6 08:33:56 2015
> New Revision: 231478
>
> URL: http://llvm.org/viewvc/llvm-project?rev=231478&view=rev
> Log:
> Symbolizer refactoring: Make WinSymbolizer use SymbolizerTool interface
>
> Reviewed at http://reviews.llvm.org/D8089
>
>
> Added:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.h
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_internal.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_internal.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_internal.h?rev=231478&r1=231477&r2=231478&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_internal.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_internal.h
> Fri Mar 6 08:33:56 2015
> @@ -26,6 +26,9 @@ const char *ExtractToken(const char *str
> const char *ExtractInt(const char *str, const char *delims, int *result);
> const char *ExtractUptr(const char *str, const char *delims, uptr
> *result);
>
> +// SymbolizerTool is an interface that is implemented by individual
> "tools"
> +// that can perform symbolication (external llvm-symbolizer, libbacktrace,
> +// Windows DbgHelp symbolizer, etc.).
> class SymbolizerTool {
> public:
> // POSIXSymbolizer implements a "fallback chain" of symbolizer tools.
> In a
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc?rev=231478&r1=231477&r2=231478&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc Fri
> Mar 6 08:33:56 2015
> @@ -18,139 +18,171 @@
> #include <dbghelp.h>
> #pragma comment(lib, "dbghelp.lib")
>
> -#include "sanitizer_symbolizer.h"
> +#include "sanitizer_symbolizer_win.h"
> +#include "sanitizer_symbolizer_internal.h"
>
> namespace __sanitizer {
>
> -class WinSymbolizer : public Symbolizer {
> - public:
> - WinSymbolizer() : initialized_(false) {}
> +namespace {
>
> - SymbolizedStack *SymbolizePC(uptr addr) override {
> - SymbolizedStack *frame = SymbolizedStack::New(addr);
> +bool is_dbghelp_initialized = false;
>
> - BlockingMutexLock l(&dbghelp_mu_);
> - InitializeIfNeeded();
> +bool TrySymInitialize() {
> + SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME |
> SYMOPT_LOAD_LINES);
> + return SymInitialize(GetCurrentProcess(), 0, TRUE);
> + // FIXME: We don't call SymCleanup() on exit yet - should we?
> +}
>
> - // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
> - char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)];
> - PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
> - symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
> - symbol->MaxNameLen = MAX_SYM_NAME;
> - DWORD64 offset = 0;
> - BOOL got_objname = SymFromAddr(GetCurrentProcess(),
> - (DWORD64)addr, &offset, symbol);
> - if (!got_objname)
> - return frame;
> -
> - DWORD unused;
> - IMAGEHLP_LINE64 line_info;
> - line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
> - BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(),
> (DWORD64)addr,
> - &unused, &line_info);
> - frame->info.function = internal_strdup(symbol->Name);
> - frame->info.function_offset = (uptr)offset;
> - if (got_fileline) {
> - frame->info.file = internal_strdup(line_info.FileName);
> - frame->info.line = line_info.LineNumber;
> - }
> -
> - IMAGEHLP_MODULE64 mod_info;
> - internal_memset(&mod_info, 0, sizeof(mod_info));
> - mod_info.SizeOfStruct = sizeof(mod_info);
> - if (SymGetModuleInfo64(GetCurrentProcess(), addr, &mod_info))
> - frame->info.FillModuleInfo(mod_info.ImageName,
> - addr - (uptr)mod_info.BaseOfImage);
> - return frame;
> +// Initializes DbgHelp library, if it's not yet initialized. Calls to this
> +// function should be synchronized with respect to other calls to DbgHelp
> API
> +// (e.g. from WinSymbolizerTool).
> +void InitializeDbgHelpIfNeeded() {
> + if (is_dbghelp_initialized)
> + return;
> + if (!TrySymInitialize()) {
> + // OK, maybe the client app has called SymInitialize already.
> + // That's a bit unfortunate for us as all the DbgHelp functions are
> + // single-threaded and we can't coordinate with the app.
> + // FIXME: Can we stop the other threads at this point?
> + // Anyways, we have to reconfigure stuff to make sure that
> SymInitialize
> + // has all the appropriate options set.
> + // Cross our fingers and reinitialize DbgHelp.
> + Report("*** WARNING: Failed to initialize DbgHelp!
> ***\n");
> + Report("*** Most likely this means that the app is already
> ***\n");
> + Report("*** using DbgHelp, possibly with incompatible flags.
> ***\n");
> + Report("*** Due to technical reasons, symbolization might crash
> ***\n");
> + Report("*** or produce wrong results.
> ***\n");
> + SymCleanup(GetCurrentProcess());
> + TrySymInitialize();
> }
> + is_dbghelp_initialized = true;
>
> - bool CanReturnFileLineInfo() override {
> + // When an executable is run from a location different from the one
> where it
> + // was originally built, we may not see the nearby PDB files.
> + // To work around this, let's append the directory of the main module
> + // to the symbol search path. All the failures below are not fatal.
> + const size_t kSymPathSize = 2048;
> + static wchar_t path_buffer[kSymPathSize + 1 + MAX_PATH];
> + if (!SymGetSearchPathW(GetCurrentProcess(), path_buffer, kSymPathSize))
> {
> + Report("*** WARNING: Failed to SymGetSearchPathW ***\n");
> + return;
> + }
> + size_t sz = wcslen(path_buffer);
> + if (sz) {
> + CHECK_EQ(0, wcscat_s(path_buffer, L";"));
> + sz++;
> + }
> + DWORD res = GetModuleFileNameW(NULL, path_buffer + sz, MAX_PATH);
> + if (res == 0 || res == MAX_PATH) {
> + Report("*** WARNING: Failed to getting the EXE directory ***\n");
> + return;
> + }
> + // Write the zero character in place of the last backslash to get the
> + // directory of the main module at the end of path_buffer.
> + wchar_t *last_bslash = wcsrchr(path_buffer + sz, L'\\');
> + CHECK_NE(last_bslash, 0);
> + *last_bslash = L'\0';
> + if (!SymSetSearchPathW(GetCurrentProcess(), path_buffer)) {
> + Report("*** WARNING: Failed to SymSetSearchPathW\n");
> + return;
> + }
> +}
> +
> +} // namespace
> +
> +bool WinSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *frame) {
> + InitializeDbgHelpIfNeeded();
> +
> + // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
> + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)];
> + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
> + symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
> + symbol->MaxNameLen = MAX_SYM_NAME;
> + DWORD64 offset = 0;
> + BOOL got_objname = SymFromAddr(GetCurrentProcess(),
> + (DWORD64)addr, &offset, symbol);
> + if (!got_objname)
> + return false;
> +
> + DWORD unused;
> + IMAGEHLP_LINE64 line_info;
> + line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
> + BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(),
> (DWORD64)addr,
> + &unused, &line_info);
> + frame->info.function = internal_strdup(symbol->Name);
> + frame->info.function_offset = (uptr)offset;
> + if (got_fileline) {
> + frame->info.file = internal_strdup(line_info.FileName);
> + frame->info.line = line_info.LineNumber;
> + }
> + return true;
> +}
> +
> +const char *WinSymbolizerTool::Demangle(const char *name) {
> + CHECK(is_dbghelp_initialized);
> + static char demangle_buffer[1000];
> + if (name[0] == '\01' &&
> + UnDecorateSymbolName(name + 1, demangle_buffer,
> sizeof(demangle_buffer),
> + UNDNAME_NAME_ONLY))
> + return demangle_buffer;
> + else
> + return name;
> +}
> +
> +bool FindModuleNameAndOffsetForAddress(uptr addr, const char
> **module_name,
> + uptr *module_offset) {
> + InitializeDbgHelpIfNeeded();
> +
> + IMAGEHLP_MODULE64 mod_info;
> + internal_memset(&mod_info, 0, sizeof(mod_info));
> + mod_info.SizeOfStruct = sizeof(mod_info);
> + if (SymGetModuleInfo64(GetCurrentProcess(), addr, &mod_info)) {
> + *module_name = mod_info.ImageName;
> + *module_offset = addr - (uptr)mod_info.BaseOfImage;
> return true;
> }
> + return false;
> +}
>
> +// TODO(kuba.brecka): To be merged with POSIXSymbolizer.
> +class WinSymbolizer : public Symbolizer {
> + public:
> + explicit WinSymbolizer(SymbolizerTool *tool) : Symbolizer(),
> tool_(tool) {
> + CHECK(tool);
> + }
> + SymbolizedStack *SymbolizePC(uptr addr) override {
> + BlockingMutexLock l(&mu_);
> + const char *module_name;
> + uptr module_offset;
> + SymbolizedStack *res = SymbolizedStack::New(addr);
> + if (FindModuleNameAndOffsetForAddress(addr, &module_name,
> &module_offset))
> + res->info.FillModuleInfo(module_name, module_offset);
> + tool_->SymbolizePC(addr, res);
> + return res;
> + }
> + bool CanReturnFileLineInfo() override {
> + return true;
> + }
> const char *Demangle(const char *name) override {
> - CHECK(initialized_);
> - static char demangle_buffer[1000];
> - if (name[0] == '\01' &&
> - UnDecorateSymbolName(name + 1, demangle_buffer,
> sizeof(demangle_buffer),
> - UNDNAME_NAME_ONLY))
> - return demangle_buffer;
> - else
> - return name;
> - }
> -
> - // FIXME: Implement GetModuleNameAndOffsetForPC().
> -
> - private:
> - void InitializeIfNeeded() {
> - if (initialized_)
> - return;
> - if (!TrySymInitialize()) {
> - // OK, maybe the client app has called SymInitialize already.
> - // That's a bit unfortunate for us as all the DbgHelp functions are
> - // single-threaded and we can't coordinate with the app.
> - // FIXME: Can we stop the other threads at this point?
> - // Anyways, we have to reconfigure stuff to make sure that
> SymInitialize
> - // has all the appropriate options set.
> - // Cross our fingers and reinitialize DbgHelp.
> - Report("*** WARNING: Failed to initialize DbgHelp!
> ***\n");
> - Report("*** Most likely this means that the app is already
> ***\n");
> - Report("*** using DbgHelp, possibly with incompatible flags.
> ***\n");
> - Report("*** Due to technical reasons, symbolization might crash
> ***\n");
> - Report("*** or produce wrong results.
> ***\n");
> - SymCleanup(GetCurrentProcess());
> - TrySymInitialize();
> - }
> - initialized_ = true;
> -
> - // When an executable is run from a location different from the one
> where it
> - // was originally built, we may not see the nearby PDB files.
> - // To work around this, let's append the directory of the main module
> - // to the symbol search path. All the failures below are not fatal.
> - const size_t kSymPathSize = 2048;
> - static wchar_t path_buffer[kSymPathSize + 1 + MAX_PATH];
> - if (!SymGetSearchPathW(GetCurrentProcess(), path_buffer,
> kSymPathSize)) {
> - Report("*** WARNING: Failed to SymGetSearchPathW ***\n");
> - return;
> - }
> - size_t sz = wcslen(path_buffer);
> - if (sz) {
> - CHECK_EQ(0, wcscat_s(path_buffer, L";"));
> - sz++;
> - }
> - DWORD res = GetModuleFileNameW(NULL, path_buffer + sz, MAX_PATH);
> - if (res == 0 || res == MAX_PATH) {
> - Report("*** WARNING: Failed to getting the EXE directory ***\n");
> - return;
> - }
> - // Write the zero character in place of the last backslash to get the
> - // directory of the main module at the end of path_buffer.
> - wchar_t *last_bslash = wcsrchr(path_buffer + sz, L'\\');
> - CHECK_NE(last_bslash, 0);
> - *last_bslash = L'\0';
> - if (!SymSetSearchPathW(GetCurrentProcess(), path_buffer)) {
> - Report("*** WARNING: Failed to SymSetSearchPathW\n");
> - return;
> - }
> - }
> -
> - bool TrySymInitialize() {
> - SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME |
> SYMOPT_LOAD_LINES);
> - return SymInitialize(GetCurrentProcess(), 0, TRUE);
> - // FIXME: We don't call SymCleanup() on exit yet - should we?
> - }
> -
> - // All DbgHelp functions are single threaded, so we should use a mutex
> to
> - // serialize accesses.
> - BlockingMutex dbghelp_mu_;
> - bool initialized_;
> + BlockingMutexLock l(&mu_);
> + return tool_->Demangle(name);
> + }
> + bool GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
> + uptr *module_address) override {
> + BlockingMutexLock l(&mu_);
> + return FindModuleNameAndOffsetForAddress(pc, module_name,
> module_address);
> + }
> +
> + BlockingMutex mu_;
> + SymbolizerTool *tool_;
> };
>
> Symbolizer *Symbolizer::PlatformInit() {
> static bool called_once = false;
> CHECK(!called_once && "Shouldn't create more than one symbolizer");
> called_once = true;
> - return new(symbolizer_allocator_) WinSymbolizer();
> + SymbolizerTool *tool = new(symbolizer_allocator_) WinSymbolizerTool();
> + return new(symbolizer_allocator_) WinSymbolizer(tool);
> }
>
> } // namespace __sanitizer
>
> Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.h?rev=231478&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.h
> (added)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.h Fri
> Mar 6 08:33:56 2015
> @@ -0,0 +1,31 @@
> +//===-- sanitizer_symbolizer_win.h ------------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Header file for the Windows symbolizer tool.
> +//
>
> +//===----------------------------------------------------------------------===//
> +#ifndef SANITIZER_SYMBOLIZER_WIN_H
> +#define SANITIZER_SYMBOLIZER_WIN_H
> +
> +#include "sanitizer_symbolizer_internal.h"
> +
> +namespace __sanitizer {
> +
> +class WinSymbolizerTool : public SymbolizerTool {
> + public:
> + bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
> + bool SymbolizeData(uptr addr, DataInfo *info) override {
> + return false;
> + }
> + const char *Demangle(const char *name) override;
> +};
> +
> +} // namespace __sanitizer
> +
> +#endif // SANITIZER_SYMBOLIZER_WIN_H
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150306/ce9266ea/attachment.html>
More information about the llvm-commits
mailing list