Ejemplo n.º 1
0
int __cdecl main(int argc, char *argv[])
{
    int err;
  
    /* Initialize the PAL environment */
    err = PAL_Initialize(argc, argv);
    
    if(0 != err)
    {
        return FAIL;
    }
    
    PAL_InitializeDebug();

    PAL_Terminate();
    return 0;
}
Ejemplo n.º 2
0
//
// Init sets up all the objects that the RC thread will need to run.
//
HRESULT DebuggerRCThread::Init(void)
{
    HRESULT hr = S_OK;
    HANDLE rightSideEventAvailable = NULL;
    HANDLE rightSideEventRead = NULL;
    HANDLE leftSideUnmanagedWaitEvent = NULL;
    HANDLE syncThreadIsLockFree = NULL;
    WCHAR tmpName[256];
    NAME_EVENT_BUFFER;
    SECURITY_ATTRIBUTES *pSA = NULL;

		
    if (m_debugger == NULL)
        return E_INVALIDARG;

    // Init should only be called once.
    if (g_pRCThread != NULL) 
        return E_FAIL;

    g_pRCThread = this;

    m_rgDCB = new DebuggerIPCControlBlock *[IPC_TARGET_COUNT];
    if (NULL == m_rgDCB)
    {
        return E_OUTOFMEMORY;
    }
    memset( m_rgDCB, 0, sizeof(DebuggerIPCControlBlock *)*IPC_TARGET_COUNT);


    // Create 2 events for managing favors: unnamed, auto-reset, default=not-signaled
    m_FavorAvailableEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL);
    if (m_FavorAvailableEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }
    
    m_FavorReadEvent = WszCreateEvent(NULL, FALSE, FALSE, NULL);
    if (m_FavorReadEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }

    // Create the thread control event.
    m_threadControlEvent = WszCreateEvent(NULL, FALSE, FALSE, NAME_EVENT(L"ThreadControlEvent"));
    if (m_threadControlEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }

    // Create the helper thread can go event. Manual reset, and
    // initially signaled.
    m_helperThreadCanGoEvent = WszCreateEvent(NULL, TRUE, TRUE, NAME_EVENT(L"HelperThreadCanGoEvent"));
    if (m_helperThreadCanGoEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }

    // We need to setup the shared memory and control block.
	// Get shared memory block from the IPCManager.
	if (g_pIPCManagerInterface == NULL) 
	{
		LOG((LF_CORDB, LL_INFO10000,
         "DRCT::I: g_pIPCManagerInterface == NULL, can't create IPC Block\n"));
		hr = E_FAIL;
		goto exit;
	}

    hr = g_pIPCManagerInterface->GetSecurityAttributes(GetCurrentProcessId(), &pSA);

    if (FAILED(hr))
        goto exit;

    // Create the events that the thread will need to receive events
    // from the out of process piece on the right side.
    // We will not fail out if CreateEvent fails for RSEA or RSER. Because
    // the worst case is that debugger cannot attach to debuggee.
    //
    rightSideEventAvailable = WszCreateEvent(pSA, FALSE, FALSE, NAME_EVENT(L"RightSideEventAvailable"));
    rightSideEventRead = WszCreateEvent(pSA, FALSE, FALSE, NAME_EVENT(L"RightSideEventRead"));

    leftSideUnmanagedWaitEvent = WszCreateEvent(NULL, TRUE, FALSE, NAME_EVENT(L"LeftSideUnmanagedWaitEvent"));

    if (leftSideUnmanagedWaitEvent == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }

    syncThreadIsLockFree = WszCreateEvent(NULL, TRUE, FALSE, NAME_EVENT(L"SyncThreadIsLockFree"));

    if (syncThreadIsLockFree == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto exit;
    }

	m_rgDCB[IPC_TARGET_OUTOFPROC] = g_pIPCManagerInterface->GetDebugBlock();

    // Don't fail out because the SHM failed to create
#if _DEBUG
    if (m_rgDCB[IPC_TARGET_OUTOFPROC] == NULL)
	{
	   LOG((LF_CORDB, LL_INFO10000,
             "DRCT::I: Failed to get Debug IPC block from IPCManager.\n"));
	}
