OpenGL crashes in 64 bit application

OpenGL crashes in 64 bit application

I have been having problems with trying to plot Trimmed NURBs surfaces obtained from standard IGES graphics files. Invariably there are several NURBs surfaces within an IGES file that contain errors that prevent the trimming process which is fine if the program can either ignore them or take action to fix them. Unfortunately my application just crashes at the fgluEndSurface() statement when trim curves are faulty. In order to reproduce this effect I have cobbled together an example using the IVF OpenGL Rings sample program. I created a simple NURBs surface with trim curve. When the trim curve is correctly orientated (counter clockwise) the program runs and displays the surface however if the trim curve orientation is reversed it crashes (in 64-bit only). I try to intercept with a callback but this does not seem to work or may be part of the cause of the crash. The message given is:

First-chance exception at 0x000007f88cd53ef8 in Rings.exe: 0xC0000028: An invalid or unaligned stack was encountered during an unwind operation.
Unhandled exception at 0x000007f88cd53ef8 in Rings.exe: 0xC0000028: An invalid or unaligned stack was encountered during an unwind operation.

The 32-bit configuration seems to ignore the error and the callback routine is not called.

Any help would be much appreciated.

 

Thanks in advance

 

Steve

AttachmentSize
Downloadapplication/zip OpenGL-Crash.zip16.46 KB
23 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I use opengl from Fortran for some caddy stuff  so I had a look at your problem. For what its worth a built your test case in 32 and 64 bit and get the behaviour you describe. I had a quick  look at your init routine for obvious against the ogl sdk docs errors and didn't find any.

It is possible that this is simply a bugin the OGL library. It would make more sense to perhaps do some validation on the nurbs before throwing bad data at OGL. I expect there will be some lib tools available for this...

What do you use for the IGES reader/parser is this Fortran also? Is it your own or third parts stuff BTW?

I will have a look a little further at this.

 Andrew

 

 

Hi Andrew

Thanks for having a look at this. I have already assumed a bug in OGL and therefore started writing routines for checking of trim curves before submitting to OGL as you suggested. This is proving a pain because of the number of types of error that can cause the crash. We get the CAD data from CATIA the quality of which is generally beyond our control. The IGES translator program is written in Fortran and I can modify this as I wish. During the course of the development process I found what I believe to be bugs in the ifopngl module interfaces (see below for list)  and I was hoping this could be the cause particular with regard to the callback assignment. I've also tried using both f90gl and f03gl interface modules but I still get the crash. BTW the f03gl looks to be the cleanest of the three interfaces I know of as they support C bindings.

The following interfaces I have found to be incorrect in the Intel ifopngl interface module: (error is generally in the data argument type)

fgluErrorString, fgluBeginPolygon, fgluBitmap, fglLoadMatrix, fgGetMaterialfv, fgGetMaterialiv, fglMap1d, fglMap1f, fglMap2d, fglMap2f, fglClipPlane

There may be others but these are the ones I've used in my program which I've worked around using my own interfaces.

I hope Intel can have a look into fixing these in the near future, they are usually pretty good at addressing user's issues. I only wish Microsoft would be so helpful to it's users.

With regard to the possible bug in OGL who should I contact to try and get this resolved (OGL, Microsoft, Intel)?

Steve

>>An invalid or unaligned stack was encountered during an unwind operation.

This could occur with C++ exception handling when intervening functions (subroutines) do not provide proper (or accidental) SEH enclosures.

My guess, is that OpenGL is written in C++ with SEH (Structured Exception Handling).

As a test/work-a-round write a MYfgluEndSurface.cpp shell function, with SEH enabled, that is called from Fortran, and which calls gluEndSurface from within a try {} block, and in which you have a catch{} to catch all errors. Once you determine the error you can take appropriate action, however in a hack test you could simply set a global error flag and return. The caller could determine if it could switch directions.

Jim Dempsey

www.quickthreadprogramming.com

yes indeed Catia and IGES aren't that happy together thought it improved a lot from Catia V4 to V5. The problem is often loose tolerances for matching trim curves at surface intersections such that the edges do not match that well so the surface  becomes untrimmed..

I use f03gl as:. 

1) It is not proprietary and the Intel interfaces sometime deviate a little from 'standard' OGL

2) It irritates me to add an F in front of all ogl functions...

You cannot use f03 as is, I have an edited version because BIND(c) cannot be used with STDCALL. Other Fortrans have a BIND(C) extension for stdcall but Intel does not.You have to remove bind(c) and add  !DEC$ attributes.

