0

What I would like to do is use MiniDumpWriteDump() write to a named pipe and then read/write it myself. I am able to perform the dump successfully if I write the contents to a file directly. However, while writing to the named pipe has been successful the subsequent read/write operation does not go so well. I can read all the data out of the pipe but then when it's written the DMP file appears to be corrupted.

Here is the ReadFile() logic:

while (ReadFile(hInboundPipe, &vecBuffer[dwOffset], vecBuffer.size() - dwOffset, &dwRead, NULL)) {
    dwOffset += dwRead;

    while (dwOffset >= vecBuffer.size()) {
        vecBuffer.resize(vecBuffer.size() + iBuffer * sizeof(char));
    }
}

Here is the WriteFile() logic:

HANDLE hDumpFile = CreateFileW(L"C:\\test.dmp", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hDumpFile , &vecBuffer[0], dwOffset, &dwOutBytes, NULL);
CloseHandle(hDumpFile);

I'm not certain if it's applicable to the root cause but here is the named pipe setup:

    HANDLE hInboundPipe = CreateNamedPipe(
    szPipeName,
    PIPE_ACCESS_DUPLEX,
    PIPE_WAIT | PIPE_TYPE_BYTE,
    PIPE_UNLIMITED_INSTANCES,
    0,
    0,
    (DWORD)-1,
    &SecAttrib);

There are not any errors being reported back from GetLastError(). Am I missing something obvious?

EDIT: Adding how the MiniDumpWriteDump() is being done in response to a comment.

HANDLE hDump = CreateFile(szPipeName, GENERIC_ALL, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
MiniDumpWriteDump(hProcess, pid, hDump, mdValue, NULL, NULL, NULL);
CloseHandle(hDump);

UPDATE: I was under the impression that reading by chunks was somehow dropping data. To test this I increased the buffer of the named pipe to accommodate the entire dump without any resizing. I also increased the vecBuffer size to match. Now when performing the ReadFile() operation I receive the entire dump but it is still off. I'm still playing with various named pipe settings trying to figure out what needs to be done to get MiniDumpWriteDump() to provide valid output to a named pipe.

piper123
  • 1
  • 2
  • Are you writing the dump on a separate thread from reading it? Because the pipe might get full and wait for someone to read the data. – user253751 Sep 16 '20 at 18:19
  • @user253751 Yes. I am launching a two different threads. One for the MiniDumpWriteDump() and the other is for the read/write operations. – piper123 Sep 16 '20 at 18:24
  • how is `vecBuffer` declared? `sizeof(char)` is always 1 by definition so is redundant on the resize line, so possibly there is confusion in that buffer's type – HerrJoebob Sep 16 '20 at 19:27
  • `std::vector vecBuffer(iBuffer);`. I added the `sizeof(char)` code in as part of the troubleshooting process and will remove it at your recommendation. In some previous tests I made `vecBuffer` large enough to avoid ever needing to resize it. The issue happens with and without resizing the `vecBuffer`. – piper123 Sep 16 '20 at 19:43
  • How are you verifying that the output is indeed invalid? `MiniDumpWriteDump` is very flexible and can produce dumps that Visual Studio fails to open successfully. If that's what's happening use WinDbg instead. – IInspectable Sep 17 '20 at 02:09
  • [`MiniDumpWriteDump`](https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump) requires a file handle instead of a pipe handle, you will get an undefined behavior. If you compare the successful file with the pipe data you read, you will find that they are quite different. Could you share the reason you want to generate a dumpfile indirectly through a pipeline, instead of directly generating a dumpfile, and then transfer the contents of the dumpfile through the pipeline? – Drake Wu Sep 17 '20 at 06:52
  • IInspectable- that was not something I had considered. I tried opening the dumps as you suggested but they are indeed still corrupt. @DrakeWu-MSFT to the operating system pipes are just files. The output when writing to the named pipe is quite similar. The difference appears to vary per process but for smaller ones it's around 60 bytes. A hex diff of the DMP files show the minor differences but it's hard to say exactly which bytes are missing. I will note that `MiniDumpWriteDump` does appear to chunk out the DMP as it's happening. You must read the data before it will write more data. – piper123 Sep 17 '20 at 12:00
  • @DrakeWu-MSFT I went ahead and added how `MiniDumpWriteDump` is being called as an edit in the original post. – piper123 Sep 17 '20 at 12:31
  • My guess is that it needs a real file handle, because at the end it will write the file header with all the stream offsets, and so it has to seek back to the start of the file. – ssbssa Sep 18 '20 at 16:36

1 Answers1

0

It appears this cannot be done. See the comments for more information. Writing directly to a named pipe from MiniDumpWriteDump() cannot be done because the handle that is passed in must have the ability to seek. Named pipes do not have that functionality, therefore you must use a legitimate file handle.

piper123
  • 1
  • 2