[PATCH] [Sanitizer] Implement Symbolizer class on Windows.

Alexey Samsonov samsonov at google.com
Tue Dec 17 04:06:27 PST 2013


Hi timurrrr,

Turn __asan_symbolize() hook returning a raw buffer into an
implementation of Symbolizer class for Windows platform. This would allow
us to streamline the code working with symbolized stack traces on all platforms.

Note: This patch is not tested (or even built) on Windows.

http://llvm-reviews.chandlerc.com/D2422

Files:
  lib/sanitizer_common/sanitizer_symbolizer_win.cc
  lib/asan/asan_win.cc
  lib/asan/asan_stack.cc

Index: lib/sanitizer_common/sanitizer_symbolizer_win.cc
===================================================================
--- lib/sanitizer_common/sanitizer_symbolizer_win.cc
+++ lib/sanitizer_common/sanitizer_symbolizer_win.cc
@@ -14,11 +14,72 @@
 
 #include "sanitizer_platform.h"
 #if SANITIZER_WINDOWS
+#include <windows.h>
+#include <dbghelp.h>
+
 #include "sanitizer_symbolizer.h"
 
 namespace __sanitizer {
 
-Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) { return 0; }
+#pragma comment(lib, "dbghelp.lib")
+
+class WinSymbolizer : public Symbolizer {
+ public:
+  WinSymbolizer() : Symbolizer(), initialized_(false) {}
+
+  uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {
+    if (max_frames == 0)
+      return 0;
+    BlockingMutexLock l(&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, &info);
+
+    AddressInfo *info = &frames[0];
+    info->Clear();
+    info->function = internal_strdup(symbol->Name);
+    if (got_fileline) {
+      info->file = internal_strdup(line_info.FileName);
+      info->line = line_info.LineNumber;
+    }
+    // FIXME: fill 'module' and 'module_offset' fields too.
+    return 1;
+  }
+
+  bool IsAvailable() {
+    return true;
+  }
+
+ private:
+  BlockingMutex mu_;
+  bool initialized_;
+};
+
+Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) {
+  return new(symbolizer_allocator_) WinSymbolizer();
+}
 
 }  // namespace __sanitizer
 
Index: lib/asan/asan_win.cc
===================================================================
--- lib/asan/asan_win.cc
+++ lib/asan/asan_win.cc
@@ -35,11 +35,6 @@
 
 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 @@
 
 }  // 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
Index: lib/asan/asan_stack.cc
===================================================================
--- lib/asan/asan_stack.cc
+++ lib/asan/asan_stack.cc
@@ -39,7 +39,7 @@
 // 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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2422.1.patch
Type: text/x-patch
Size: 5423 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131217/dce9e146/attachment.bin>


More information about the llvm-commits mailing list