Is it possible to create mini dump file programmatically without a crash?
Asked Answered
I

1

7

Assume a remote site gets a rare error but doesn't crash the application. I would still like to create a mini dump file when this happens so I have some information to work with, mainly the call stack.

Pseudo code is following:

try
{
    doStuff();
}
catch(_com_error &e)
{
    make_minidump(); // is this possible?

    dump_com_error(e);
    return FALSE;
}

All the examples I see requires that I will have to cause the application to crash (for demo purpose at least) to produce dump file but I don't want to do that. Is it possible to create dump file like this?

I know I can go to task manager and create dump file of a running process and likewise I can use ProcessExplorer to achieve the same, so it seems like it should be possible.

At the same time in all examples I see, dump file is generated only when controls comes to SetUnhandledExceptionFilter which is called when an application crashes!

As a last resort, is the only way to get dump file generated is to deliberately crash the application with something like below: Will that produce anything useful beyond the crash? because I know what caused the crash in this case.

LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e)
{
    make_minidump(e);
    return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
    SetUnhandledExceptionFilter(unhandled_handler);

    return *(int*)0;
}
Imminent answered 3/4, 2017 at 20:43 Comment(2)
msdn.microsoft.com/en-us/library/windows/desktop/…Orsa
Possible duplicate (not flagged as it's dated 2009) #1547711Darter
C
7

Yes, sure. Similar like Windows task manager can create a crash dump of a running / hanging application without any exception, you can use MiniDumpWriteDump() to create a crash dump. Just pass NULL for ExceptionParam.

Here's some code that might help:

typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile,
        MINIDUMP_TYPE DumpType,
        CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
        CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
        CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
                                        );

const wchar_t * DBGHELP = L"DbgHelp.dll";

bool Dump(const std::wstring & dumpFile)
{
    bool success = false;
    DllLoader loader;

    // Load dbghelp.dll. Try first to find it in the application directory.
    loader.Load(::GetModuleHandle(NULL), DBGHELP);
    if (!loader.IsLoaded())
    {
        loader.Load(DBGHELP);
    }

    if (loader.IsLoaded())
    {
        MINIDUMPWRITEDUMP pDump = MINIDUMPWRITEDUMP(loader.GetProcAddress("MiniDumpWriteDump"));

        if (pDump)
        {
            // Create dump file
            HANDLE fileHandle = ::CreateFileW(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS,
                                              FILE_ATTRIBUTE_NORMAL, nullptr);

            if (fileHandle != INVALID_HANDLE_VALUE)
            {
                BOOL bOK = pDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpWithFullMemory, nullptr, nullptr, nullptr);
                if (bOK)
                {
                    success = true;
                }

                ::CloseHandle(fileHandle);
            }
        }
    }

    return success;
}

Due to optimization, I can't see the correct stack in k, but dds ebpshow it:

0029f8d0  01302029 GetCrashWithDLL!MethodB+0x99 [f:\...\getcrashwithdll.cpp @ 12]
[...]
0029f914  0130209c GetCrashWithDLL!wmain+0x3c [f:\...\getcrashwithdll.cpp @ 31]
[...]
0029f920  01302cff GetCrashWithDLL!__tmainCRTStartup+0xfd [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 623]
Colvert answered 3/4, 2017 at 21:11 Comment(8)
I tried this in the mean time and created the dump file but the base EBP pointer is 0x00000 and it doesn't break in my function. I am looking at your code but not sure what DllLoader is? Thanks.Imminent
DllLoader is just a wrapper around ::LoadLibrary(). Nothing special.Colvert
@zar: that code is supposed to create a crash dump from outside a process. You need to be lucky to have your function on the call stack as long as it's not very long-running or hanging.Colvert
Right is is not breaking in the function, so I don't what's the usefulness of this without having proper call stack. I am doing this in a simple demo app and it doesn't even touch my application code.Imminent
@zar: then use my code. As you can see, MethodB is visibleColvert
I did use your code but because I have linked DbgHelp.lib through linker settings so I don't have to typedef the function or load dll specifically, the rest is the same.Imminent
@zar: so, is it fine or not? Perhaps use a debug build for testing purposes so that optimization does not affect your callstacks.Colvert
I did use debug version as wekk and tried using dds with stack frame limit so i can easily dds the whole stack since it's a small demo but i don't see any call to my function or any trace of my executable related file.Imminent

© 2022 - 2024 — McMap. All rights reserved.