#endif // _DEBUG

    // Copy RSEA and RSER into the control block only if SHM is created without error.
    if (m_rgDCB[IPC_TARGET_OUTOFPROC])
	{
        hr = m_rgDCB[IPC_TARGET_OUTOFPROC]->Init(rightSideEventAvailable,
                                            rightSideEventRead, 
                                            NULL, 
                                            NULL,
                                            leftSideUnmanagedWaitEvent,
                                            syncThreadIsLockFree);
        if (FAILED(hr))
            goto exit;

        // We have to ensure that most of the runtime offsets for the out-of-proc DCB are initialized right away. This is
        // needed to support certian races during an interop attach. Since we can't know whether an interop attach will ever
        // happen or not, we are forced to do this now. Note: this is really too early, as some data structures haven't been
        // initialized yet!
        hr = EnsureRuntimeOffsetsInit(IPC_TARGET_OUTOFPROC);
        if (FAILED(hr))
            goto exit;

        // Note: we have to mark that we need the runtime offsets re-initialized for the out-of-proc DCB. This is because
        // things like the patch table aren't initialized yet. Calling NeedRuntimeOffsetsReInit() ensures that this happens
        // before we really need the patch table.
        NeedRuntimeOffsetsReInit(IPC_TARGET_OUTOFPROC);

        m_rgDCB[IPC_TARGET_OUTOFPROC]->m_helperThreadStartAddr =
            (void *) DebuggerRCThread::ThreadProcStatic;

        m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideProtocolCurrent = CorDB_LeftSideProtocolCurrent;
        m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideProtocolMinSupported = CorDB_LeftSideProtocolMinSupported;
        
        LOG((LF_CORDB, LL_INFO10,
             "DRCT::I: version info: %d.%d.%d current protocol=%d, min protocol=%d\n",
             m_rgDCB[IPC_TARGET_OUTOFPROC]->m_verMajor, 
             m_rgDCB[IPC_TARGET_OUTOFPROC]->m_verMinor, 
             m_rgDCB[IPC_TARGET_OUTOFPROC]->m_checkedBuild,
             m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideProtocolCurrent,
             m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideProtocolMinSupported));
    }

    // Next we'll create the setup sync event for the right side - this
    // solves a race condition of "who gets to the setup code first?"
    // Since there's no guarantee that the thread executing managed
    // code will be executed after us, we've got to do this for
    // the inproc portion of the code, as well.

	hr = CreateSetupSyncEvent();
	if (FAILED(hr))
		goto exit;

    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        // the event already exists.
        LOG((LF_CORDB, LL_INFO10000,
             "DRCT::I: setup sync event already exists.\n"));

        // Need to do some delayed initialization of the debugger services.
        DebuggerController::Initialize();

        // Wait for the Setup Sync event before continuing. 
        DWORD ret = WaitForSingleObject(m_SetupSyncEvent, INFINITE);

        if (ret != WAIT_OBJECT_0)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            goto exit;
        }

        // We no longer need this event now.
        CloseHandle(m_SetupSyncEvent);
        m_SetupSyncEvent = NULL;

		// Open LSEA and LSER (which would have been 
		// created by Right side)

            swprintf(tmpName, CorDBIPCLSEventAvailName, GetCurrentProcessId());

        if (m_rgDCB[IPC_TARGET_OUTOFPROC])
        {
		    m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideEventAvailable = 
		        WszOpenEvent(EVENT_ALL_ACCESS,
						    true,
						    tmpName
						    );
		    
		    if (m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideEventAvailable == NULL)
		    {
			    hr = HRESULT_FROM_WIN32(GetLastError());
			    goto exit;
		    }
        }

            swprintf(tmpName, CorDBIPCLSEventReadName, GetCurrentProcessId());

        if (m_rgDCB[IPC_TARGET_OUTOFPROC])
        {
		    m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideEventRead = 
		            WszOpenEvent(EVENT_ALL_ACCESS,
				                true,
							    tmpName
							    );
		    
		    if (m_rgDCB[IPC_TARGET_OUTOFPROC]->m_leftSideEventRead == NULL)
		    {
			    hr = HRESULT_FROM_WIN32(GetLastError());
			    goto exit;
		    }
        }
        
        LOG((LF_CORDB, LL_INFO10000,"DRCT::I: calling PAL_InitializeDebug.\n"));
        // Tell the PAL that we're trying to debug
        PAL_InitializeDebug();

        // At this point, the control block is complete and all four
        // events are available and valid for this process.
        
        // Since the sync event was created by the Right Side,
        // we'll need to mark the debugger as "attached."
        g_pEEInterface->MarkDebuggerAttached();
        m_debugger->m_debuggerAttached = TRUE;
    }
    else
    {
		LOG((LF_CORDB, LL_INFO10000,
			 "DRCT::I: setup sync event was created.\n"));	

        // At this point, only RSEA and RSER are in the control
        // block. LSEA and LSER will remain invalid until the first
        // receipt of an event from the Right Side.
        
        // Set the Setup Sync event to let the Right Side know that
        // we've finished setting up the control block.
        SetEvent(m_SetupSyncEvent);
    }
    
    // Now do this all again for the inproc stuff
    m_rgDCB[IPC_TARGET_INPROC] = GetInprocControlBlock();
    if (m_rgDCB[IPC_TARGET_INPROC] == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto exit;
    }
    
    m_rgDCB[IPC_TARGET_INPROC]->Init(NULL, 
                                     NULL, 
                                     NULL, 
                                     NULL,
                                     NULL,
                                     NULL);

exit:
    g_pIPCManagerInterface->DestroySecurityAttributes(pSA);
    return hr;
}