Propagating C ++ exceptions in C stack frame on OS X

The application I'm working on (it's a game, actually) uses XML for some of its configuration. Since I am using CEGUI for the GUI and it has its own XML parsing objects, I converted my code to use it instead of my own hand-crafted parser class. If the document is missing attributes for certain tags, it will throw the exception that I want. However, the exception does not propagate through C calls on the stack; terminate () is called instead.

For those not familiar with CEGUI, it uses a plugin system for parsing XML. There are currently plugins for tinyxml, expat, libxml and xerces. No special plugin will be present in a particular CEGUI binary distribution; the only requirement is to have at least one. So my problem cannot be solved by using a C ++ parser (tinyxml or xerces).

Does anyone know of a good workaround for this issue that doesn't require me to distribute the source for CEGUI and its XML parser plugin dependencies with my game source?

It should also be noted that this problem only occurs on OS X; it works fine on GNU / Linux.

Here's a simple code example that demonstrates the problem:

EDIT: minor code correction http://pastebin.com/m23ba5577

Thanks Rob

+1


source to share


6 answers


With regard to the source you posted, if you compile test.c with a C ++ compiler, everything will work as expected (you will need to do extern "C" functions, which I understand you cannot do outside of your example) ...

The difference in the generated symbols sheds light on what's going on:

C ++ compiler: g++ -c test.c

00000040 s EH_frame1
         U ___gxx_personality_v0
0000001a T _callIt
0000005c S _callIt.eh
00000088 b _callback
00000000 T _setCallback
00000000 A _setCallback.eh

C compiler: gcc -c test.c



00000019 T _callIt
0000003c b _callback
00000000 T _setCallback

As you can see, there is an extra symbol for each function ending with ".eh" and EH_frame1 - these contain a description of the call frames to be unwound if an exception occurs. If they are missing ... do nothing but call terminate ().

Given that C does not support exceptions, the C compiler will not write these characters to the object file.

So, if you have no control over how these libraries are compiled, your best bet is to install a SIGABRT handler before parsing and treat it as a "thrown exception" call. You are still missing information about the errors, but you will know what happened.

+4


source


Nothing happens in the sample code. In such a case (when the exception to throw does not have a matching catch block), the C ++ runtime calls std :: terminate.



But I don't see how all this has to do with the body of your question ...

0


source


Sorry about that; I just added a fix. If you compile and run this code on OS X, you will notice that it is still terminate () s.

What this has to do with my comment is that this is a simple demonstration of the problem without posting all of my application code. = D

0


source


I have a feeling that you answered your own question

http://discussions.apple.com/thread.jspa?threadID=1852579&tstart=0

0


source


It's true, I got the answer to this question on the Apple development forums. However, this does not mean that this is the only answer. I actually came up with four answers, all of which are suboptimal:

  • Distribute Expat, libxml and CEGUI with my application and make sure Expat and libxml use -fexceptions when built on OS X.
  • Limit the parser plugins my app can use on OS X for tinyxml and xerces plugins.
  • Wrap my XML reading code in setjmp / longjmp and throw an exception if setjmp returns a valid value.
  • Get rid of XML and CEGUI in my application.

While each of these answers solves my problem, they all have drawbacks. I'm just trying to get all the answers I can do to make an informed decision.

0


source


I am definitely not an expert, but something that I can define; how the C / C ++ runtime will execute with respect to C ++ exceptions thrown in the presence of C functions on the stack is implementation defined.

I am wondering how to use C ++ exceptions as a mechanism to handle missing attributes. Do C XML libraries support using C ++ exceptions this way? In other words, are C runtime resources properly released when there is an exception, given that the libraries are for the C language?

I would recommend shortening your use of XML libraries for those that support either C or C ++, not so that you can implement one error mechanism.

0


source







All Articles