Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a dump of a process that crashes on startup

On a customer machine (WinXP SP2) to which I have no access, I have a Win32 EXE (unmanaged C++) that crashes on startup. I guess the best way to troubleshoot this is to obtain a (mini-)dump and analyze it later with windbg or similar.

Now, I would normally tell the customer to install Debugging Tools for Windows and run

cscript adplus.vbs -crash

However, it appears that you can't use adplus for apps that crash on startup (http://support.microsoft.com/kb/q286350/ says that "Do not use ADPlus in the following situations: If you must troubleshoot a program or process that quits unexpectedly during startup"). The same article says "use User Mode Process Dump", but I failed to install it successfully.

Any idea of how to get a dump of a process that crashes on startup on Win32?

like image 799
Guido Domenici Avatar asked Nov 29 '22 07:11

Guido Domenici


1 Answers

Alternatively you may set up your own dump generation framework which automatically creates a process dump when any Unhandled exception is encountered. This would avoid clients having to install Windbg.

Use SetUnhandledExceptionFilter Win32 API to register the application level exception handler at the application start up. The registered callback function is called whenever there is any exception which is not handled. U may then create the process dump using MiniDumpWriteDump api from DbgHelp.dll.

Sample Code:-

LONG WINAPI My_UnhandledExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
    HANDLE hFile = CreateFile("FileName",
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

    MINIDUMP_EXCEPTION_INFORMATION aMiniDumpInfo;
    aMiniDumpInfo.ThreadId = GetCurrentThreadId();
    aMiniDumpInfo.ExceptionPointers = ExceptionInfo;
    aMiniDumpInfo.ClientPointers = TRUE;

    MiniDumpWriteDump(GetCurrentProcess(),
            GetCurrentProcessId(),
            hFile,
            (MINIDUMP_TYPE) (MiniDumpWithFullMemory|MiniDumpWithHandleData),
            &aMiniDumpInfo,
            NULL,
            NULL);

    CloseHandle(hFile);

    return EXCEPTION_EXECUTE_HANDLER;
}


int main(int argc, char* argv[])
{
    SetUnhandledExceptionFilter(&My_UnhandledExceptionFilter);

    // User code throwing exception..

    return 0; 
}

NB:- The registered exception filter is not called when the process is being debugged. So during debugging if you put breakpoint in the exception filter function dont be surprised if it does not hit even after causing an Unhandled Exception.

like image 194
Canopus Avatar answered Dec 10 '22 15:12

Canopus