Exemplo n.º 1
0
//--------------------------------------------------------------------------
/// End the frame.
//--------------------------------------------------------------------------
void ModernAPILayerManager::EndFrame()
{
    // Check if we need to collect a trace for this currently-rendering frame.
    MultithreadedTraceAnalyzerLayer* pTraceAnalyzer = GetTraceAnalyzerLayer();

    bool bDisableObjectDataBase = false;

    if (mCmdFrameCaptureWithSave.IsActive())
    {
        // Extract the capture mode argument from the
        m_captureType = (CaptureType)mCmdFrameCaptureWithSave.GetCaptureType();
        m_captureCount = mCmdFrameCaptureWithSave.GetCaptureCount();

        // Exclude Frame Capture
        if (m_captureType > 0 && m_captureType < 4)
        {
            // Now need to make sure that the MultithreadedTraceAnalyzerLayer is on the stack.
            if (pTraceAnalyzer != nullptr)
            {
                pTraceAnalyzer->DisableLinkedTraceCollection();
            }

            // stop objectInspector from writing to disk
            bDisableObjectDataBase = true;
        }
    }

    LayerManager::EndFrame();

    // If the TraceAnalyzer layer is active, and a trace was triggered by keypress, disable the tracing layer.
    if (pTraceAnalyzer != nullptr)
    {
        // Check if the previous frame had been traced. If so, we'll need to clean up the TraceAnalyzer from the stack.
        bool bTracedLastFrame = (pTraceAnalyzer->GetLastTracedFrameIndex() == static_cast<int>(GetCurrentFrameIndex()));

        if (bTracedLastFrame && mbTraceTriggeredFromKeypress)
        {
            Log(logMESSAGE, "Keypress capture ending.\n");

            // Enable trace collection for the next rendered frame.
            pTraceAnalyzer->DisableLinkedTraceCollection();

            if (pTraceAnalyzer->IsEnabled())
            {
                // Remove the TraceAnalyzerLayer that we pushed earlier.
                PopEnabledLayer();
            }

#if ENABLE_CLIENT_LOCKOUT_ON_KEYPRESS
            // Tell the GPUPerfServer to accept all incoming commands
            SG_SET_BOOL(ForceRenderStallState, false);
#endif // ENABLE_CLIENT_LOCKOUT_ON_KEYPRESS

            // Disable the keypress flag- we've finished tracing the frame.
            mbTraceTriggeredFromKeypress = false;
        }
    }

    // need to disable ObjectDataBase after because mCmdFrameCaptureWithSave is cleared before object EndFrame
    if (bDisableObjectDataBase)
    {
        // stop objectInspector from writing to disk
        ObjectDatabaseProcessor* objectDatabase = GetObjectDatabaseProcessor();
        objectDatabase->DisableObjectDatabaseCollection();
    }
}
Exemplo n.º 2
0
//--------------------------------------------------------------
//  LaunchAppInNewProcess
//--------------------------------------------------------------
PROCESS_INFORMATION ProcessTracker::LaunchAppInNewProcess(gtASCIIString strApp, gtASCIIString strDir, gtASCIIString strArgs, osModuleArchitecture binaryType)
{
#ifdef _LINUX
    PS_UNREFERENCED_PARAMETER(binaryType);
#endif
    LogConsole(logMESSAGE, "About to launch: %s\n", strApp.asCharArray());
    LogConsole(logMESSAGE, "Params: %s\n", strArgs.asCharArray());
    LogConsole(logMESSAGE, "Working Directory: %s\n", strDir.asCharArray());

    // Get app directory and make it default
    if (strDir.isEmpty())
    {
        size_t pos = strApp.find_last_of("\\");

        if (pos != std::string::npos)
        {
            strDir = strApp.substr(0, (int)pos);

            if (strApp[0] == '\"')
            {
                strDir += "\"";
            }
        }
    }

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));

#ifdef _WIN32
    DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;

    SetLastError(0);

    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