The OGL library is the onus of the OS vendor which is in this case is Microsoft. Good look in getting MS to fix anything, OGL is  not their thing, they want you to use directx or whatever they call it now.

Have you looked at Nlib Nurbs library that might do what you need (at a price). There may be other options.

Back to the IGES interfaces are those your own? Is there anything that is shareable?

Andrew

 

 

 

 

We inherited the OpenGL declarations from Microsoft - I too don't care for the f prefix naming, but we're stuck with it. I will check the interfaces you mention and compare with the Microsoft documentation to see if they need changing - we have fixed errors in these over the years.

Steve - Intel Developer Support

A module with USE statements and rename clauses could fix the names easily one would think.

I've had a go at Jim's suggestion though it didn't prevent the crash. This may be down to my ignorance of C++. I have managed to create the wrapper (with /EHsc enabled) that calls glEndSurface within a try {} block but this has no effect. I have put in an empty catch {} block as a starting point that I was hoping to populate once I understand to coding etc. but this now looks like a blind alley so may not be worth going down further. See below for C++ routine.  Sorry couldn't get the syntax highlighting to work!

#include <windows.h>
#include <GL/glu.h>
#include <iostream>

using namespace std;

class MyException{};

extern "C" {int MygluEndSurface(GLUnurbs *nurb);}

int MygluEndSurface(GLUnurbs *nurb)
{

//*************************************************************************
// Wrapper for gluEnd Surface to try to intercept excetpions
//*************************************************************************

try
    {
       gluEndSurface(nurb);
    }

catch(MyException& e)
{
       return(1);
}

return(0);

}

Quote:

Stephen Sutcliffe wrote:

The following interfaces I have found to be incorrect in the Intel ifopngl interface module: (error is generally in the data argument type)

fgluErrorString, fgluBeginPolygon, fgluBitmap, fglLoadMatrix, fgGetMaterialfv, fgGetMaterialiv, fglMap1d, fglMap1f, fglMap2d, fglMap2f, fglClipPlane

Here's what I've found:

fgluErrorString - incorrectly returns an integer(4) instead of a pointer

fgluBeginPolygon - argument needs to be address-sized integer

fgluBitMap - I assume you mean fglBitmap, had integer*4 for the bitmap pointer, needs to be address size

fglLoadMatrix - there isn't a routine by that name. There is fglLoadMatrixf and fglLoadMatrixd. I can't spot a problem with these. I note that we define these names as generics with two specifics each, one taking an array by reference, the other a pointer. This is how we've been addressing many of the routines that passed integer by value for all things by reference.

fglGetMaterialfv, fglGetMaterialiv - Need to specify float/int by reference instead of integer*4 by value (we use IGNORE_LOC to prevent problems when LOC(arg) is passed)

fglMapxx - points argument needs to be array of proper type passed by reference, or allow address-sized integer

fglClipPlane - equation needs to be an array by reference, or address-sized integer

We will get these fixes into an update. If you find any more errors, let us know.

Steve - Intel Developer Support

Here's a revised IFOPNGL module. Does it do what you need?

Attachments: 

AttachmentSize
Downloadapplication/octet-stream ifopngl.f90219.8 KB
Steve - Intel Developer Support

Hi Steve.

I've tried the revised ifopngl module and it works regarding the interfaces, so thanks for that, however the original problem regarding the application crash when calling fgluEndSurface (with faulty trim curves) still exists which is not that unexpected. Our findings so far suggest a bug in Microsoft's OpenGL libraries although whether this is specific to Fortran remains to be seen. I have spent far too long on this already (three weeks), I also recall I first encountered this issue back in October 2010 (Post still exists on this forum - "dannycat" 02/10/2010) and find it very frustrating that we can't get it resolved after all this time. As Andrew intimated earlier in this thread getting MS to address this might prove difficult from an individual user like myself though a request from a large respected company like Intel may carry more weight. I want to continue to support (and use)  both Intel Fortran and OpenGL (neither of which are owned by MS) and removing any hurdles preventing like this would be of benefit to every one.

 

So there is no issue with fglLoadMatrix? Note that when you use IFOPNGL, you're simply calling into the Microsoft API - there is no intermediate code we supply,

I haven't looked at your code yet, but make sure that any Windows API callback routines use the STDCALL mechanism. If you don't change this, you'll corrupt the stack.

Steve - Intel Developer Support

I am sure this is not the answer you want to hear....

