X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=cli%2Fcli_trace.cpp;h=078739ddc57918e969f6500577f4576e6256a2ab;hb=4ce88b87e64c56b2638ee2b6b4785b4ed35aabd6;hp=f87a383b009cd0c13e29754144b63b13ad16cbfb;hpb=d7c738e13decf8a8a891008c51b437ccbe3434fb;p=apitrace diff --git a/cli/cli_trace.cpp b/cli/cli_trace.cpp index f87a383..078739d 100644 --- a/cli/cli_trace.cpp +++ b/cli/cli_trace.cpp @@ -126,14 +126,33 @@ traceProgram(trace::API api, return 1; } - os::String wrapperPath = findWrapper(wrapperFilename); + os::String wrapperPath = findWrapper(wrapperFilename, verbose); if (!wrapperPath.length()) { - std::cerr << "error: failed to find " << wrapperFilename << "\n"; + std::cerr << "error: failed to find " << wrapperFilename << " wrapper\n"; goto exit; } #if defined(_WIN32) - useInject = true; + /* + * Use DLL injection method on Windows, even for APIs that don't stricly + * need it. Except when tracing OpenGL on Windows 8, as the injection + * method seems to have troubles tracing the internal + * gdi32.dll!SwapBuffers -> opengl32.dll!wglSwapBuffer calls, per github + * issue #172. + */ + { + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof osvi); + osvi.dwOSVersionInfoSize = sizeof osvi; + GetVersionEx(&osvi); + BOOL bIsWindows8orLater = + osvi.dwMajorVersion > 6 || + (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 2); + if (api != trace::API_GL || !bIsWindows8orLater) { + useInject = true; + } + } + if (useInject) { args.push_back("inject"); args.push_back(wrapperPath); @@ -154,38 +173,57 @@ traceProgram(trace::API api, wrapperPath.trimFilename(); #endif + /* + * Spawn child process. + */ + + { #if defined(TRACE_VARIABLE) - if (verbose) { - std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n"; - } - /* FIXME: Don't modify the current environment */ - os::setEnvironment(TRACE_VARIABLE, wrapperPath.str()); + const char *oldEnvVarValue = getenv(TRACE_VARIABLE); + if (oldEnvVarValue) { + wrapperPath.append(OS_PATH_SEP); + wrapperPath.append(oldEnvVarValue); + } + + /* FIXME: Don't modify our (ie parent) environment */ + os::setEnvironment(TRACE_VARIABLE, wrapperPath.str()); + + if (verbose) { + std::cerr << TRACE_VARIABLE << "=" << wrapperPath.str() << "\n"; + } #endif /* TRACE_VARIABLE */ - if (output) { - os::setEnvironment("TRACE_FILE", output); - } + if (output) { + os::setEnvironment("TRACE_FILE", output); + } - for (char * const * arg = argv; *arg; ++arg) { - args.push_back(*arg); - } - args.push_back(NULL); + for (char * const * arg = argv; *arg; ++arg) { + args.push_back(*arg); + } - if (verbose) { - const char *sep = ""; - for (unsigned i = 0; i < args.size(); ++i) { - std::cerr << sep << args[i]; - sep = " "; + if (verbose) { + const char *sep = ""; + for (unsigned i = 0; i < args.size(); ++i) { + std::cerr << sep << args[i]; + sep = " "; + } + std::cerr << "\n"; } - std::cerr << "\n"; - } - status = os::execute((char * const *)&args[0]); + args.push_back(NULL); + + status = os::execute((char * const *)&args[0]); -exit: #if defined(TRACE_VARIABLE) - os::unsetEnvironment(TRACE_VARIABLE); + if (oldEnvVarValue) { + os::setEnvironment(TRACE_VARIABLE, oldEnvVarValue); + } else { + os::unsetEnvironment(TRACE_VARIABLE); + } #endif + } + +exit: #if defined(_WIN32) if (!useInject) { os::String tmpWrapper(argv[0]); @@ -285,7 +323,7 @@ command(int argc, char *argv[]) output = optarg; break; default: - std::cerr << "error: unexpected option `" << opt << "`\n"; + std::cerr << "error: unexpected option `" << (char)opt << "`\n"; usage(); return 1; }