#endif

    // Cmd line has to include the exe name since many apps expect the executable name to be in argv[0]!
    // Note argv[0] on the command line needs to be surrounded with quotes if it contains spaces.
    // The arguments in strArgs have already been "quoted" as they are parsed.

    gtASCIIString strCmdLine = AddQuotesIfStringHasSpaces(strApp.asCharArray());
    strCmdLine += " ";
    strCmdLine += strArgs;

    LogConsole(logMESSAGE, "strApp: %s\n", strApp.asCharArray());
    LogConsole(logMESSAGE, "strCmdLine: %s\n", strCmdLine.asCharArray());

    // Attempt to initialize the environment that the new process will run in. The child process should inherit "this" environment.
    if (!PrelaunchEnvironmentInitialization())
    {
        // Log a warning if this failed- initializing the environment for the new process can fail if Mantle support isn't installed.
        // In these cases, if the user is attempting to debug a Mantle application, they will have bigger problems to deal with.
        // In cases where a DX/GL app is being debugged, this warning can be ignored without any side effects.
        Log(logWARNING, "Environment initialization failed. If using DX/GL, it is safe to ignore this warning.\n");
    }

    BOOL succeeded = FALSE;

#ifdef _WIN32

    char microDLLPath[PS_MAX_PATH];
    const char* strServerPath;
    strServerPath = SG_GET_PATH(ServerPath);

    if (SG_GET_BOOL(OptionDllReplacement) == true)
    {
        DllReplacement::SetDllDirectory(binaryType == OS_X86_64_ARCHITECTURE);
    }

    // if using manual dll replacement or the AppInit_DLLs registry setting, don't use any kind of dll injection
    if (SG_GET_BOOL(OptionManualDllReplacement) == true || SG_GET_BOOL(OptionAppInitDll))
    {
        succeeded = CreateProcess(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(), NULL, NULL, TRUE, dwFlags, NULL, strDir.asCharArray(), &si, &pi);
    }
    else
    {
#ifdef X64

        // can only launch 64 bit applications
        if (binaryType != OS_X86_64_ARCHITECTURE)
        {
            sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX);
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        microDLLPath);
        }

#else

        if (binaryType != OS_I386_ARCHITECTURE)
        {
            sprintf_s(microDLLPath, PS_MAX_PATH, "%s" MICRODLLNAME "-x64%s%s.dll", SG_GET_PATH(ServerPath), GDT_DEBUG_SUFFIX, GDT_BUILD_SUFFIX);
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        microDLLPath);
        }

#endif // X64
        else
        {
            succeeded = AMDT::CreateProcessAndInjectDll(strApp.asCharArray(), (LPSTR)strCmdLine.asCharArray(),
                                                        NULL, NULL, TRUE, dwFlags, NULL,
                                                        strDir.asCharArray(),
                                                        &si, &pi,
                                                        SG_GET_PATH(MicroDLLPath));
        }
    }

#else

    // Create the app process
    succeeded = CreateProcess(strApp.asCharArray(), strCmdLine.asCharArray(), strDir.asCharArray(), &pi);
#endif // _WIN32

    if (!succeeded)
    {
        osSystemErrorCode systemLastError = osGetLastSystemError();

        gtString systemErrorString;
        osGetLastSystemErrorAsString(systemErrorString);

        Log(logERROR, "CreateProcessAndInjectDll failed; Error %d: %s\n", systemLastError, systemErrorString.asASCIICharArray());
        pi.dwProcessId = 0;
    }

#ifdef _WIN32
    else
    {
        // Check to see if the Steam.exe has been hooked and if so, set the value in shared memory
        // If Steam.exe was used to launch the target application, then the checks for cmd.exe and fcx.exe
        // need to be ignored.
        if (strApp.length() > 0)
        {
            if (strstr(strApp.toLowerCase().asCharArray(), "steam.exe") != NULL)
            {
                SG_SET_BOOL(SteamInjected, true);
            }

            ShowLauncherReminder(strApp.toLowerCase().asCharArray());
        }
        else
        {
            if (strstr(strCmdLine.toLowerCase().asCharArray(), "steam.exe") != NULL)
            {
                SG_SET_BOOL(SteamInjected, true);
            }

            ShowLauncherReminder(strCmdLine.toLowerCase().asCharArray());
        }
    }