I thought about this issue a bit further, the problem is the OGL (glu) function crashing with invalid data. OGL is primarily designed to display 3D data quickly and repeatedly. I am not sure it is within the remit of OGL to do extensive checking on the numerical validity of surface trim nurbs curves, some basic data validation yes but not extensive validation. Extensive checking would occur for every surface very time it was displayed. Really, all your entities need to be validated before they are made part of a display list. If I was the OGL lib author I could with some justification invoke the garbage in garbage out clause. 

I do agree that the behaviour of the OGL routine is  wrong in that you might not validate the cause of the crash but an effect that causes a crash is a bug...

I appreciate this is a difficult (and big) job to do all the validation. Some third party libraries are what you need if you want to to this at reduced effort.

 

Hi Steve,

fglLoadMatrixd works as long as you use reshape to ensure matrix argument is a 4x4 rather than a single vector(16). I would be interested to know if you spot anything wrong in the coding.

Andrew,

With regard to validating the trim curves issue I would hope that the OGL routine would simply not trim the surface if the data was invalid and not crash. The end user does not necessarily have the information to determine what is or isn't valid. With regard to trim curves I check if the curves are orientated consistently with respect to each other; that the ends are coincident with adjacent curves and that the winding direction is counterclockwise for outer & clock-wise for inner (unless concentric loops which alternate directions). The documentation states that if curve end points are close to being coincident then the trim should be successful so it does allow for some tolerance although not sure what size this is.

I originally suspected the callback routines being the cause of the crash and this may still be to case (hopefully it is!).

Before spending hours going through all this I wanted to rule out any programming issues on my part. During this process I have highlighted some bugs in the supplied interfaces that should help future users so I suppose the time was not wholly unproductive.

The OGL will not trim the surface at all. GLU functions are just preparatory, all I would expect it to do are create points on the edge curves and some internal points on the surface definition and make some triangles to pipe to OGL.

glLoadMatrixd expects a pointer to 16 consecutive memory locations. It is common practice to use 4x4 or 16, it should really not fuss about the shape of the data IMO.

 

 

 

While my comment about STDCALL in the callback is valid, it isn't relevant to x64. Nevertheless, your error callback needs to be STDCALL for IA-32.

I'd like to think that Intel would have some greater weight here with Microsoft, but in cases such as this I don't think we do. MS wouldn't look at a problem without a C example to demonstrate it.

Steve - Intel Developer Support

Hi Steve,

So can I assume that if I provide a C example which demonstates the problem, are you able to do something wrt MS? If I can't get the C program to produce the error then does this not imply the error is in Fortran interfaces? I can get the Trimmed NURB Surface example from the OpenGL Superbible and try that.

I've got so absorbed in this discussion that I am missing the point. Surely the NURBS error callback capability is provided to indicate errors in the input data and would not expect the user to have to check it to prevent a program crash. I can live with undesirable displays such as blank or untrimmed surfaces because the user can chose whether to ignore, fix the geometry or delete it.

 

If you can come up with a C example that demonstrates the problem, I'll see what I can do, but can't promise that my request would have any greater weight than your own to Microsoft. We have a good relationship with the Visual Studio side of MS, but the Windows OS side we don't deal much with (not counting the CPU folks who work with the OS kernel folks.)
 

Steve - Intel Developer Support

Hi Steve,

I've taken the nurbst example from the OpenGL SuperBible Rev.4 (Chapter 10) which renders a nurb surface with triangular hole. I've swapped the trim curves so that the inner becomes the outer and vice versa. The 32-bit displays something which is not right as expected but the 64-bit hangs. The error routine is not invoked. This behahavior is similar to my fortran example.

Note I had to rename the attachment (which hopefully includes all files needed to build in VS 2010) to be able attach it, should be .zip.

Thanks

Attachments: 

AttachmentSize
Downloadapplication/octet-stream nurbt.log276.33 KB

Ok, thanks.

Steve - Intel Developer Support

The errors in IFOPNGL are expected to be fixed in Update 3, due later this month.

Steve - Intel Developer Support

Thanks Steve

Will Update 3 address issue DPD200249339 which is currently preventing me from upgrading from Version 13. (Internal compiler message when union/map is used within a type end type block.) I first highlighted this when the first version 14 was released in October 2013.

With regard to the OpenGL issue (this thread) I have worked around the problem by performing an exhaustive validation of the trim curve definitions before calling the OGL routines. The only problem with this is that there is no guarantee that I have covered every possible failure scenario bearing in mind there  number of IGES files that I will have to deal with. I still hope that the stack corruption can be fixed so that the program at least stays alive. The callback mechanism does work but it only seems to check the main NURBS Curve or Surface definitions; programming sequence but not the trim curves.

Sorry, DPD200249339  is not yet fixed.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today