From: José Fonseca Date: Sat, 23 Apr 2011 09:46:21 +0000 (+0100) Subject: Provide an alternative tracing mechanism based on LD_LIBRARY_PATH. X-Git-Tag: 2.0_alpha^2~1014 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9e80096b66c0d6609e8bedb61f55814a6eca21d;p=tools%2Fapitrace.git Provide an alternative tracing mechanism based on LD_LIBRARY_PATH. Still a bit flaky because everybody, even DRI drivers, are trying to dlopen("libGL.so"). --- diff --git a/README b/README index 37ecc4a..f0b8bf2 100644 --- a/README +++ b/README @@ -89,7 +89,7 @@ http://www.cmake.org/Wiki/CmakeMingw for detailed instructions. == Linux == -* Run the application you want to trace as +Run the application you want to trace as LD_PRELOAD=/path/to/glxtrace.so /path/to/application @@ -97,15 +97,32 @@ and it will generate a trace named "application.trace" in the current directory. You can specify the written trace filename by setting the TRACE_FILE envirnment variable before running. -* View the trace with +View the trace with /path/to/tracedump application.trace | less -R -* Replay the trace with +Replay the trace with /path/to/glretrace application.trace +The LD_PRELOAD mechanism should work with most applications. There are some +applications, e.g., Unigine Heaven, which global function pointers with the +same name as GL entrypoints, living in a shared object that wasn't linked with +-Bsymbolic flag, so relocations to those globals function pointers get +overwritten with the address to our wrapper library, and the application will +segfault when trying to write to them. For these applications it is possible +to trace by using glxtrace.so as an ordinary libGL.so and injecting into +LD_LIBRARY_PATH: + + ln -s glxtrace.so libGL.so + ln -s glxtrace.so libGL.so.1 + ln -s glxtrace.so libGL.so.1.2 + export LD_LIBRARY_PATH=/path/to/directory/where/glxtrace/is:$LD_LIBRARY_PATH + export TRACE_LIBGL=/path/to/real/libGL.so.1 + /path/to/application + + == Windows == * Copy opengl32.dll, d3d8.dll, or d3d9.dll from build/wrappers directory to the diff --git a/glxtrace.py b/glxtrace.py index 7a3574b..78d6146 100644 --- a/glxtrace.py +++ b/glxtrace.py @@ -90,6 +90,9 @@ if __name__ == '__main__': print r''' +/* + * Handle to the true libGL.so + */ static void *libgl_handle = NULL; @@ -126,7 +129,9 @@ void * dlopen(const char *filename, int flag) handle = __dlopen(filename, flag); - if (filename && handle) { + const char * libgl_filename = getenv("TRACE_LIBGL"); + + if (filename && handle && !libgl_filename) { if (0) { OS::DebugMessage("warning: dlopen(\"%s\", 0x%x)\n", filename, flag); } @@ -134,6 +139,7 @@ void * dlopen(const char *filename, int flag) // FIXME: handle absolute paths and other versions if (strcmp(filename, "libGL.so") == 0 || strcmp(filename, "libGL.so.1") == 0) { + // Use the true libGL.so handle instead of RTLD_NEXT from now on libgl_handle = handle; @@ -162,19 +168,34 @@ static void * __dlsym(const char *symbol) if (!libgl_handle) { /* - * Try to use whatever libGL.so the library is linked against. + * The app doesn't directly link against libGL.so, nor does it directly + * dlopen it. So we have to load it ourselves. */ - result = dlsym(RTLD_NEXT, symbol); - if (result) { - libgl_handle = RTLD_NEXT; - return result; + + const char * libgl_filename = getenv("TRACE_LIBGL"); + + if (!libgl_filename) { + /* + * Try to use whatever libGL.so the library is linked against. + */ + + result = dlsym(RTLD_NEXT, symbol); + if (result) { + libgl_handle = RTLD_NEXT; + return result; + } + + libgl_filename = "libGL.so.1"; } /* - * The app doesn't directly link against libGL.so, nor does it directly - * dlopen it. So we have to load it ourselves. + * It would have been preferable to use RTLD_LOCAL to ensure that the + * application can never access libGL.so symbols directly, but this + * won't work, given libGL.so often loads a driver specific SO and + * exposes symbols to it. */ - libgl_handle = __dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL); + + libgl_handle = __dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY); if (!libgl_handle) { OS::DebugMessage("error: couldn't find libGL.so\n"); return NULL;