0

在我的应用程序中,我Unnamed Pipes用作函数的输出MiniDumpWriteDump- 我不想实际创建文件,只需将 MiniDump 写入内存缓冲区。

从另一个线程调用从管道读取字节的方法。当我调用MiniDumpWriteDump函数时,ReadFileandMiniDumpWriteDump函数永远不会返回。

我试图检查是否是句柄错误或管道尺寸太小的问题,但是当我使用简单的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;
}
4

0 回答 0