]> git.cworth.org Git - apitrace/blob - common/trace_tools_trace.cpp
9a69928d859618ceb678e409d138fd6b29aa1be1
[apitrace] / common / trace_tools_trace.cpp
1 /*********************************************************************
2  *
3  * Copyright 2011 Intel Corporation
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use, copy,
10  * modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *
26  *********************************************************************/
27
28
29 #include <stdlib.h>
30
31 #include <iostream>
32
33 #include "os_path.hpp"
34 #include "trace_tools.hpp"
35
36
37
38 namespace trace {
39
40
41 #if defined(__APPLE__)
42 #define CLI_TRACE_VARIABLE "DYLD_LIBRARY_PATH"
43 #define CLI_TRACE_WRAPPER  "OpenGL"
44 #elif defined(_WIN32)
45 #define CLI_TRACE_VARIABLE ""
46 #define CLI_TRACE_WRAPPER  "opengl32.dll"
47 #else
48 #define CLI_TRACE_VARIABLE "LD_PRELOAD"
49 #define CLI_TRACE_WRAPPER  "glxtrace.so"
50 #endif
51
52
53 os::Path
54 findFile(const char *relPath,
55          const char *absPath,
56          bool verbose)
57 {
58     os::Path complete;
59
60     /* First look in the same directory from which this process is
61      * running, (to support developers running a compiled program that
62      * has not been installed. */
63     os::Path process_dir = os::getProcessName();
64
65     process_dir.trimFilename();
66
67     complete = process_dir;
68     complete.join(relPath);
69
70     if (complete.exists())
71         return complete;
72
73     /* Second, look in the directory for installed wrappers. */
74     complete = absPath;
75     if (complete.exists())
76         return complete;
77
78     if (verbose) {
79         std::cerr << "error: cannot find " << relPath << " or " << absPath << "\n";
80     }
81
82     return "";
83 }
84
85
86 int
87 traceProgram(char * const *argv,
88              const char *output,
89              bool verbose)
90 {
91     os::Path wrapper;
92
93     wrapper = findFile("wrappers/" CLI_TRACE_WRAPPER, APITRACE_WRAPPER_INSTALL_DIR "/" CLI_TRACE_WRAPPER, verbose);
94
95     if (!wrapper.length()) {
96         return 1;
97     }
98
99 #if defined(_WIN32)
100
101     std::cerr <<
102         "The 'apitrace trace' command is not supported for this operating system.\n"
103         "Instead, you will need to copy opengl32.dll, d3d8.dll, or d3d9.dll from\n"
104         APITRACE_WRAPPER_INSTALL_DIR "\n"
105         "to the directory with the application to trace, then run the application.\n";
106
107 #else
108
109 #if defined(__APPLE__)
110     /* On Mac OS X, using DYLD_LIBRARY_PATH, we actually set the
111      * directory, not the file. */
112     wrapper.trimFilename();
113 #endif
114
115     if (verbose) {
116         std::cerr << CLI_TRACE_VARIABLE << "=" << wrapper.str() << "\n";
117     }
118
119     /* FIXME: Don't modify the current environment */
120     setenv(CLI_TRACE_VARIABLE, wrapper.str(), 1);
121
122     if (output) {
123         setenv("TRACE_FILE", output, 1);
124     }
125
126     if (verbose) {
127         const char *sep = "";
128         for (char * const * arg = argv; *arg; ++arg) {
129             std::cerr << *arg << sep;
130             sep = " ";
131         }
132         std::cerr << "\n";
133     }
134
135     execvp(argv[0], argv);
136
137     unsetenv(CLI_TRACE_VARIABLE);
138     if (output) {
139         unsetenv("TRACE_FILE");
140     }
141
142     std::cerr << "error: Failed to execute " << argv[0] << "\n";
143 #endif
144
145     return 1;
146 }
147
148
149 } /* namespace trace */