Use StringUtils instead of strrchr, some code cleanup.
This commit is contained in:
parent
5a35bb6195
commit
6d61ef7fb9
@ -17,7 +17,10 @@
|
|||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "crash_reporting.hpp"
|
#include "crash_reporting.hpp"
|
||||||
#include "log.hpp"
|
|
||||||
|
#include "utils/log.hpp"
|
||||||
|
#include "utils/string_utils.hpp"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(DEBUG) && !defined(__MINGW32__)
|
#if defined(WIN32) && !defined(DEBUG) && !defined(__MINGW32__)
|
||||||
@ -161,8 +164,8 @@
|
|||||||
// ----- Per-thread handlers -----
|
// ----- Per-thread handlers -----
|
||||||
// TODO
|
// TODO
|
||||||
} // installHandlers
|
} // installHandlers
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
void getCallStackWithContext(std::string& callstack, PCONTEXT pContext)
|
void getCallStackWithContext(std::string& callstack, PCONTEXT pContext)
|
||||||
{
|
{
|
||||||
HINSTANCE hDbgHelpDll = LoadLibraryA("DbgHelp.dll");
|
HINSTANCE hDbgHelpDll = LoadLibraryA("DbgHelp.dll");
|
||||||
@ -176,10 +179,12 @@
|
|||||||
// Retrieve the DLL functions
|
// Retrieve the DLL functions
|
||||||
#define GET_FUNC_PTR(FuncName) \
|
#define GET_FUNC_PTR(FuncName) \
|
||||||
t##FuncName _##FuncName = (t##FuncName)GetProcAddress(hDbgHelpDll, #FuncName); \
|
t##FuncName _##FuncName = (t##FuncName)GetProcAddress(hDbgHelpDll, #FuncName); \
|
||||||
if(!_##FuncName) { \
|
if(!_##FuncName) \
|
||||||
Log::warn("CrashReporting", "Failed to import symbol " #FuncName " from hDbgHelpDll"); \
|
{ \
|
||||||
FreeLibrary(hDbgHelpDll); \
|
Log::warn("CrashReporting", "Failed to import symbol " #FuncName \
|
||||||
return; \
|
" from hDbgHelpDll"); \
|
||||||
|
FreeLibrary(hDbgHelpDll); \
|
||||||
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_FUNC_PTR(SymCleanup)
|
GET_FUNC_PTR(SymCleanup)
|
||||||
@ -192,50 +197,45 @@
|
|||||||
GET_FUNC_PTR(UnDecorateSymbolName)
|
GET_FUNC_PTR(UnDecorateSymbolName)
|
||||||
GET_FUNC_PTR(SymFromAddr);
|
GET_FUNC_PTR(SymFromAddr);
|
||||||
GET_FUNC_PTR(StackWalk64);
|
GET_FUNC_PTR(StackWalk64);
|
||||||
|
|
||||||
#undef GET_FUNC_PTR
|
#undef GET_FUNC_PTR
|
||||||
|
|
||||||
|
|
||||||
const HANDLE hProcess = GetCurrentProcess();
|
const HANDLE hProcess = GetCurrentProcess();
|
||||||
const HANDLE hThread = GetCurrentThread();
|
const HANDLE hThread = GetCurrentThread();
|
||||||
|
|
||||||
|
// Since the stack trace can also be used for leak checks, don't
|
||||||
|
// initialise this all the time.
|
||||||
|
static bool first_time = true;
|
||||||
|
|
||||||
// Initialize the symbol hander for the process
|
// Initialize the symbol hander for the process
|
||||||
|
if (first_time)
|
||||||
{
|
{
|
||||||
// Get the file path of the executable
|
// Get the file path of the executable
|
||||||
char filepath[512];
|
char filepath[512];
|
||||||
GetModuleFileNameA(NULL, filepath, sizeof(filepath));
|
GetModuleFileNameA(NULL, filepath, sizeof(filepath));
|
||||||
if(!filepath)
|
if (!filepath)
|
||||||
{
|
{
|
||||||
Log::warn("CrashReporting", "GetModuleFileNameA failed");
|
Log::warn("CrashReporting", "GetModuleFileNameA failed");
|
||||||
FreeLibrary(hDbgHelpDll);
|
FreeLibrary(hDbgHelpDll);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only keep the directory
|
// Only keep the directory
|
||||||
char* last_separator = strrchr(filepath, '/');
|
std::string s(filepath);
|
||||||
if(!last_separator) last_separator = strrchr(filepath, '\\');
|
std::string path = StringUtils::getPath(s);
|
||||||
if(last_separator)
|
|
||||||
last_separator[0] = '\0';
|
|
||||||
|
|
||||||
// Since the stack trace can also be used for leak checks, don't
|
// Finally initialize the symbol handler.
|
||||||
// initialise this all the time.
|
BOOL bOk = _SymInitialize(hProcess,
|
||||||
static bool first_time = true;
|
path.empty() ? NULL : path.c_str(),
|
||||||
|
TRUE);
|
||||||
if (first_time)
|
if (!bOk)
|
||||||
{
|
{
|
||||||
// Finally initialize the symbol handler.
|
Log::warn("CrashReporting", "SymInitialize() failed");
|
||||||
BOOL bOk = _SymInitialize(hProcess, filepath ? filepath : NULL, TRUE);
|
FreeLibrary(hDbgHelpDll);
|
||||||
if (!bOk)
|
return;
|
||||||
{
|
|
||||||
Log::warn("CrashReporting", "SymInitialize() failed");
|
|
||||||
FreeLibrary(hDbgHelpDll);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SymSetOptions(SYMOPT_LOAD_LINES);
|
|
||||||
first_time = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
_SymSetOptions(SYMOPT_LOAD_LINES);
|
||||||
|
first_time = false;
|
||||||
|
} // if first_time
|
||||||
|
|
||||||
// Get the stack trace
|
// Get the stack trace
|
||||||
{
|
{
|
||||||
@ -263,63 +263,43 @@
|
|||||||
const int max_nb_calls = 32;
|
const int max_nb_calls = 32;
|
||||||
for(int i=0 ; i < max_nb_calls ; i++)
|
for(int i=0 ; i < max_nb_calls ; i++)
|
||||||
{
|
{
|
||||||
const BOOL stackframe_ok = _StackWalk64( machine_type,
|
const BOOL stackframe_ok =
|
||||||
hProcess,
|
_StackWalk64(machine_type, hProcess, hThread,
|
||||||
hThread,
|
&stackframe, pContext, NULL,
|
||||||
&stackframe,
|
_SymFunctionTableAccess64,
|
||||||
pContext,
|
_SymGetModuleBase64, NULL );
|
||||||
NULL,
|
if (!stackframe_ok) break;
|
||||||
_SymFunctionTableAccess64,
|
|
||||||
_SymGetModuleBase64,
|
// Decode the symbol and add it to the call stack
|
||||||
NULL);
|
DWORD64 sym_displacement;
|
||||||
if(stackframe_ok)
|
char buffer[ sizeof(SYMBOL_INFO) +
|
||||||
|
MAX_SYM_NAME * sizeof(TCHAR) ];
|
||||||
|
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
||||||
|
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||||
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
if (!_SymFromAddr(hProcess, stackframe.AddrPC.Offset,
|
||||||
|
&sym_displacement, symbol))
|
||||||
{
|
{
|
||||||
// Decode the symbol and add it to the call stack
|
callstack += "\n <no symbol available>";
|
||||||
DWORD64 sym_displacement;
|
continue;
|
||||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
|
||||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
|
||||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
|
||||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
||||||
if(_SymFromAddr(hProcess, stackframe.AddrPC.Offset,
|
|
||||||
&sym_displacement, symbol) )
|
|
||||||
{
|
|
||||||
IMAGEHLP_LINE64 line64;
|
|
||||||
DWORD dwDisplacement = (DWORD)sym_displacement;
|
|
||||||
if(_SymGetLineFromAddr64(hProcess, stackframe.AddrPC.Offset, &dwDisplacement, &line64))
|
|
||||||
{
|
|
||||||
callstack += "\n ";
|
|
||||||
|
|
||||||
// Directory + filename -> filename only
|
|
||||||
const char* filename = line64.FileName;
|
|
||||||
const char* ptr = line64.FileName;
|
|
||||||
while(*ptr)
|
|
||||||
{
|
|
||||||
if(*ptr == '\\' || *ptr == '/')
|
|
||||||
filename = ptr+1;
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
callstack += filename;
|
|
||||||
callstack += ":";
|
|
||||||
callstack += symbol->Name;
|
|
||||||
|
|
||||||
char str[128];
|
|
||||||
_itoa(line64.LineNumber, str, 10);
|
|
||||||
callstack += ":";
|
|
||||||
callstack += str;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
callstack += "\n ";
|
|
||||||
callstack += symbol->Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
callstack += "\n <no symbol available>";
|
|
||||||
}
|
}
|
||||||
|
IMAGEHLP_LINE64 line64;
|
||||||
|
DWORD dwDisplacement = (DWORD)sym_displacement;
|
||||||
|
if (_SymGetLineFromAddr64(hProcess,
|
||||||
|
stackframe.AddrPC.Offset,
|
||||||
|
&dwDisplacement, &line64))
|
||||||
|
{
|
||||||
|
std::string s(line64.FileName);
|
||||||
|
callstack += "\n " + StringUtils::getBasename(s)
|
||||||
|
+ ":" + symbol->Name + ":"
|
||||||
|
+ StringUtils::toString(line64.LineNumber);
|
||||||
|
} // if SymGetLineFromAddr64
|
||||||
else
|
else
|
||||||
break; // done
|
{
|
||||||
}
|
callstack += std::string("\n ") + symbol->Name;
|
||||||
}
|
}
|
||||||
|
} // for i < max_calls
|
||||||
|
} // get the stack trace
|
||||||
|
|
||||||
FreeLibrary(hDbgHelpDll);
|
FreeLibrary(hDbgHelpDll);
|
||||||
} // // getCallStackWithContext
|
} // // getCallStackWithContext
|
||||||
|
@ -21,6 +21,12 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <new.h>
|
||||||
|
|
||||||
namespace CrashReporting
|
namespace CrashReporting
|
||||||
{
|
{
|
||||||
void installHandlers();
|
void installHandlers();
|
||||||
|
Loading…
Reference in New Issue
Block a user