开发者

glDrawArrays() segfaults when drawing too many elements

开发者 https://www.devze.com 2023-03-12 15:28 出处:网络
I have some simple OpenGL ES code in C++ that I\'ve run on a phone running Android, a phone running webOS, and my Mac using SDL/OpenGL. The code in question just draws a GL_LINE_STRIP that\'s stored i

I have some simple OpenGL ES code in C++ that I've run on a phone running Android, a phone running webOS, and my Mac using SDL/OpenGL. The code in question just draws a GL_LINE_STRIP that's stored in an array of GLfloats. Here's how I'm trying to do this (version 1):

GLfloat array* = new GLfloat[2048];
//later... (array gets filled)
int howMany = 1024;
glVertexPointer(2, GL_FLOAT, 0, array); checkError();
glDrawArrays(GL_LINE_STRIP, 0, howMany); checkError();

Seems like it should be pretty straightforward. However, the above code segfaults inside OpenGL drivers on both Android and my Mac (seems to run fine on webOS, for whatever reason.) Here's what I have to do to avoid this (version 2):

GLfloat array* = new GLfloat[2048];
//later... (array gets filled)
int howMany = 1024;
for (unsigned i = 0; i < howMany; i += 789) {
    glVertexPointer(2, GL_FLOAT, 0, array+i*2); checkError();
    //this is not a bug: we draw one more than we increment by, or there is a hole in the graph
    glDrawArrays(GL_LINE_STRIP, 0, std::min(790U, howMany-i)); checkError();
}

Limiting the number of lines drawn at a time consistently avoids the segfault. The number 790 was determined experimentally; at 791 it crashes on OSX (Android can go higher, though it used to be limited to 113 many versions ago... so the number seems to be consistent for each app version but not between different versions or platforms.)

There is a lot of other GL stuff going on in my app, but it's a large application and posting all of that code wouldn't be practical. So, what could possibly cause this? What possibilities should I look into?

Here's the valgrind output of my program running and crashing on OSX when I try to use version 1:

==85414== Conditional jump or move depends on uninitialised value(s)
==85414==    at 0x1D022993: glVertexPointer_Exec (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x6AA59A9: glVertexPointer (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)
==85414==    by 0x2B001: draw_elements (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x2B44C: glDrawArrays (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0xB639: GLImage::glDraw(int, int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0xC292: GLLabel::glDraw(int, int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1AC67: RTAPlot::drawAxes(int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1B30A: RTAPlot::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x225F5: RTAPlotView::updateForeground() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x19FC4: RTAComponent::update() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x805D: AudiaApplication_private::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x267DF: AudiaApplication::run() (in ./rta.app/Contents/MacOS/rta)
==85414==  Uninitialised value was created by a stack allocation
==85414==    at 0x1D02268F: glVertexPointer_Exec (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414== 
==85414== Conditional jump or move depends on uninitialised value(s)
==85414==    at 0x1D022E0C: glTexCoordPointer_Exec (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x6AA5216: glTexCoordPointer (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)
==85414==    by 0x2B279: draw_elements (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x2B44C: glDrawArrays (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0xB639: GLImage::glDraw(int, int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0xC292: GLLabel::glDraw(int, int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1AC67: RTAPlot::drawAxes(int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1B30A: RTAPlot::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x225F5: RTAPlotView::updateForeground() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x19FC4: RTAComponent::update() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x805D: AudiaApplication_private::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x267DF: AudiaApplication::run() (in ./rta.app/Contents/MacOS/rta)
==85414==  Uninitialised value was created by a stack allocation
==85414==    at 0x1D022A6B: glTexCoordPointer_Exec (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414== 
==85414== Invalid read of size 8
==85414==    at 0x1D0B9166: gleRunVertexSubmitImmediate (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x1D0B84FB: gleLLVMArrayFunc (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x1D0A14F2: gleDrawArraysOrElements_ExecCore (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x1D0A2A04: glDrawElements_IMM_Exec (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Resources/GLEngine.bundle/GLEngine)
==85414==    by 0x6AA304F: glDrawElements (in /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)
==85414==    by 0x2B2DB: draw_elements (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x2B44C: glDrawArrays (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1FEF6: RTAPlotCanvas::drawLineStrip(float*, unsigned int) (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1E91A: RTAPlotCanvas::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x1B318: RTAPlot::updateGL() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x225F5: RTAPlotView::updateForeground() (in ./rta.app/Contents/MacOS/rta)
==85414==    by 0x19FC4: RTAComponent::update() (in ./rta.app/Contents/MacOS/rta)
==85414==  Address 0xc0000000 is not stack'd, malloc'd or (recently) free'd
==85414== 
==85414== 
==85414== Process terminating with default action of signal 11 (SIGSEGV)
==85414==  General Protection Fault
==85414==    at 0x10AED0: misaligned_stack_error_ (in /usr/lib/libSystem.B.dylib)
==85414==    by 0x1E45E87: -[NSCustomReleaseData dealloc] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0x1E45E37: -[NSBitmapImageRep _freeData] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0x1E45DCA: -[NSBitmapImageRep _freeImage] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0x1E45D74: -[NSBitmapImageRep dealloc] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0x171DF37: CFRelease (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==85414==    by 0x1748691: __CFArrayReleaseValues (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==85414==    by 0x171E100: _CFRelease (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundat开发者_如何学Pythonion)
==85414==    by 0x1D89F7A: -[NSImage dealloc] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0x20857D4: -[NSCursor dealloc] (in /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit)
==85414==    by 0xDFE33: QZ_FreeWMCursor (in /opt/PalmPDK/host/lib/libSDL-1.2.0.11.2.dylib)
==85414==    by 0xCA11F: SDL_FreeCursor (in /opt/PalmPDK/host/lib/libSDL-1.2.0.11.2.dylib)
--85414:0:schedule VG_(sema_down): read returned -4

Note that the first two conditional jump errors happen every time, and might not be a problem with my app. The invalid read error only occurs when I try to use version 1 on OSX.


It may not be related to your vertex array at all. For example there might be still pointers to the other vertex attribues set, and of course if those are of smaller buffers than the new vertex array you'll get a segfault.

If you look closely at your valgrind output you'll see, that there's still a texture coord pointer set.

So what I suggest is you disable all vertex attribute arrays you don't need:

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
/* ... */

in your case

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
0

精彩评论

暂无评论...
验证码 换一张
取 消