Пример #1
0
//-----------------------------------------------------------------------------
// Name: setMiniDumpFileName()
// Desc: 
//-----------------------------------------------------------------------------
void KG3DCritDumper::setMiniDumpFileName( void )
{
    time_t currentTime;
    time( &currentTime );

    _tcssprintf( m_szMiniDumpPath,
                 _T( "%s%s.%ld.dmp" ),
                 m_szAppPath,
                 m_szAppBaseName,
                 currentTime );
}
Пример #2
0
//
// MiniDumper::WriteMiniDump	- Chapter 21, page 814
//
LONG MiniDumper::WriteMiniDump(_EXCEPTION_POINTERS *pExceptionInfo )
{
    time( &m_lTime );

	LONG retval = EXCEPTION_CONTINUE_SEARCH;
	m_pExceptionInfo = pExceptionInfo;

	// You have to find the right dbghelp.dll. 
	// Look next to the EXE first since the one in System32 might be old (Win2k)
	
	HMODULE hDll = NULL;
	TCHAR szDbgHelpPath[_MAX_PATH];

	if (GetModuleFileName( NULL, m_szAppPath, _MAX_PATH ))
	{
		TCHAR *pSlash = _tcsrchr( m_szAppPath, '\\' );
		if (pSlash)
		{
#ifdef _VS2005_
			_tcscpy_s( m_szAppBaseName, pSlash + 1);
#else
			_tcscpy( m_szAppBaseName, pSlash + 1 );
#endif
			*(pSlash+1) = 0;
		}

#ifdef _VS2005_
		_tcscpy_s( szDbgHelpPath, m_szAppPath );
        _tcscat_s( szDbgHelpPath, _T("DBGHELP.DLL") );
#else
		_tcscpy( szDbgHelpPath, m_szAppPath );
        _tcscat( szDbgHelpPath, _T("DBGHELP.DLL") );
#endif
		hDll = ::LoadLibrary( szDbgHelpPath );
	}

	if (hDll==NULL)
	{
		// If we haven't found it yet - try one more time.
		hDll = ::LoadLibrary( _T("DBGHELP.DLL") );
	}

	LPCTSTR szResult = NULL;

	if (hDll)
	{
		MINIDUMPWRITEDUMP pMiniDumpWriteDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );
		if (pMiniDumpWriteDump)
		{
			TCHAR szScratch [USER_DATA_BUFFER_SIZE];

			VSetDumpFileName();

			// ask the user if they want to save a dump file
			_tcssprintf(szScratch, _T("There was an unexpected error:\n\n%s\nWould you like to save a diagnostic file?\n\nFilename: %s"), VGetUserMessage(), m_szDumpPath);
			if (m_bHeadless || (::MessageBox( NULL, szScratch, NULL, MB_YESNO )==IDYES))
			{
				// create the file
				HANDLE hFile = ::CreateFile( m_szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
											FILE_ATTRIBUTE_NORMAL, NULL );

				if (hFile!=INVALID_HANDLE_VALUE)
				{
					_MINIDUMP_EXCEPTION_INFORMATION ExInfo;

					ExInfo.ThreadId = ::GetCurrentThreadId();
					ExInfo.ExceptionPointers = pExceptionInfo;
					ExInfo.ClientPointers = NULL;

					// write the dump
					BOOL bOK = pMiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, VGetUserStreamArray(), NULL );
					if (bOK)
					{
						szResult = NULL;
						retval = EXCEPTION_EXECUTE_HANDLER;
					}
					else
					{
						_tcssprintf( szScratch, _T("Failed to save dump file to '%s' (error %d)"), m_szDumpPath, GetLastError() );
						szResult = szScratch;
					}
					::CloseHandle(hFile);
				}
				else
				{
					_tcssprintf( szScratch, _T("Failed to create dump file '%s' (error %d)"), m_szDumpPath, GetLastError() );
					szResult = szScratch;
				}
			}
		}
		else
		{
			szResult = _T("DBGHELP.DLL too old");
		}
	}
	else
	{
		szResult = _T("DBGHELP.DLL not found");
	}

	if (szResult && !m_bHeadless)
		::MessageBox( NULL, szResult, NULL, MB_OK );

	TerminateProcess(GetCurrentProcess(), 0);
	
	// MLM Note: ExitThread will work, and it allows the MiniDumper to kill a crashed thread
	// without affecting the rest of the application. The question of the day:
	//   Is That A Good Idea??? Answer: ABSOLUTELY NOT!!!!!!!
	//
	//ExitThread(0);

	return retval;
}
Пример #3
0
//-----------------------------------------------------------------------------
// Name: writeMiniDump()
// Desc: 
//-----------------------------------------------------------------------------
LONG KG3DCritDumper::writeMiniDump( _EXCEPTION_POINTERS *pExceptionInfo )
{
	LONG retval = EXCEPTION_CONTINUE_SEARCH;
	m_pExceptionInfo = pExceptionInfo;

    HANDLE hImpersonationToken = NULL;
    if( !getImpersonationToken( &hImpersonationToken ) )
        return FALSE;

	// You have to find the right dbghelp.dll. 
	// Look next to the EXE first since the one in System32 might be old (Win2k)
	
	HMODULE hDll = NULL;
	TCHAR szDbgHelpPath[MAX_PATH];

	if( GetModuleFileName( NULL, m_szAppPath, _MAX_PATH ) )
	{
		TCHAR *pSlash = _tcsrchr( m_szAppPath, '\\' );

		if( pSlash )
		{
			_tcscpy( m_szAppBaseName, pSlash + 1);
			*(pSlash+1) = 0;
		}

		_tcscpy( szDbgHelpPath, m_szAppPath );
        _tcscat( szDbgHelpPath, _T("DBGHELP.DLL") );
		hDll = ::LoadLibrary( szDbgHelpPath );
	}

	if( hDll == NULL )
	{
		// If we haven't found it yet - try one more time.
		hDll = ::LoadLibrary( _T("DBGHELP.DLL") );
	}

	LPCTSTR szResult = NULL;

	if( hDll )
	{
        // Get the address of the MiniDumpWriteDump function, which writes 
        // user-mode mini-dump information to a specified file.
		MINIDUMPWRITEDUMP MiniDumpWriteDump = 
            (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );

		if( MiniDumpWriteDump != NULL )
        {
			TCHAR szScratch[USER_DATA_BUFFER_SIZE];

			setMiniDumpFileName();

			// Ask the user if he or she wants to save a mini-dump file...
			_tcssprintf( szScratch,
                         _T("There was an unexpected error:\n\nWould you "
                         "like to create a mini-dump file?\n\n%s " ),
                         m_szMiniDumpPath);

			if( !m_bPromptUserForMiniDump )//|| (::MessageBox( NULL, szScratch, NULL, MB_YESNO )==IDYES) )
			{
				// Create the mini-dump file...
				HANDLE hFile = ::CreateFile( m_szMiniDumpPath, 
                                             GENERIC_WRITE, 
                                             FILE_SHARE_WRITE, 
                                             NULL, 
                                             CREATE_ALWAYS, 
                                             FILE_ATTRIBUTE_NORMAL, 
                                             NULL );

				if( hFile != INVALID_HANDLE_VALUE )
				{
					_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
					ExInfo.ThreadId          = ::GetCurrentThreadId();
					ExInfo.ExceptionPointers = pExceptionInfo;
					ExInfo.ClientPointers    = NULL;

                    // We need the SeDebugPrivilege to be able to run MiniDumpWriteDump
                    TOKEN_PRIVILEGES tp;
                    BOOL bPrivilegeEnabled = enablePrivilege( SE_DEBUG_NAME, hImpersonationToken, &tp );

                    BOOL bOk;

                    // DBGHELP.dll is not thread-safe, so we need to restrict access...
                    EnterCriticalSection( s_pCriticalSection );
                    {
					    // Write out the mini-dump data to the file...
                        bOk = MiniDumpWriteDump( GetCurrentProcess(),
                                                 GetCurrentProcessId(),
                                                 hFile,
                                                 MiniDumpNormal,
                                                 &ExInfo,
                                                 NULL,
                                                 NULL );
                    }
                    LeaveCriticalSection( s_pCriticalSection );

                    // Restore the privileges when done
                    if( bPrivilegeEnabled )
	                    restorePrivilege( hImpersonationToken, &tp );

                    if( bOk )
					{
						szResult = NULL;
						retval = EXCEPTION_EXECUTE_HANDLER;
					}
					else
					{
						_tcssprintf( szScratch,
                                     _T("Failed to save the mini-dump file to '%s' (error %d)"),
                                     m_szMiniDumpPath,
                                     GetLastError() );

						szResult = szScratch;
					}

					::CloseHandle( hFile );
				}
				else
				{
					_tcssprintf( szScratch,
                                 _T("Failed to create the mini-dump file '%s' (error %d)"),
                                 m_szMiniDumpPath,
                                 GetLastError() );

					szResult = szScratch;
				}
			}
		}
		else
		{
			szResult = _T( "Call to GetProcAddress failed to find MiniDumpWriteDump. "
                           "The DBGHELP.DLL is possibly outdated." );
		}
	}
	else
	{
		szResult = _T( "Call to LoadLibrary failed to find DBGHELP.DLL." );
	}

//	if( szResult && m_bPromptUserForMiniDump )
//		::MessageBox( NULL, szResult, NULL, MB_OK );

	TerminateProcess( GetCurrentProcess(), 0 );

	return retval;
}
Пример #4
0
//
// MiniDumper::VSetDumpFileName				- Chapter 21, page 817
//
void MiniDumper::VSetDumpFileName(void)
{
	_tcssprintf(m_szDumpPath, _T("%s%s.%ld.dmp"), m_szAppPath, m_szAppBaseName, m_lTime);
}