使用post [RFC] C-source code writing functionality for ApiTrace (glx/egl),我设法在Android上获取正在运行的应用程序的跟踪,并为此跟踪生成了C代码 . 此代码构建于Linux(Ubuntu 14.04)之上,但遗憾的是它不运行/ segfaults . 下面的代码是问题的最小例子.2397644_ .
我首先注意到 glBindBuffer
上的一个段错误,它在未初始化的 glewInit
上发布(glGenBuffers crashing with Segmentation fault) . 所以我尝试添加 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;
}