Click here to Skip to main content
15,891,926 members
Articles / Web Development / HTML

Catch All Bugs with BugTrap!

Rate me:
Please Sign up or sign in to vote.
4.34/5 (84 votes)
31 Jan 2009MIT5 min read 1.9M   9.1K   293  
A tool that can catch unhandled errors and exceptions, and deliver error reports to remote support servers
/*
 * This is a part of the BugTrap package.
 * Copyright (c) 2005-2007 IntelleSoft.
 * All rights reserved.
 *
 * Description: Pdb file processor.
 * Author: Maksim Pyatkovskiy.
 *
 * This source code is only intended as a supplement to the
 * BugTrap package reference and related electronic documentation
 * provided with the product. See these sources for detailed
 * information regarding the BugTrap package.
 */

#include "StdAfx.h"
#include "PdbProcessor.h"
#include "ComError.h"
#include "WinVersion.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_RUNTIME_CLASS(CPdbProcessor, CBaseProcessor)

/**
 * @param pszSearchPath - search path for loaded modules.
 */
CPdbProcessor::CPdbProcessor(PCTSTR pszSearchPath)
{
	DWORD dwOptions = SymGetOptions();
	SymSetOptions(dwOptions | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
	m_hSymProcess = (HANDLE)1;
	if (! SymInitialize(m_hSymProcess, CT2A(pszSearchPath), FALSE))
	{
		m_hSymProcess = NULL;
		CHECK_WIN32RESULT(GetLastError());
	}
}

CPdbProcessor::~CPdbProcessor()
{
	if (m_hSymProcess != NULL)
		SymCleanup(m_hSymProcess);
}

/**
 * @param pszModuleName - module file name.
 * @param pBaseAddr - module base address.
 * @param dwModuleSize - module size.
 */
void CPdbProcessor::LoadModule(PCTSTR pszModuleName, PVOID pBaseAddr, DWORD dwModuleSize)
{
	_ASSERTE(m_hSymProcess != NULL);
	if (! SymLoadModule64(m_hSymProcess, NULL, CT2A(pszModuleName), NULL, (DWORD64)pBaseAddr, dwModuleSize))
		CHECK_WIN32RESULT(GetLastError());
}

/**
 * @param ptrAddress - function address.
 * @param rFnInfo - reference to function info block.
 * @param dwDisplacement64 - symbol displacement.
 * @return true if function info has been found.
 */
bool CPdbProcessor::FindFunctionInfo(PVOID ptrAddress, CPdbFnInfo& rFnInfo, DWORD64& dwDisplacement64) const
{
	_ASSERTE(m_hSymProcess != NULL);
	BYTE arrSymBuffer[512];
	ZeroMemory(arrSymBuffer, sizeof(arrSymBuffer));
	PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)arrSymBuffer;
	pSymbol->SizeOfStruct = sizeof(*pSymbol);
	pSymbol->MaxNameLen = sizeof(arrSymBuffer) - sizeof(*pSymbol) + 1;
	if (SymFromAddr(m_hSymProcess, (DWORD64)ptrAddress, &dwDisplacement64, pSymbol))
	{
		rFnInfo = CPdbFnInfo((PVOID)pSymbol->Address, std::string(pSymbol->Name));
		return true;
	}
	else
	{
		rFnInfo = CPdbFnInfo();
		dwDisplacement64 = 0;
		return false;
	}
}

/**
 * @param ptrAddress - function address.
 * @param dwDisplacement64 - symbol displacement.
 * @param pFnInfo - pointer to function info block.
 * @return true if function info has been found.
 */
bool CPdbProcessor::FindFunctionInfo(PVOID ptrAddress, boost::shared_ptr<CBaseFnInfo>& pFnInfo, DWORD64& dwDisplacement64) const
{
	_ASSERTE(m_hSymProcess != NULL);
	CPdbFnInfo FnInfo;
	if (FindFunctionInfo(ptrAddress, FnInfo, dwDisplacement64))
	{
		pFnInfo.reset(new CPdbFnInfo(FnInfo));
		return true;
	}
	else
	{
		pFnInfo.reset();
		return false;
	}
}

/**
 * @param ptrAddress - line address.
 * @param rFileInfo - pointer to file information.
 * @param rLineInfo - pointer to line number information.
 * @param dwDisplacement32 - symbol displacement.
 * @return true if line was found.
 */
bool CPdbProcessor::FindLineInfo(PVOID ptrAddress, CPdbFileInfo& rFileInfo, CPdbLineInfo& rLineInfo, DWORD& dwDisplacement32) const
{
	_ASSERTE(m_hSymProcess != NULL);
	IMAGEHLP_LINE64 il;
	ZeroMemory(&il, sizeof(il));
	il.SizeOfStruct = sizeof(il);
	if (SymGetLineFromAddr64(m_hSymProcess, (DWORD64)ptrAddress, &dwDisplacement32, &il))
	{
		rFileInfo = CPdbFileInfo(il.FileName);
		rLineInfo = CPdbLineInfo((PVOID)il.Address, il.LineNumber);
		return true;
	}
	else
	{
		rFileInfo = CPdbFileInfo();
		rLineInfo = CPdbLineInfo();
		dwDisplacement32 = 0;
		return false;
	}
}

/**
 * @param ptrAddress - line address.
 * @param pFileInfo - pointer to file information.
 * @param pLineInfo - pointer to line number information.
 * @param dwDisplacement32 - symbol displacement.
 * @return true if line was found.
 */
bool CPdbProcessor::FindLineInfo(PVOID ptrAddress, boost::shared_ptr<CBaseFileInfo>& pFileInfo, boost::shared_ptr<CBaseLineInfo>& pLineInfo, DWORD& dwDisplacement32) const
{
	_ASSERTE(m_hSymProcess != NULL);
	CPdbFileInfo FileInfo;
	CPdbLineInfo LineInfo;
	if (FindLineInfo(ptrAddress, FileInfo, LineInfo, dwDisplacement32))
	{
		pFileInfo.reset(new CPdbFileInfo(FileInfo));
		pLineInfo.reset(new CPdbLineInfo(LineInfo));
		return true;
	}
	else
	{
		pFileInfo.reset();
		pLineInfo.reset();
		return false;
	}
}

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.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions