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);
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);
- }
+ 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";
- }
- args.push_back(NULL);
+ args.push_back(NULL);
- status = os::execute((char * const *)&args[0]);
+ 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]);
output = optarg;
break;
default:
- std::cerr << "error: unexpected option `" << opt << "`\n";
+ std::cerr << "error: unexpected option `" << (char)opt << "`\n";
usage();
return 1;
}