[compiler-rt] r197571 - [Sanitizer] Implement Symbolizer class on Windows

Timur Iskhodzhanov timurrrr at google.com
Wed Dec 18 06:29:16 PST 2013


Author: timurrrr
Date: Wed Dec 18 08:29:16 2013
New Revision: 197571

URL: http://llvm.org/viewvc/llvm-project?rev=197571&view=rev
Log:
[Sanitizer] Implement Symbolizer class on Windows

Modified:
    compiler-rt/trunk/lib/asan/asan_stack.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc

Modified: compiler-rt/trunk/lib/asan/asan_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.cc?rev=197571&r1=197570&r2=197571&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.cc Wed Dec 18 08:29:16 2013
@@ -39,7 +39,7 @@ void PrintStack(StackTrace *stack) {
 // Provide default implementation of __asan_symbolize that does nothing
 // and may be overriden by user if he wants to use his own symbolization.
 // ASan on Windows has its own implementation of this.
-#if !SANITIZER_WINDOWS && !SANITIZER_SUPPORTS_WEAK_HOOKS
+#if !SANITIZER_SUPPORTS_WEAK_HOOKS
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE
 bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) {
   return false;

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=197571&r1=197570&r2=197571&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Wed Dec 18 08:29:16 2013
@@ -35,11 +35,6 @@ extern "C" {
 
 namespace __asan {
 
-// ---------------------- Stacktraces, symbols, etc. ---------------- {{{1
-static BlockingMutex dbghelp_lock(LINKER_INITIALIZED);
-static bool dbghelp_initialized = false;
-#pragma comment(lib, "dbghelp.lib")
-
 // ---------------------- TSD ---------------- {{{1
 static bool tsd_key_inited = false;
 
@@ -97,52 +92,4 @@ void ReadContextStack(void *context, upt
 
 }  // namespace __asan
 
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan;  // NOLINT
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE NOINLINE
-bool __asan_symbolize(const void *addr, char *out_buffer, int buffer_size) {
-  BlockingMutexLock lock(&dbghelp_lock);
-  if (!dbghelp_initialized) {
-    SymSetOptions(SYMOPT_DEFERRED_LOADS |
-                  SYMOPT_UNDNAME |
-                  SYMOPT_LOAD_LINES);
-    CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE));
-    // FIXME: We don't call SymCleanup() on exit yet - should we?
-    dbghelp_initialized = true;
-  }
-
-  // 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 info;
-  info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
-  BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(),
-                                           (DWORD64)addr, &unused, &info);
-  int written = 0;
-  out_buffer[0] = '\0';
-  // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too.
-  if (got_fileline) {
-    written += internal_snprintf(out_buffer + written, buffer_size - written,
-                        " %s %s:%d", symbol->Name,
-                        info.FileName, info.LineNumber);
-  } else {
-    written += internal_snprintf(out_buffer + written, buffer_size - written,
-                        " %s+0x%p", symbol->Name, offset);
-  }
-  return true;
-}
-}  // extern "C"
-
-
 #endif  // _WIN32

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc?rev=197571&r1=197570&r2=197571&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc Wed Dec 18 08:29:16 2013
@@ -79,6 +79,9 @@ void StackTrace::PrintStack(const uptr *
         PrintStackFramePrefix(&frame_desc, frame_num, pc);
         if (info.function) {
           frame_desc.append(" in %s", info.function);
+          // Print offset in function if we don't know the source file.
+          if (!info.file && info.function_offset != AddressInfo::kUnknown)
+            frame_desc.append("+0x%zx", info.function_offset);
         }
         if (info.file) {
           frame_desc.append(" ");

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h?rev=197571&r1=197570&r2=197571&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer.h Wed Dec 18 08:29:16 2013
@@ -27,23 +27,30 @@ namespace __sanitizer {
 
 struct AddressInfo {
   uptr address;
+
   char *module;
   uptr module_offset;
+
+  static const uptr kUnknown = ~(uptr)0;
   char *function;
+  uptr function_offset;
+
   char *file;
   int line;
   int column;
 
   AddressInfo() {
     internal_memset(this, 0, sizeof(AddressInfo));
+    function_offset = kUnknown;
   }
 
-  // Deletes all strings and sets all fields to zero.
+  // Deletes all strings and resets all fields.
   void Clear() {
     InternalFree(module);
     InternalFree(function);
     InternalFree(file);
     internal_memset(this, 0, sizeof(AddressInfo));
+    function_offset = kUnknown;
   }
 
   void FillAddressAndModuleInfo(uptr addr, const char *mod_name,

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=197571&r1=197570&r2=197571&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_win.cc Wed Dec 18 08:29:16 2013
@@ -14,11 +14,83 @@
 
 #include "sanitizer_platform.h"
 #if SANITIZER_WINDOWS
+#include <windows.h>
+#include <dbghelp.h>
+#pragma comment(lib, "dbghelp.lib")
+
 #include "sanitizer_symbolizer.h"
 
 namespace __sanitizer {
 
-Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) { return 0; }
+class WinSymbolizer : public Symbolizer {
+ public:
+  WinSymbolizer() : initialized_(false) {}
+
+  uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) {
+    if (max_frames == 0)
+      return 0;
+
+    BlockingMutexLock l(&dbghelp_mu_);
+    if (!initialized_) {
+      SymSetOptions(SYMOPT_DEFERRED_LOADS |
+                    SYMOPT_UNDNAME |
+                    SYMOPT_LOAD_LINES);
+      CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE));
+      // FIXME: We don't call SymCleanup() on exit yet - should we?
+      initialized_ = true;
+    }
+
+    // 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 0;
+
+    DWORD unused;
+    IMAGEHLP_LINE64 line_info;
+    line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+    BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)addr,
+                                             &unused, &line_info);
+    AddressInfo *info = &frames[0];
+    info->Clear();
+    info->function = internal_strdup(symbol->Name);
+    info->function_offset = offset;
+    if (got_fileline) {
+      info->file = internal_strdup(line_info.FileName);
+      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))
+      info->FillAddressAndModuleInfo(addr, mod_info.ImageName,
+                                     addr - mod_info.BaseOfImage);
+    return 1;
+  }
+
+  bool IsAvailable() {
+    return true;
+  }
+
+ private:
+  // All DbgHelp functions are single threaded, so we should use a mutex to
+  // serialize accesses.
+  BlockingMutex dbghelp_mu_;
+  bool initialized_;
+};
+
+Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) {
+  static bool called_once = false;
+  CHECK(!called_once && "Shouldn't create more than one symbolizer");
+  called_once = true;
+  return new(symbolizer_allocator_) WinSymbolizer();
+}
 
 }  // namespace __sanitizer
 





More information about the llvm-commits mailing list