使用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;
}