diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/CMakeLists.txt | 1 | ||||
-rw-r--r-- | cli/cli_diff.cpp | 4 | ||||
-rw-r--r-- | cli/cli_diff_images.cpp | 4 | ||||
-rw-r--r-- | cli/cli_diff_state.cpp | 4 | ||||
-rw-r--r-- | cli/cli_resources.cpp | 148 | ||||
-rw-r--r-- | cli/cli_resources.hpp | 46 | ||||
-rw-r--r-- | cli/cli_retrace.cpp | 4 | ||||
-rw-r--r-- | cli/cli_trace.cpp | 172 | ||||
-rw-r--r-- | cli/trace_tools.hpp | 48 | ||||
-rw-r--r-- | cli/trace_tools_trace.cpp | 208 |
10 files changed, 629 insertions, 10 deletions
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index ed998810..521886b7 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable (apitrace cli_retrace.cpp cli_trace.cpp cli_trim.cpp + cli_resources.cpp ) target_link_libraries (apitrace diff --git a/cli/cli_diff.cpp b/cli/cli_diff.cpp index ffc0e303..76cdce1d 100644 --- a/cli/cli_diff.cpp +++ b/cli/cli_diff.cpp @@ -31,14 +31,14 @@ #include "cli.hpp" #include "os_string.hpp" #include "os_process.hpp" -#include "trace_resource.hpp" +#include "cli_resources.hpp" static const char *synopsis = "Identify differences between two traces."; static os::String find_command(void) { - return trace::findScript("tracediff.py"); + return findScript("tracediff.py"); } static void diff --git a/cli/cli_diff_images.cpp b/cli/cli_diff_images.cpp index 3932fa24..ba8df3e9 100644 --- a/cli/cli_diff_images.cpp +++ b/cli/cli_diff_images.cpp @@ -31,14 +31,14 @@ #include "cli.hpp" #include "os_string.hpp" #include "os_process.hpp" -#include "trace_resource.hpp" +#include "cli_resources.hpp" static const char *synopsis = "Identify differences between two image dumps."; static os::String find_command(void) { - return trace::findScript("snapdiff.py"); + return findScript("snapdiff.py"); } static void diff --git a/cli/cli_diff_state.cpp b/cli/cli_diff_state.cpp index 7f754842..341d244f 100644 --- a/cli/cli_diff_state.cpp +++ b/cli/cli_diff_state.cpp @@ -33,7 +33,7 @@ #include "cli.hpp" #include "os_string.hpp" #include "os_process.hpp" -#include "trace_resource.hpp" +#include "cli_resources.hpp" static const char *synopsis = "Identify differences between two state dumps."; @@ -83,7 +83,7 @@ command(int argc, char *argv[]) file1 = argv[optind]; file2 = argv[optind + 1]; - os::String command = trace::findScript("jsondiff.py"); + os::String command = findScript("jsondiff.py"); char *args[5]; diff --git a/cli/cli_resources.cpp b/cli/cli_resources.cpp new file mode 100644 index 00000000..255a98b6 --- /dev/null +++ b/cli/cli_resources.cpp @@ -0,0 +1,148 @@ +/********************************************************************* + * + * Copyright 2011 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *********************************************************************/ + + +#include <iostream> + +#include "os_string.hpp" + +#include "cli_resources.hpp" + + +os::String +findProgram(const char*programFilename) +{ + os::String programPath; + + os::String processDir = os::getProcessName(); + processDir.trimFilename(); + + programPath = processDir; + programPath.join(programFilename); + if (programPath.exists()) { + return programPath; + } + +#ifndef _WIN32 + // Try absolute install directory + programPath = APITRACE_PROGRAMS_INSTALL_DIR; + programPath.join(programFilename); + if (programPath.exists()) { + return programPath; + } +#endif + + return ""; +} + +os::String +findWrapper(const char *wrapperFilename) +{ + os::String wrapperPath; + + os::String processDir = os::getProcessName(); + processDir.trimFilename(); + + // Try relative build directory + // XXX: Just make build and install directory layout match + wrapperPath = processDir; + wrapperPath.join("wrappers"); + wrapperPath.join(wrapperFilename); + if (wrapperPath.exists()) { + return wrapperPath; + } + + // Try relative install directory + wrapperPath = processDir; +#if defined(_WIN32) + wrapperPath.join("..\\lib\\wrappers"); +#elif defined(__APPLE__) + wrapperPath.join("../lib/wrappers"); +#else + wrapperPath.join("../lib/apitrace/wrappers"); +#endif + wrapperPath.join(wrapperFilename); + if (wrapperPath.exists()) { + return wrapperPath; + } + +#ifndef _WIN32 + // Try absolute install directory + wrapperPath = APITRACE_WRAPPERS_INSTALL_DIR; + wrapperPath.join(wrapperFilename); + if (wrapperPath.exists()) { + return wrapperPath; + } +#endif + + return ""; +} + +os::String +findScript(const char *scriptFilename) +{ + os::String scriptPath; + + os::String processDir = os::getProcessName(); + processDir.trimFilename(); + + // Try relative build directory + // XXX: Just make build and install directory layout match + scriptPath = processDir; + scriptPath.join("scripts"); + scriptPath.join(scriptFilename); + if (scriptPath.exists()) { + return scriptPath; + } + + // Try relative install directory + scriptPath = processDir; +#if defined(_WIN32) + scriptPath.join("..\\lib\\scripts"); +#elif defined(__APPLE__) + scriptPath.join("../lib/scripts"); +#else + scriptPath.join("../lib/apitrace/scripts"); +#endif + scriptPath.join(scriptFilename); + if (scriptPath.exists()) { + return scriptPath; + } + +#ifndef _WIN32 + // Try absolute install directory + scriptPath = APITRACE_SCRIPTS_INSTALL_DIR; + scriptPath.join(scriptFilename); + if (scriptPath.exists()) { + return scriptPath; + } +#endif + + std::cerr << "error: cannot find " << scriptFilename << " script\n"; + + return ""; +} diff --git a/cli/cli_resources.hpp b/cli/cli_resources.hpp new file mode 100644 index 00000000..dde86dd5 --- /dev/null +++ b/cli/cli_resources.hpp @@ -0,0 +1,46 @@ +/************************************************************************** + * + * Copyright 2011 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _CLI_RESOURCES_HPP_ +#define _CLI_RESOURCES_HPP_ + + +#include <stdlib.h> + +#include "os_string.hpp" +#include "trace_api.hpp" + + +os::String +findProgram(const char*programFilename); + +os::String +findScript(const char *name); + +os::String +findWrapper(const char *wrapperFilename); + + +#endif /* _CLI_RESOURCES_HPP_ */ diff --git a/cli/cli_retrace.cpp b/cli/cli_retrace.cpp index a2dbd099..062f51bd 100644 --- a/cli/cli_retrace.cpp +++ b/cli/cli_retrace.cpp @@ -35,7 +35,7 @@ #include "os_process.hpp" #include "trace_parser.hpp" -#include "trace_resource.hpp" +#include "cli_resources.hpp" #include "cli.hpp" #include "cli_retrace.hpp" @@ -89,7 +89,7 @@ executeRetrace(const std::vector<const char *> & opts, } std::vector<const char *> command; - os::String retracePath = trace::findProgram(retraceName); + os::String retracePath = findProgram(retraceName); if (retracePath.length()) { command.push_back(retracePath); } else { diff --git a/cli/cli_trace.cpp b/cli/cli_trace.cpp index 80775090..1d19ed5c 100644 --- a/cli/cli_trace.cpp +++ b/cli/cli_trace.cpp @@ -28,13 +28,181 @@ #include <assert.h> #include <string.h> +#include <stdlib.h> #include <getopt.h> #include <iostream> +#include "os_string.hpp" +#include "os_process.hpp" + #include "cli.hpp" +#include "cli_resources.hpp" + + +#if defined(__APPLE__) +#define TRACE_VARIABLE "DYLD_LIBRARY_PATH" +#define GL_TRACE_WRAPPER "OpenGL" +#elif defined(_WIN32) +#define GL_TRACE_WRAPPER "opengl32.dll" +#else +#define TRACE_VARIABLE "LD_PRELOAD" +#define GL_TRACE_WRAPPER "glxtrace.so" +#define EGL_TRACE_WRAPPER "egltrace.so" +#endif + + +static inline bool +copyWrapper(const os::String & wrapperPath, + const char *programPath, + bool verbose) +{ + os::String wrapperFilename(wrapperPath); + wrapperFilename.trimDirectory(); + + os::String tmpWrapper(programPath); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + + if (verbose) { + std::cerr << wrapperPath << " -> " << tmpWrapper << "\n"; + } + + if (tmpWrapper.exists()) { + std::cerr << "error: not overwriting " << tmpWrapper << "\n"; + return false; + } + + if (!os::copyFile(wrapperPath, tmpWrapper, false)) { + std::cerr << "error: failed to copy " << wrapperPath << " into " << tmpWrapper << "\n"; + return false; + } + + return true; +} + + +static int +traceProgram(trace::API api, + char * const *argv, + const char *output, + bool verbose) +{ + const char *wrapperFilename; + std::vector<const char *> args; + int status = 1; + + /* + * TODO: simplify code + */ + + bool useInject = false; + switch (api) { + case trace::API_GL: + wrapperFilename = GL_TRACE_WRAPPER; + break; +#ifdef EGL_TRACE_WRAPPER + case trace::API_EGL: + wrapperFilename = EGL_TRACE_WRAPPER; + break; +#endif +#ifdef _WIN32 + case trace::API_D3D7: + wrapperFilename = "ddraw.dll"; + break; + case trace::API_D3D8: + wrapperFilename = "d3d8.dll"; + break; + case trace::API_D3D9: + wrapperFilename = "d3d9.dll"; + break; + case trace::API_D3D10: + case trace::API_D3D10_1: + case trace::API_D3D11: + wrapperFilename = "dxgitrace.dll"; + useInject = true; + break; +#endif + default: + std::cerr << "error: unsupported API\n"; + return 1; + } + + os::String wrapperPath = findWrapper(wrapperFilename); + if (!wrapperPath.length()) { + std::cerr << "error: failed to find " << wrapperFilename << "\n"; + goto exit; + } + +#if defined(_WIN32) + if (useInject) { + args.push_back("inject"); + args.push_back(wrapperPath); + } else { + /* On Windows copy the wrapper to the program directory. + */ + if (!copyWrapper(wrapperPath, argv[0], verbose)) { + goto exit; + } + } +#else /* !_WIN32 */ + (void)useInject; +#endif /* !_WIN32 */ + +#if defined(__APPLE__) + /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the + * directory, not the file. */ + wrapperPath.trimFilename(); +#endif + +#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()); +#endif /* TRACE_VARIABLE */ + + if (output) { + os::setEnvironment("TRACE_FILE", output); + } -#include "trace_tools.hpp" + for (char * const * arg = argv; *arg; ++arg) { + args.push_back(*arg); + } + args.push_back(NULL); + + if (verbose) { + const char *sep = ""; + for (unsigned i = 0; i < args.size(); ++i) { + std::cerr << sep << args[i]; + sep = " "; + } + std::cerr << "\n"; + } + + status = os::execute((char * const *)&args[0]); + +exit: +#if defined(TRACE_VARIABLE) + os::unsetEnvironment(TRACE_VARIABLE); +#endif +#if defined(_WIN32) + if (!useInject) { + os::String tmpWrapper(argv[0]); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + os::removeFile(tmpWrapper); + } +#endif + + if (output) { + os::unsetEnvironment("TRACE_FILE"); + } + + return status; + +} static const char *synopsis = "Generate a new trace by executing the given program."; @@ -131,7 +299,7 @@ command(int argc, char *argv[]) } assert(argv[argc] == 0); - return trace::traceProgram(api, argv + optind, output, verbose); + return traceProgram(api, argv + optind, output, verbose); } const Command trace_command = { diff --git a/cli/trace_tools.hpp b/cli/trace_tools.hpp new file mode 100644 index 00000000..ddfe888c --- /dev/null +++ b/cli/trace_tools.hpp @@ -0,0 +1,48 @@ +/************************************************************************** + * + * Copyright 2011 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _TRACE_TOOLS_HPP_ +#define _TRACE_TOOLS_HPP_ + + +#include <stdlib.h> + +#include "trace_api.hpp" + + +namespace trace { + + +int +traceProgram(API api, + char * const *argv, + const char *output = NULL, + bool verbose = false); + + + +} /* namespace trace */ + +#endif /* _TRACE_TOOLS_HPP_ */ diff --git a/cli/trace_tools_trace.cpp b/cli/trace_tools_trace.cpp new file mode 100644 index 00000000..fa899f9e --- /dev/null +++ b/cli/trace_tools_trace.cpp @@ -0,0 +1,208 @@ +/********************************************************************* + * + * Copyright 2011 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + *********************************************************************/ + + +#include <stdlib.h> + +#include <iostream> + +#include "os_string.hpp" +#include "os_process.hpp" +#include "trace_tools.hpp" +#include "cli_resources.hpp" + + + +namespace trace { + + +#if defined(__APPLE__) +#define TRACE_VARIABLE "DYLD_LIBRARY_PATH" +#define GL_TRACE_WRAPPER "OpenGL" +#elif defined(_WIN32) +#define GL_TRACE_WRAPPER "opengl32.dll" +#else +#define TRACE_VARIABLE "LD_PRELOAD" +#define GL_TRACE_WRAPPER "glxtrace.so" +#define EGL_TRACE_WRAPPER "egltrace.so" +#endif + + +static inline bool +copyWrapper(const os::String & wrapperPath, + const char *programPath, + bool verbose) +{ + os::String wrapperFilename(wrapperPath); + wrapperFilename.trimDirectory(); + + os::String tmpWrapper(programPath); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + + if (verbose) { + std::cerr << wrapperPath << " -> " << tmpWrapper << "\n"; + } + + if (tmpWrapper.exists()) { + std::cerr << "error: not overwriting " << tmpWrapper << "\n"; + return false; + } + + if (!os::copyFile(wrapperPath, tmpWrapper, false)) { + std::cerr << "error: failed to copy " << wrapperPath << " into " << tmpWrapper << "\n"; + return false; + } + + return true; +} + + +int +traceProgram(API api, + char * const *argv, + const char *output, + bool verbose) +{ + const char *wrapperFilename; + std::vector<const char *> args; + int status = 1; + + /* + * TODO: simplify code + */ + + bool useInject = false; + switch (api) { + case API_GL: + wrapperFilename = GL_TRACE_WRAPPER; + break; +#ifdef EGL_TRACE_WRAPPER + case API_EGL: + wrapperFilename = EGL_TRACE_WRAPPER; + break; +#endif +#ifdef _WIN32 + case API_D3D7: + wrapperFilename = "ddraw.dll"; + break; + case API_D3D8: + wrapperFilename = "d3d8.dll"; + break; + case API_D3D9: + wrapperFilename = "d3d9.dll"; + break; + case API_D3D10: + case API_D3D10_1: + case API_D3D11: + wrapperFilename = "dxgitrace.dll"; + useInject = true; + break; +#endif + default: + std::cerr << "error: unsupported API\n"; + return 1; + } + + os::String wrapperPath = findWrapper(wrapperFilename); + if (!wrapperPath.length()) { + std::cerr << "error: failed to find " << wrapperFilename << "\n"; + goto exit; + } + +#if defined(_WIN32) + if (useInject) { + args.push_back("inject"); + args.push_back(wrapperPath); + } else { + /* On Windows copy the wrapper to the program directory. + */ + if (!copyWrapper(wrapperPath, argv[0], verbose)) { + goto exit; + } + } +#else /* !_WIN32 */ + (void)useInject; +#endif /* !_WIN32 */ + +#if defined(__APPLE__) + /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the + * directory, not the file. */ + wrapperPath.trimFilename(); +#endif + +#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()); +#endif /* TRACE_VARIABLE */ + + if (output) { + os::setEnvironment("TRACE_FILE", output); + } + + for (char * const * arg = argv; *arg; ++arg) { + args.push_back(*arg); + } + args.push_back(NULL); + + if (verbose) { + const char *sep = ""; + for (unsigned i = 0; i < args.size(); ++i) { + std::cerr << sep << args[i]; + sep = " "; + } + std::cerr << "\n"; + } + + status = os::execute((char * const *)&args[0]); + +exit: +#if defined(TRACE_VARIABLE) + os::unsetEnvironment(TRACE_VARIABLE); +#endif +#if defined(_WIN32) + if (!useInject) { + os::String tmpWrapper(argv[0]); + tmpWrapper.trimFilename(); + tmpWrapper.join(wrapperFilename); + os::removeFile(tmpWrapper); + } +#endif + + if (output) { + os::unsetEnvironment("TRACE_FILE"); + } + + return status; + +} + + +} /* namespace trace */ |