#endif // _WIN32

    return pi;
}
Exemplo n.º 3
0
//--------------------------------------------------------------------------
/// Begin the frame.
//--------------------------------------------------------------------------
void ModernAPILayerManager::BeginFrame()
{
    GetPendingRequests();

    if (mCmdSetSessionName.IsActive())
    {
        gtASCIIString sessionName = mCmdSetSessionName.GetValue();

        if (SessionManager::Instance()->SetSessionName(sessionName) == false)
        {
            mCmdSetSessionName.Send("Failed");
        }
        else
        {
            mCmdSetSessionName.Send("OK");
        }
    }

    if (mCmdSetProjectName.IsActive())
    {
        gtASCIIString projectName = mCmdSetProjectName.GetValue();

        if (SessionManager::Instance()->SetProjectName(projectName) == false)
        {
            mCmdSetProjectName.Send("Failed");
        }
        else
        {
            mCmdSetProjectName.Send("OK");
        }
    }

    // Check if we need to collect a trace for this currently-rendering frame.
    if (mbTraceTriggeredFromKeypress)
    {
        Log(logMESSAGE, "Keypress capture starting.\n");

        MultithreadedTraceAnalyzerLayer* traceAnalyzer = GetTraceAnalyzerLayer();

        if (traceAnalyzer != nullptr)
        {
            // Examine the layer stack to check for any enabled layers. If there are,
            // we won't be able to collect a trace successfully.
            if (m_EnabledLayers.empty())
            {
#if ENABLE_CLIENT_LOCKOUT_ON_KEYPRESS
                // Tell the GPUPerfServer to reject all incoming requests (it will send the stalled status return to all messages)
                SG_SET_BOOL(ForceRenderStallState, true);
#endif // ENABLE_CLIENT_LOCKOUT_ON_KEYPRESS

                // Since there aren't any layers enabled in the stack, we can proceed with pushing the Logger.
                if (!traceAnalyzer->IsEnabled())
                {
                    // Need to add the TraceAnalyzer layer to the stack.
                    PushLayer(*traceAnalyzer, &m_pushLayer);
                }

                // Enable trace collection for the next rendered frame.
                traceAnalyzer->EnableLinkedTraceCollection();
            }
            else
            {
                // The LayerManager's "enabled layer stack" wasn't empty, meaning the client was in the middle of an operation.
                // Dump a message to the log, and forget that a keypress trace was requested.
                Log(logMESSAGE, "Layer stack is non-empty. Not going to push the Logger for Keypress Capture.\n");
                mbTraceTriggeredFromKeypress = false;
            }
        }
    }

    if (mCmdFrameCaptureWithSave.IsActive())
    {
        // Extract the capture mode argument from the capture mode string
        m_captureType = (CaptureType)mCmdFrameCaptureWithSave.GetCaptureType();
        m_captureCount = mCmdFrameCaptureWithSave.GetCaptureCount();

        if (m_captureCount == 0)
        {
            Log(logERROR, "ModernAPILayerManager::BeginFrame - m_captureCount is 0, forcing it to 1.\n");
            m_captureCount = 1;
        }

        // Exclude Frame Capture
        if (m_captureType > 0 && m_captureType < 4)
        {
            // Now I need to make sure that the MultithreadedTraceAnalyzerLayer is on the stack.
            MultithreadedTraceAnalyzerLayer* traceAnalyzer = GetTraceAnalyzerLayer();
            traceAnalyzer->EnableLinkedTraceCollection();

            // enable objectInspector writing to disk
            ObjectDatabaseProcessor* objectDatabase = GetObjectDatabaseProcessor();
            objectDatabase->EnableObjectDatabaseCollection();
        }
    }

    // Call into the base class to deal with basic layer management.
    LayerManager::BeginFrame();
}