apitrace icon indicating copy to clipboard operation
apitrace copied to clipboard

HACK do not merge: this makes tracing GTK apps with EGL backend possible

Open okias opened this issue 1 year ago • 3 comments

Due to GTK or Epoxy checking for the symbol glXGetCurrentContext (which they won't use later), apitrace fails:

$ apitrace trace -a egl gtk4-demo
apitrace: loaded into /usr/bin/apitrace
apitrace: unloaded from /usr/bin/apitrace
apitrace: loaded into /usr/bin/gtk4-demo
** Message: 02:06:00.252: For syntax highlighting, install the “highlight” program
apitrace: redirecting dlopen("libEGL.so.1", 0x1) from /lib/x86_64-linux-gnu/libepoxy.so.0
apitrace: tracing to /home/projects/collabora/mesa/gtk4-demo.trace
apitrace: warning: eglChooseConfig: unknown key 0x3339, interpreting value as int
apitrace: warning: eglChooseConfig: unknown key 0x3339, interpreting value as int
apitrace: redirecting dlopen("libGL.so.1", 0x1) from /lib/x86_64-linux-gnu/libepoxy.so.0
apitrace: attempting to read configuration file: /home/okias/.config/apitrace/gltrace.conf
apitrace: using configuration file: /home/okias/.config/apitrace/gltrace.conf
apitrace: config GL_VENDOR = 
apitrace: config GL_VERSION = 4.5
apitrace: config GL_EXTENSIONS = 
apitrace: config GL_NUM_EXTENSIONS = 0
apitrace: config GL_RENDERER = 
apitrace: config GL_SHADING_LANGUAGE_VERSION = 4.50
apitrace: config GL_MAX_TEXTURE_SIZE = 0
apitrace: config GL_MAJOR_VERSION = 4
apitrace: config GL_MINOR_VERSION = 5
apitrace: config GL_CONTEXT_PROFILE_MASK = 0x0
apitrace: config GL_CONTEXT_PROFILE_MASK = 0x0
apitrace: config GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 32
apitrace: config GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 16
apitrace: config GL_STORAGE_BUFFER_OFFSET_ALIGNMENT = 4
glXGetCurrentContext() not found: /usr/bin/../lib/x86_64-linux-gnu/apitrace/wrappers/egltrace.so: undefined symbol: glXGetCurrentContext
apitrace: warning: caught signal 6
apitrace: flushing trace
/usr/bin/../lib/x86_64-linux-gnu/apitrace/wrappers/egltrace.so+0x226300
/lib/x86_64-linux-gnu/libc.so.6+0x3bf8f: ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
/lib/x86_64-linux-gnu/libc.so.6: __pthread_kill_implementation+0x8accc: ./nptl/pthread_kill.c:44
/lib/x86_64-linux-gnu/libc.so.6: __GI_raise+0x11: ../sysdeps/posix/raise.c:26
/lib/x86_64-linux-gnu/libc.so.6: __GI_abort+0xd2: ./stdlib/abort.c:79
/lib/x86_64-linux-gnu/libepoxy.so.0: do_dlsym+0xc0fb0: ../src/dispatch_common.c:343
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_glXGetCurrentContext_resolver+0xbecee: src/glx_generated_dispatch.c:3736
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_glXGetCurrentContext_global_rewrite_ptr+0xbecee: src/glx_generated_dispatch.c:4270
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_get_bootstrap_proc_address+0xc185d: ../src/dispatch_common.c:813
/lib/x86_64-linux-gnu/libepoxy.so.0: gl_single_resolver+0x64332: src/gl_generated_dispatch.c:75810
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_glGetIntegerv_resolver+0x70ffe: src/gl_generated_dispatch.c:87733
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_glGetIntegerv_global_rewrite_ptr+0x70ffe: src/gl_generated_dispatch.c:115489
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_internal_has_gl_extension+0xc128a: ../src/dispatch_common.c:530
/lib/x86_64-linux-gnu/libepoxy.so.0: epoxy_internal_has_gl_extension+0xc128a: ../src/dispatch_common.c:519
/lib/x86_64-linux-gnu/libgtk-4.so.1: gdk_gl_context_make_current+0x21a
/lib/x86_64-linux-gnu/libgtk-4.so.1+0x4b7a23
/lib/x86_64-linux-gnu/libgtk-4.so.1+0x4ac48f
/lib/x86_64-linux-gnu/libgtk-4.so.1: gsk_renderer_realize+0x11d
/lib/x86_64-linux-gnu/libgtk-4.so.1: gsk_renderer_new_for_surface+0x9c
/lib/x86_64-linux-gnu/libgtk-4.so.1+0x31e6b7
/lib/x86_64-linux-gnu/libgtk-4.so.1+0xd3680
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_closure_invoke+0x15f
/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x28d2c
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit_valist+0xf34
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit+0x8e
/lib/x86_64-linux-gnu/libgtk-4.so.1: gtk_widget_realize+0x6f
/lib/x86_64-linux-gnu/libgtk-4.so.1+0x323851
/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x165a8
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit_valist+0xefe
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit+0x8e
/lib/x86_64-linux-gnu/libgtk-4.so.1: gtk_widget_show+0xa0
/lib/x86_64-linux-gnu/libgtk-4.so.1: gtk_window_present_with_time+0xb4
gtk4-demo+0x6cf77
/lib/x86_64-linux-gnu/libgio-2.0.so.0+0x81b66
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_closure_invoke+0x15f
/lib/x86_64-linux-gnu/libgobject-2.0.so.0+0x29075
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit_valist+0x76c
/lib/x86_64-linux-gnu/libgobject-2.0.so.0: g_signal_emit+0x8e
/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xdafd2
/lib/x86_64-linux-gnu/libgio-2.0.so.0+0xdd309
/lib/x86_64-linux-gnu/libgio-2.0.so.0: g_application_run+0x145
gtk4-demo: main+0x204
/lib/x86_64-linux-gnu/libc.so.6: __libc_start_call_main+0x27189: ../sysdeps/nptl/libc_start_call_main.h:58
/lib/x86_64-linux-gnu/libc.so.6: __libc_start_main_impl+0x84: ../csu/libc-start.c:381
gtk4-demo: _start+0x20
?
apitrace: info: taking default action for signal 6

Signed-off-by: David Heidelberg [email protected]

okias avatar Dec 27 '22 16:12 okias

A less invasive fix would be to expose glXGetCurrentContext from egltrace.so by hand. I think this should do the trick, and be relatively safe:

diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
index e98eb3ce..22d6f0e6 100644
--- a/wrappers/egltrace.py
+++ b/wrappers/egltrace.py
@@ -125,3 +125,21 @@ if __name__ == '__main__':
     api.addModule(module)
     tracer = EglTracer()
     tracer.traceApi(api)
+
+    # Epoxy checks for the symbol glXGetCurrentContext (which they won't use later)
+    # https://github.com/apitrace/apitrace/pull/855
+    print('''
+#ifndef HAVE_X11
+typedef void * GLXContext;
+#endif
+
+extern "C" PUBLIC
+GLXContext glXGetCurrentContext(void)
+{
+#if HAVE_X11
+    return _glXGetCurrentContext();
+#else
+    os::abort();
+#endif
+}
+''')

It would be nice to one day merge egltrace/glxtrace and eglretrace/glretrace. For eglretrace/glretrace I know this should now be feasible, at least on systems with libglvnd. But I'm less sanguine about egltrace/glxtrace

jrfonseca avatar Jan 11 '23 15:01 jrfonseca

works for me, but with little edit:

diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
index 22d6f0e6..50f25b9a 100644
--- a/wrappers/egltrace.py
+++ b/wrappers/egltrace.py
@@ -139,7 +139,7 @@ GLXContext glXGetCurrentContext(void)
 #if HAVE_X11
     return _glXGetCurrentContext();
 #else
-    os::abort();
+    return nullptr;
 #endif
 }
 ''')

okias avatar Jan 11 '23 20:01 okias

works for me, but with little edit

I left os::abort() under the assumption glXGetCurrentContext would not be called by GTK/Epoxy like you said on your earliest comment, but I suppose that's not the case after all.

Returning nullptr from the wrapper's glXGetCurrentContext() means the wrapper will change the traced application behavior, possibly even causing misbehavior, so we can't do that.

Therefore I see three ways forward here:

  • we commit my patch above with the os::abort as is, and you avoid the os::abort by building egltrace.so with X11 headersl
  • we replace os::abort with more hand written code to dlsym and call the real glXGetCurrentContext() function;
  • or this stays as a hack that doesn't get merged.

jrfonseca avatar Jan 16 '23 13:01 jrfonseca