< prev index next >

src/os/windows/vm/windbghelp.cpp

Print this page
rev 13549 : 8185712: [windows] Improve native symbol decoder
Reviewed-by: goetz, zgu


  99     // Note: We loaded the DLL successfully. From here on we count
 100     // initialization as success. We still may fail to load all of the
 101     // desired function pointers successfully, but DLL may still be usable
 102     // enough for our purposes.
 103     g_state = state_ready;
 104 
 105 #define DO_RESOLVE(functionname) \
 106       g_pfn_##functionname = (pfn_##functionname) ::GetProcAddress(g_dll_handle, #functionname);
 107 
 108     FOR_ALL_FUNCTIONS(DO_RESOLVE)
 109 
 110     // Retrieve version information.
 111     if (g_pfn_ImagehlpApiVersion) {
 112       const API_VERSION* p = g_pfn_ImagehlpApiVersion();
 113       memcpy(&g_version, p, sizeof(API_VERSION));
 114     }
 115   }
 116 
 117 }
 118 

 119 ///////////////////// External functions //////////////////////////
 120 
 121 // All outside facing functions are synchronized. Also, we run
 122 // initialization on first touch.
 123 

 124 
 125 // Call InitializeCriticalSection as early as possible.
 126 class CritSect {
 127   CRITICAL_SECTION cs;
 128 public:
 129   CritSect() { ::InitializeCriticalSection(&cs); }
 130   void enter() { ::EnterCriticalSection(&cs); }
 131   void leave() { ::LeaveCriticalSection(&cs); }
 132 };
 133 
 134 static CritSect g_cs;
 135 
 136 class EntryGuard {
 137 public:
 138   EntryGuard() {
 139     g_cs.enter();
 140     if (g_state == state_uninitialized) {
 141       initialize();
 142     }
 143   }
 144   ~EntryGuard() {
 145     g_cs.leave();
 146   }
 147 };






 148 
 149 DWORD WindowsDbgHelp::symSetOptions(DWORD arg) {
 150   EntryGuard entry_guard;
 151   if (g_pfn_SymSetOptions != NULL) {
 152     return g_pfn_SymSetOptions(arg);
 153   }
 154   return 0;
 155 }
 156 
 157 DWORD WindowsDbgHelp::symGetOptions(void) {
 158   EntryGuard entry_guard;
 159   if (g_pfn_SymGetOptions != NULL) {
 160     return g_pfn_SymGetOptions();
 161   }
 162   return 0;
 163 }
 164 
 165 BOOL WindowsDbgHelp::symInitialize(HANDLE hProcess, PCTSTR UserSearchPath, BOOL fInvadeProcess) {
 166   EntryGuard entry_guard;
 167   if (g_pfn_SymInitialize != NULL) {
 168     return g_pfn_SymInitialize(hProcess, UserSearchPath, fInvadeProcess);
 169   }
 170   return FALSE;
 171 }
 172 
 173 BOOL WindowsDbgHelp::symGetSymFromAddr64(HANDLE hProcess, DWORD64 the_address,
 174                                          PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol) {
 175   EntryGuard entry_guard;
 176   if (g_pfn_SymGetSymFromAddr64 != NULL) {
 177     return g_pfn_SymGetSymFromAddr64(hProcess, the_address, Displacement, Symbol);
 178   }
 179   return FALSE;
 180 }
 181 
 182 DWORD WindowsDbgHelp::unDecorateSymbolName(const char* DecoratedName, char* UnDecoratedName,
 183                                            DWORD UndecoratedLength, DWORD Flags) {
 184   EntryGuard entry_guard;
 185   if (g_pfn_UnDecorateSymbolName != NULL) {
 186     return g_pfn_UnDecorateSymbolName(DecoratedName, UnDecoratedName, UndecoratedLength, Flags);
 187   }
 188   if (UnDecoratedName != NULL && UndecoratedLength > 0) {
 189     UnDecoratedName[0] = '\0';
 190   }
 191   return 0;
 192 }
 193 
 194 BOOL WindowsDbgHelp::symSetSearchPath(HANDLE hProcess, PCTSTR SearchPath) {
 195   EntryGuard entry_guard;
 196   if (g_pfn_SymSetSearchPath != NULL) {
 197     return g_pfn_SymSetSearchPath(hProcess, SearchPath);
 198   }
 199   return FALSE;
 200 }
 201 
 202 BOOL WindowsDbgHelp::symGetSearchPath(HANDLE hProcess, PTSTR SearchPath, int SearchPathLength) {
 203   EntryGuard entry_guard;
 204   if (g_pfn_SymGetSearchPath != NULL) {
 205     return g_pfn_SymGetSearchPath(hProcess, SearchPath, SearchPathLength);
 206   }
 207   return FALSE;
 208 }
 209 
 210 BOOL WindowsDbgHelp::stackWalk64(DWORD MachineType,
 211                                  HANDLE hProcess,
 212                                  HANDLE hThread,
 213                                  LPSTACKFRAME64 StackFrame,
 214                                  PVOID ContextRecord) {
 215   EntryGuard entry_guard;
 216   if (g_pfn_StackWalk64 != NULL) {
 217     return g_pfn_StackWalk64(MachineType, hProcess, hThread, StackFrame,
 218                              ContextRecord,
 219                              NULL, // ReadMemoryRoutine
 220                              g_pfn_SymFunctionTableAccess64, // FunctionTableAccessRoutine,
 221                              g_pfn_SymGetModuleBase64, // GetModuleBaseRoutine
 222                              NULL // TranslateAddressRoutine
 223                              );
 224   }
 225   return FALSE;
 226 }
 227 
 228 PVOID WindowsDbgHelp::symFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) {
 229   EntryGuard entry_guard;
 230   if (g_pfn_SymFunctionTableAccess64 != NULL) {
 231     return g_pfn_SymFunctionTableAccess64(hProcess, AddrBase);
 232   }
 233   return NULL;
 234 }
 235 
 236 DWORD64 WindowsDbgHelp::symGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) {
 237   EntryGuard entry_guard;
 238   if (g_pfn_SymGetModuleBase64 != NULL) {
 239     return g_pfn_SymGetModuleBase64(hProcess, dwAddr);
 240   }
 241   return 0;
 242 }
 243 
 244 BOOL WindowsDbgHelp::miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
 245                                        MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
 246                                        PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
 247                                        PMINIDUMP_CALLBACK_INFORMATION CallbackParam) {
 248   EntryGuard entry_guard;
 249   if (g_pfn_MiniDumpWriteDump != NULL) {
 250     return g_pfn_MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType,
 251                                    ExceptionParam, UserStreamParam, CallbackParam);
 252   }
 253   return FALSE;
 254 }
 255 
 256 BOOL WindowsDbgHelp::symGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr,
 257                           PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line) {
 258   EntryGuard entry_guard;
 259   if (g_pfn_SymGetLineFromAddr64 != NULL) {
 260     return g_pfn_SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, Line);
 261   }
 262   return FALSE;
 263 }
 264 
 265 // Print one liner describing state (if library loaded, which functions are
 266 // missing - if any, and the dbhelp API version)
 267 void WindowsDbgHelp::print_state_on(outputStream* st) {
 268   // Note: We should not lock while printing, but this should be
 269   // safe to do without lock anyway.
 270   st->print("dbghelp: ");
 271 
 272   if (g_state == state_uninitialized) {
 273     st->print("uninitialized.");
 274   } else if (g_state == state_error) {
 275     st->print("loading error: %u", g_dll_load_error);
 276   } else {
 277     st->print("loaded successfully ");
 278 




  99     // Note: We loaded the DLL successfully. From here on we count
 100     // initialization as success. We still may fail to load all of the
 101     // desired function pointers successfully, but DLL may still be usable
 102     // enough for our purposes.
 103     g_state = state_ready;
 104 
 105 #define DO_RESOLVE(functionname) \
 106       g_pfn_##functionname = (pfn_##functionname) ::GetProcAddress(g_dll_handle, #functionname);
 107 
 108     FOR_ALL_FUNCTIONS(DO_RESOLVE)
 109 
 110     // Retrieve version information.
 111     if (g_pfn_ImagehlpApiVersion) {
 112       const API_VERSION* p = g_pfn_ImagehlpApiVersion();
 113       memcpy(&g_version, p, sizeof(API_VERSION));
 114     }
 115   }
 116 
 117 }
 118 
 119 
 120 ///////////////////// External functions //////////////////////////
 121 
 122 // All outside facing functions are synchronized. Also, we run
 123 // initialization on first touch.
 124 
 125 static CRITICAL_SECTION g_cs;
 126 
 127 namespace { // Do not export.
 128   class WindowsDbgHelpEntry {
 129    public:
 130     WindowsDbgHelpEntry() {
 131       ::EnterCriticalSection(&g_cs);










 132       if (g_state == state_uninitialized) {
 133         initialize();
 134       }
 135     }
 136     ~WindowsDbgHelpEntry() {
 137       ::LeaveCriticalSection(&g_cs);
 138     }
 139   };
 140 }
 141 
 142 // Called at DLL_PROCESS_ATTACH.
 143 void WindowsDbgHelp::pre_initialize() {
 144   ::InitializeCriticalSection(&g_cs);
 145 }
 146 
 147 DWORD WindowsDbgHelp::symSetOptions(DWORD arg) {
 148   WindowsDbgHelpEntry entry_guard;
 149   if (g_pfn_SymSetOptions != NULL) {
 150     return g_pfn_SymSetOptions(arg);
 151   }
 152   return 0;
 153 }
 154 
 155 DWORD WindowsDbgHelp::symGetOptions(void) {
 156   WindowsDbgHelpEntry entry_guard;
 157   if (g_pfn_SymGetOptions != NULL) {
 158     return g_pfn_SymGetOptions();
 159   }
 160   return 0;
 161 }
 162 
 163 BOOL WindowsDbgHelp::symInitialize(HANDLE hProcess, PCTSTR UserSearchPath, BOOL fInvadeProcess) {
 164   WindowsDbgHelpEntry entry_guard;
 165   if (g_pfn_SymInitialize != NULL) {
 166     return g_pfn_SymInitialize(hProcess, UserSearchPath, fInvadeProcess);
 167   }
 168   return FALSE;
 169 }
 170 
 171 BOOL WindowsDbgHelp::symGetSymFromAddr64(HANDLE hProcess, DWORD64 the_address,
 172                                          PDWORD64 Displacement, PIMAGEHLP_SYMBOL64 Symbol) {
 173   WindowsDbgHelpEntry entry_guard;
 174   if (g_pfn_SymGetSymFromAddr64 != NULL) {
 175     return g_pfn_SymGetSymFromAddr64(hProcess, the_address, Displacement, Symbol);
 176   }
 177   return FALSE;
 178 }
 179 
 180 DWORD WindowsDbgHelp::unDecorateSymbolName(const char* DecoratedName, char* UnDecoratedName,
 181                                            DWORD UndecoratedLength, DWORD Flags) {
 182   WindowsDbgHelpEntry entry_guard;
 183   if (g_pfn_UnDecorateSymbolName != NULL) {
 184     return g_pfn_UnDecorateSymbolName(DecoratedName, UnDecoratedName, UndecoratedLength, Flags);
 185   }
 186   if (UnDecoratedName != NULL && UndecoratedLength > 0) {
 187     UnDecoratedName[0] = '\0';
 188   }
 189   return 0;
 190 }
 191 
 192 BOOL WindowsDbgHelp::symSetSearchPath(HANDLE hProcess, PCTSTR SearchPath) {
 193   WindowsDbgHelpEntry entry_guard;
 194   if (g_pfn_SymSetSearchPath != NULL) {
 195     return g_pfn_SymSetSearchPath(hProcess, SearchPath);
 196   }
 197   return FALSE;
 198 }
 199 
 200 BOOL WindowsDbgHelp::symGetSearchPath(HANDLE hProcess, PTSTR SearchPath, int SearchPathLength) {
 201   WindowsDbgHelpEntry entry_guard;
 202   if (g_pfn_SymGetSearchPath != NULL) {
 203     return g_pfn_SymGetSearchPath(hProcess, SearchPath, SearchPathLength);
 204   }
 205   return FALSE;
 206 }
 207 
 208 BOOL WindowsDbgHelp::stackWalk64(DWORD MachineType,
 209                                  HANDLE hProcess,
 210                                  HANDLE hThread,
 211                                  LPSTACKFRAME64 StackFrame,
 212                                  PVOID ContextRecord) {
 213   WindowsDbgHelpEntry entry_guard;
 214   if (g_pfn_StackWalk64 != NULL) {
 215     return g_pfn_StackWalk64(MachineType, hProcess, hThread, StackFrame,
 216                              ContextRecord,
 217                              NULL, // ReadMemoryRoutine
 218                              g_pfn_SymFunctionTableAccess64, // FunctionTableAccessRoutine,
 219                              g_pfn_SymGetModuleBase64, // GetModuleBaseRoutine
 220                              NULL // TranslateAddressRoutine
 221                              );
 222   }
 223   return FALSE;
 224 }
 225 
 226 PVOID WindowsDbgHelp::symFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) {
 227   WindowsDbgHelpEntry entry_guard;
 228   if (g_pfn_SymFunctionTableAccess64 != NULL) {
 229     return g_pfn_SymFunctionTableAccess64(hProcess, AddrBase);
 230   }
 231   return NULL;
 232 }
 233 
 234 DWORD64 WindowsDbgHelp::symGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) {
 235   WindowsDbgHelpEntry entry_guard;
 236   if (g_pfn_SymGetModuleBase64 != NULL) {
 237     return g_pfn_SymGetModuleBase64(hProcess, dwAddr);
 238   }
 239   return 0;
 240 }
 241 
 242 BOOL WindowsDbgHelp::miniDumpWriteDump(HANDLE hProcess, DWORD ProcessId, HANDLE hFile,
 243                                        MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
 244                                        PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
 245                                        PMINIDUMP_CALLBACK_INFORMATION CallbackParam) {
 246   WindowsDbgHelpEntry entry_guard;
 247   if (g_pfn_MiniDumpWriteDump != NULL) {
 248     return g_pfn_MiniDumpWriteDump(hProcess, ProcessId, hFile, DumpType,
 249                                    ExceptionParam, UserStreamParam, CallbackParam);
 250   }
 251   return FALSE;
 252 }
 253 
 254 BOOL WindowsDbgHelp::symGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr,
 255                           PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line) {
 256   WindowsDbgHelpEntry entry_guard;
 257   if (g_pfn_SymGetLineFromAddr64 != NULL) {
 258     return g_pfn_SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, Line);
 259   }
 260   return FALSE;
 261 }
 262 
 263 // Print one liner describing state (if library loaded, which functions are
 264 // missing - if any, and the dbhelp API version)
 265 void WindowsDbgHelp::print_state_on(outputStream* st) {
 266   // Note: We should not lock while printing, but this should be
 267   // safe to do without lock anyway.
 268   st->print("dbghelp: ");
 269 
 270   if (g_state == state_uninitialized) {
 271     st->print("uninitialized.");
 272   } else if (g_state == state_error) {
 273     st->print("loading error: %u", g_dll_load_error);
 274   } else {
 275     st->print("loaded successfully ");
 276 


< prev index next >