Closed jjcasmar closed 2 years ago
apitrace issue was solved with this patch, which may help to solve this similar issue in renderdoc
diff --git i/dispatch/glproc.py w/dispatch/glproc.py
index f26a4f7d..c2701228 100644
--- i/dispatch/glproc.py
+++ w/dispatch/glproc.py
@@ -590,6 +590,7 @@ if __name__ == '__main__':
print
print 'void * _getPublicProcAddress(const char *procName);'
print 'void * _getPrivateProcAddress(const char *procName);'
+ print 'void * _eglGetProcAddress_KDAB(const char *procName, void (* (_eglGetProcAddress)(const char*))());'
print
dispatcher = GlDispatcher()
print
diff --git i/dispatch/glproc_egl.cpp w/dispatch/glproc_egl.cpp
index 07714ae8..40119118 100644
--- i/dispatch/glproc_egl.cpp
+++ w/dispatch/glproc_egl.cpp
@@ -72,10 +72,12 @@ _getPublicProcAddress(const char *procName)
* symbols are exported by multiple APIs/SOs, and it's not trivial to
* determine which API/SO we should get the current symbol from.
*/
+ // egl
proc = dlsym(RTLD_NEXT, procName);
if (proc) {
return proc;
}
+ os::log("apitrace: _getPublicProcAddress(%s) couldn't dlsym(RTLD_NEXT)\n", procName);
/*
* dlsym(RTLD_NEXT, ...) will fail when the SO containing the symbol was
@@ -87,13 +89,16 @@ _getPublicProcAddress(const char *procName)
*/
if (procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') {
+ os::log("apitrace: loading libEGL ourselves\n");
static void *libEGL = NULL;
if (!libEGL) {
libEGL = _dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY);
if (!libEGL) {
+ os::log("apitrace: loading libEGL ourselves didn't work: %s\n", dlerror());
return NULL;
}
}
+ os::log("apitrace: dlsym(libEGL, \"%s\")\n", procName);
return dlsym(libEGL, procName);
}
@@ -114,12 +119,12 @@ _getPublicProcAddress(const char *procName)
*
* See https://github.com/apitrace/apitrace/issues/301#issuecomment-68532248
*/
- if (strcmp(procName, "eglGetProcAddress") != 0) {
- proc = (void *) _eglGetProcAddress(procName);
- if (proc) {
- return proc;
- }
- }
+// if (strcmp(procName, "eglGetProcAddress") != 0) {
+// proc = (void *) _eglGetProcAddress(procName);
+// if (proc) {
+// return proc;
+// }
+// }
/*
* TODO: We could futher mitigate against using the wrong SO by:
@@ -128,14 +133,17 @@ _getPublicProcAddress(const char *procName)
*/
if (procName[0] == 'g' && procName[1] == 'l') {
+ os::log("apitrace: looking up gl function by loading lib ourselves\n");
/* TODO: Use GLESv1/GLESv2 on a per-context basis. */
static void *libGLESv2 = NULL;
if (!libGLESv2) {
+ os::log("apitrace: loading libGLESv2\n");
libGLESv2 = _dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY);
}
if (libGLESv2) {
proc = dlsym(libGLESv2, procName);
+ os::log("apitrace: dlsym(libGLESv2, %s) = %p\n", procName, proc);
}
if (proc) {
return proc;
@@ -156,6 +164,44 @@ _getPublicProcAddress(const char *procName)
return NULL;
}
+void * _eglGetProcAddress_KDAB(const char *procName, void (* (_eglGetProcAddress)(const char*))())
+{
+ void * proc;
+ os::log("apitrace: KDAB eglGetProcAddress\n");
+ if (procName[0] == 'g' && procName[1] == 'l') {
+ os::log("apitrace: looking up gl function by loading lib ourselves\n");
+ /* TODO: Use GLESv1/GLESv2 on a per-context basis. */
+
+ static void *libGLESv2 = NULL;
+ if (!libGLESv2) {
+ os::log("apitrace: loading libGLESv2\n");
+ libGLESv2 = _dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY);
+ }
+ if (libGLESv2) {
+ proc = dlsym(libGLESv2, procName);
+ os::log("apitrace: dlsym(libGLESv2, %s) = %p\n", procName, proc);
+ }
+ if (proc) {
+ return proc;
+ }
+
+ static void *libGLESv1 = NULL;
+ if (!libGLESv1) {
+ libGLESv1 = _dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY);
+ }
+ if (libGLESv1) {
+ proc = dlsym(libGLESv1, procName);
+ }
+ if (proc) {
+ return proc;
+ }
+ }
+
+ os::log("apitrace: defaulting to original eglGetProcAddress\n");
+ proc = (void*)_eglGetProcAddress(procName);
+ return proc;
+}
+
/*
* Lookup a private EGL/GL/GLES symbol
*
diff --git i/dispatch/glproc_gl.cpp w/dispatch/glproc_gl.cpp
index 7d162dab..7b094f6c 100644
--- i/dispatch/glproc_gl.cpp
+++ w/dispatch/glproc_gl.cpp
@@ -148,7 +148,7 @@ _getPrivateProcAddress(const char *procName)
static inline void
logSymbol(const char *name, void *ptr) {
- if (0) {
+ if (1) {
if (ptr) {
Dl_info info;
if (ptr && dladdr(ptr, &info)) {
diff --git i/wrappers/gltrace.py w/wrappers/gltrace.py
index 6f96572e..d4a11adc 100644
--- i/wrappers/gltrace.py
+++ w/wrappers/gltrace.py
@@ -853,13 +853,15 @@ class GlTracer(Tracer):
print ' } else if (strcmp("%s", (const char *)%s) == 0) {' % (marker_function, nameArg)
print ' _result = (%s)&%s;' % (function.type, marker_function)
print ' } else {'
- Tracer.doInvokeFunction(self, function)
+# Tracer.doInvokeFunction(self, function)
+ print ' _result = (__eglMustCastToProperFunctionPointerType)_eglGetProcAddress_KDAB(procname, _eglGetProcAddress);';
# Replace function addresses with ours
# XXX: Doing this here instead of wrapRet means that the trace will
# contain the addresses of the wrapper functions, and not the real
# functions, but in practice this should make no difference.
if function.name in self.getProcAddressFunctionNames:
+ print ' os::log("apitrace: got %p for %s\\n", _result, procname);'
print ' _result = _wrapProcAddress(%s, _result);' % (nameArg,)
print ' }'
Sorry, you've included a lot of information that I'm not familiar with so you'll need to explain it to me in more detail. What is "eglds Qt qpa" ? You also mention under steps to reproduce that "Rendercapture" displays errors about unresolved functions but I don't know what that is. Is that the application that you're capturing, and is it something that's available or that I could run myself to test with?
You've mentioned a log, but the log you've include is not from RenderDoc so I don't know what it is. Can you attach the RenderDoc log? You mention using renderdoccmd, is this on an Android system?
Are you able to run your program on a non-embedded linux system and reproduce the problem? RenderDoc is not supported on anything except x86-64 for linux, ARM is only supported on Android, so from what you're describing if this issue only replicates on ARM systems then it might be an architecture/platform specific problem and not something I can look into.
eglfs Qt qpa is a platform integration plugin to abstract the underlying window system of a platform (X, wayland, egl...) in Qt. Basically, on an embedded device, when you are not running a windows manager, you can use eglfs to render to fullscreen a Qt application. (https://doc.qt.io/qt-5/embedded-linux.html). I doubt you can run it yourself, at least not without a lot of work. Maybe I can share a rpi4/3 image with everything needed if you have a spare one to test if you want.
The log I have posted is the output I am getting when I try to run the application. How can I get a RenderDoc log?
No, its not android, its a Linux system running on an ARM platform, so I guess it is an unsupported platform. Feel free to close the issue in that case.
Yes sorry, if you're running on ARM linux that's not supported at the moment so there may be bugs. In addition I would imagine there are platform-specific details and requirements for embedded devices which are not handled on top of that. I don't have any such device to test on even if it were supported I'm afraid.
Description
When using eglfs Qt qpa on an embedded platform, renderdocmd is unable to capture a trace due to unresolved functions (log below).
Steps to reproduce
On an embedded linux platform (I have tried several iMX8 and Rpi4), try to run
renderdoccmd capture yourApp
. Rendercapture shows a bunch of unresolved functions and then the application crashes. I have tested with several applications, both my own applications and also with Qt OpenGL examples.Environment
I have been using a linux image built with yocto. RenderDoc version: Tested with 1.7 and 1.17, both with same result Operating System: Linux Graphics API: GLES 3.1 Driver: Vivante GC7000UL
apitrace shows a similar behavior, described in this patch https://github.com/dangelog/apitrace/commit/1f42a3484e97a2008ad43891c17dc9fcaee60f67