MiniDumpWriteDump и запись в канал вызывает тупик

В моем приложении я использую Unnamed Pipes как результат MiniDumpWriteDump функция — я не хочу на самом деле создать файл, просто записать MiniDump в буфер памяти.

Метод для чтения байтов из канала вызывается из другого потока. Когда я звоню MiniDumpWriteDump функция, ReadFile а также MiniDumpWriteDump функция никогда не возвращается.

Я пытался проверить, является ли это проблемой с плохими ручками или слишком маленьким размером труб, но когда я использую простой WriteFile функция, все кажется в порядке (даже если размер канала меньше, чем записанная строка).

Вот часть моего кода:

void CCrashHandler::PipeDump()
{
...
m_ePipeEnd = CreateEvent(
NULL, // default security attribute
TRUE, // manual reset event
TRUE, // initial state = signaled
NULL);   // unnamed event object
m_ePipeStart = CreateEvent(
NULL, // default security attribute
TRUE, // manual reset event
TRUE, // initial state = signaled
NULL);   // unnamed event object

if(m_ePipeEnd == NULL || m_ePipeStart == NULL)
{

return;
}

// Create pipe handles
HANDLE readPipe, writePipe;
if(!CreatePipe(&readPipe, &writePipe, NULL, PIPESIZE))
{

return;
}

// Load dbghelp.dll
hDbgHelp = LoadLibrary(_T("dbghelp.dll"));
if(hDbgHelp==NULL)
{
// Error - couldn't load dbghelp.dll

return;
}

// Write minidump to the file
mei.ThreadId = GetCurrentThreadId();
mei.ExceptionPointers = pExcPtrs;
mei.ClientPointers = FALSE;
mci.CallbackRoutine = NULL;
mci.CallbackParam = NULL;

typedef BOOL (WINAPI *LPMINIDUMPWRITEDUMP)(
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
MINIDUMP_TYPE DumpType,
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
CONST PMINIDUMP_USER_STREAM_INFORMATION UserEncoderParam,
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);

LPMINIDUMPWRITEDUMP pfnMiniDumpWriteDump =
(LPMINIDUMPWRITEDUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if(!pfnMiniDumpWriteDump)
{
// Bad MiniDumpWriteDump function
// Close handles
CloseHandle(readPipe);
CloseHandle(writePipe);

return;
}
HANDLE hProcess   = GetCurrentProcess();
DWORD dwProcessId = GetCurrentProcessId();
DWORD  dwThreadId = 0;

ResetEvent(m_ePipeStart);
ResetEvent(m_ePipeEnd);
// Create thread to read from pipe
HANDLE hThreadRead = CreateThread(
NULL,              // no security attribute
PIPESIZE*2,      // default stack size
PipeThreadRead,     // thread proc
(LPVOID)readPipe,   // thread parameter
0,                // not suspended
&dwThreadId);       // returns thread ID

// Signal start of writing to a pipe
BOOL bRet = SetEvent(m_ePipeStart);
BOOL bWriteDump = pfnMiniDumpWriteDump(
hProcess,
dwProcessId,
writePipe,
m_MiniDumpType,
&mei,
NULL,
&mci);
/*
This one works fine!
wchar_t bufor[100];
int len=wsprintf(bufor,_T("Hello Client From Server (msg #)\n"));

bRet=WriteFile(writePipe,bufor,len*sizeof(wchar_t),&m_wPipeBytes,NULL);
*/

Sleep(100);
// Signal end of writing to a pipe
bRet = SetEvent(m_ePipeEnd);

if(!bWriteDump)
{
// Error writing dump.
// Close handles
CloseHandle(readPipe);
CloseHandle(writePipe);

DWORD nOSError = ::GetLastError();
wchar_t buf[1024];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, nOSError, LANG_USER_DEFAULT, buf, 1024, NULL);

return;
}
//bRet = TerminateThread(hThreadRead, -1);
CloseHandle(writePipe);
CloseHandle(readPipe);
...
}
// Functions, which handles reading from pipe
DWORD WINAPI CCrashHandler::PipeThreadRead(LPVOID szParams)
{
HANDLE hPipe = (HANDLE) szParams;
DWORD sum = 0;
m_pPipeRead = NULL;
while(1)
{
if(WaitForSingleObject(m_ePipeStart, 5000)==WAIT_OBJECT_0)
break;
}
BYTE buf[PIPESIZE];

while(1)
{
memset(buf, 0, PIPESIZE);

DWORD dwRead;

if( ReadFile(hPipe,buf,10,&dwRead,NULL) )
{
if(m_pPipeRead == NULL)
{
m_pPipeRead = (BYTE*) malloc(dwRead);
}else
{
m_pPipeRead = (BYTE*) realloc( m_pPipeRead, dwRead + sum );
}

memcpy(m_pPipeRead+sum, buf, dwRead);

sum+=dwRead;
}
if(WaitForSingleObject(m_ePipeEnd, 0)==WAIT_OBJECT_0)
break;
}
return 1;
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]