|
#include "SymbolHandler.h"
#include "SymbolFunctionEntry.h"
SymbolHandler::SymbolHandler()
{
// The second parameter can point to a list of strings separated by comma where
// symbol files should be searched (which means where the PDB should be searched).
// For example "C:\\Symbols;C:\\Development\\Symbols". If its NULL the default
// paths are used which are the current folder, the _NT_SYMBOL_PATH environment
// variable and the _NT_ALTERNATE_SYMBOL_PATH environment variable. (you can use
// getenv to get the values of them).
// The third parameter tells if it should also try to load symbols for all DLLs
// in the current process.
BOOL ret = SymInitialize(GetCurrentProcess(), NULL, TRUE);
// return FALSE here does not actually mean that it failed, it also returns false
// if the symbols are already loaded. So we need to use GetLastError to know what
// actually happened and act accordingly.
if(ret == FALSE)
{
DWORD err = GetLastError();
// If the symbols are already loaded it returns an invalid parameter error
// That of course is a bit bad because it could also mean that we really had
// a bad parameter. Thats why printing out a message is a good idea!
if(err == ERROR_INVALID_PARAMETER)
{
OutputDebugString("Warning: SymInitialize returned ERROR_INVALID_PARAMETER. This could mean that an error happened "\
"or just that symbol are already loaded!\n");
// We are already loaded so lets just update things:
SymRefreshModuleList(GetCurrentProcess());
}
else
throw std::exception("Failed to initialize symbols! See last error for more information.");
}
}
bool SymbolHandler::IsFunctionPresent(const char* name)
{
SYMBOL_INFO sym;
sym.SizeOfStruct = sizeof(sym);
sym.MaxNameLen = 1;
// SymGetSymFromName tries to search a symbol by its name
// In fact this would also catch symbols for global variables for example
// which have the same name.
if(SymFromName(GetCurrentProcess(), name, &sym) == FALSE)
return false;
if(sym.Tag != SymTagFunction)
return false;
return true;
}
PSYMBOL_INFO SymbolHandler::AllocSymbol(int nameLen)
{
void* space = malloc(sizeof(SYMBOL_INFO) + nameLen);
memset(space, 0, sizeof(SYMBOL_INFO) + nameLen);
PSYMBOL_INFO sym = reinterpret_cast<PSYMBOL_INFO>(space);
sym->NameLen = nameLen;
// SizeOfStruct is ment to point at the actual size of the struct and not
// of the whole memory allocated
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
return sym;
}
void SymbolHandler::FreeSymbol(PSYMBOL_INFO symbol)
{
free(symbol);
}
bool SymbolHandler::GetFunction(const char* name, SymbolFunctionEntry& symbol)
{
PSYMBOL_INFO sym = AllocSymbol(MAX_SYM_NAME);
if(SymFromName(GetCurrentProcess(), name, sym) == FALSE)
{
FreeSymbol(sym);
return false;
}
if(sym->Tag != SymTagFunction)
{
FreeSymbol(sym);
return false;
}
symbol.m_symbol = sym;
return true;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.