使用帖子[RFC] C-source code writing functionality for ApiTrace (glx/egl),我设法在Android上获取正在运行的应用程序的跟踪,并为此跟踪生成了C代码。此代码构建于Linux(Ubuntu 14.04)之上,但遗憾的是它不运行/ segfaults。下面的代码是问题的最小“工作”示例。
我首先注意到glBindBuffer
上的段错误,其中(glGenBuffers crashing with Segmentation fault)对未初始化的glewInit
发布了错误。所以我尝试添加glewInit
,但是:
glewInit()
之前发生eglMakeCurrent()
,则err
不是GLEW_OK
,最终glBindBuffer
会出现段错误:glewInit failed Program received signal SIGSEGV, Segmentation fault. 0x00000000 in ?? () (gdb) bt #0 0x00000000 in ?? () #1 0x08048b43 in frame_0 () at myegltestmain.c:29 #2 0x08048b6a in run_trace () at myegltestmain.c:36 #3 0x08048f42 in main (argc=1, argv=0xbffff044) at myegltestmain.c:126
glewInit()
发生在eglMakeCurrent()
之前(如下面的代码所示),那么我会得到一个带有此堆栈跟踪的段错误:Program received signal SIGSEGV, Segmentation fault. 0xb7e12f6a in XQueryExtension () from /usr/lib/i386-linux-gnu/libX11.so.6 (gdb) bt #0 0xb7e12f6a in XQueryExtension () from /usr/lib/i386-linux-gnu/libX11.so.6 #1 0xb7e0722e in XInitExtension () from /usr/lib/i386-linux-gnu/libX11.so.6 #2 0xb7bbdd54 in ?? () from /usr/lib/i386-linux-gnu/mesa/libGL.so.1 #3 0xb7bb9785 in glXQueryVersion () from /usr/lib/i386-linux-gnu/mesa/libGL.so.1 #4 0xb7f857d7 in glxewContextInit () from /usr/lib/i386-linux-gnu/libGLEW.so.1.10 #5 0xb7f8bf44 in glewInit () from /usr/lib/i386-linux-gnu/libGLEW.so.1.10 #6 0x08048ee6 in main (argc=1, argv=0xbffff044) at myegltestmain.c:115
是否可以在桌面Linux版本上使用GLEW和OpenGL ES(显然,它适用于Android) - 如果是,那么如何;我可以在下面的例子中修改什么,以便运行?
myegltestmain.c
// gcc -Wall -ansi --std=c99 -g -O0 myegltestmain.c -o myegltestmain -lGLEW -lEGL -lGLESv1_CM -lX11
#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES 1
#include <string.h>
#include <math.h>
#include <GL/glew.h> // added for GL_VERTEX_SHADER
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
unsigned int _buffers_1 = 1;
unsigned int* _buffers_1_p = &_buffers_1;
const int screensize0[2] = { 600 ,976 };
int egl_config_params0[] = { 12352, 4, 12324, 8, 12323, 8, 12322, 8, 12321, 8, 12325, 0, 12326, 0, 12339, 4, 12344, 0 };
int egl_context_params0[] = { 12440, 2, 12344, 0 };
Display *dpy;
EGLDisplay display;
EGLContext context;
EGLSurface surface;
void frame_0(){
glViewport(0, 0, 600, 976);
glScissor(0, 0, 600, 976);
glGenBuffers(1, _buffers_1_p); // line 29
glBindBuffer(GL_ARRAY_BUFFER, *_buffers_1_p);
}
static void run_trace()
{
frame_0();
return;
}
static Bool WaitForNotify( Display *dpy, XEvent *event, XPointer arg ) {
return (event->type == MapNotify) && (event->xmap.window == (Window) arg);
(void)dpy;
}
int main( int argc, char *argv[] )
{
Window xWin;
XEvent event;
XSetWindowAttributes swa;
EGLConfig ecfg;
EGLint num_config;
//load_all_blobs;
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
printf("Not able to connect to X server\n");
exit(EXIT_FAILURE);
}
swa.event_mask = StructureNotifyMask;
xWin = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, screensize0[0], screensize0[1],
0, CopyFromParent, InputOutput, CopyFromParent,
CWEventMask, &swa);
XMapWindow(dpy, xWin);
XIfEvent(dpy, &event, WaitForNotify, (XPointer)xWin);
display = eglGetDisplay((EGLNativeDisplayType)dpy);
if (display == EGL_NO_DISPLAY) {
fprintf(stderr, "Got no EGL display.\n");
exit(EXIT_FAILURE);
}
if (!eglInitialize(display, NULL, NULL)) {
fprintf(stderr, "Unable to initialize EGL\n");
exit(EXIT_FAILURE);
}
eglBindAPI(EGL_OPENGL_ES_API);//EGL_OPENGL_API);//EGL_OPENGL_ES_API);//egl_api_bind0);
if (!eglChooseConfig(display, egl_config_params0, &ecfg, 1,
&num_config)) {
fprintf(stderr, "Failed to choose config (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
if (num_config != 1) {
fprintf(stderr, "Didn't get just one config, but %d\n", num_config);
exit(EXIT_FAILURE);
}
surface = eglCreateWindowSurface(display, ecfg, xWin, NULL);
if (surface == EGL_NO_SURFACE) {
fprintf(stderr, "Not able to create EGL surface (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
context = eglCreateContext (display, ecfg, EGL_NO_CONTEXT,
egl_context_params0);
if (context == EGL_NO_CONTEXT) {
fprintf(stderr, "Not able to create EGL context (eglError: 0x%x)\n",
eglGetError());
exit(EXIT_FAILURE);
}
eglMakeCurrent(display, surface, surface, context);
GLenum err=glewInit();
if(err!=GLEW_OK) {
fprintf(stderr, "glewInit failed\n");
} else {
fprintf(stderr, "glewInit OK\n");
}
/*
* Setup done. Now go to the trace.
*/
run_trace();
eglDestroyContext(display, context);
eglDestroySurface(display, surface);
eglTerminate(display);
XDestroyWindow(dpy, xWin);
XCloseDisplay(dpy);
//free_all_blobs;
exit(EXIT_SUCCESS);
(void)argc;
(void)argv;
}