
Hi Christian, I wonder if anyone will notice this message amid all the mud and flame-slinging that's going on? I know - I'll get everyone's attention by pointing out that the fundamental problem here is that the C library, libjpeg, has a truly awful API design: when it gets an error, it calls a user-supplied function-pointer and that mustn't return. Christian Henning wrote:
I agree with Phil; that's undefined behaviour. ?I can't access the official C standard here, but in the C99 draft N1256 (http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf), in 7.13.2.1p2, it says (of longjmp):
... if the function containing the invocation of the setjmp macro has terminated execution in the interim, ... the behavior is undefined.
So, once try_something has returned, the effect of calls to longjmp is undefined.
Does that mean I have to call setjmp everytime before I call libjeg function? This way the function that calls setjmp would not have been terminated.
Your choices are: 1. setjmp() in each function (scope?) that calls into libjpeg. That's nasty because setjmp(), IIRC, is detected by the compiler and prevents some optimisations. It's relatively non-intrusive in your code though. 2. setjmp() once, and make sure that that is in a scope that contains all the calls. This means turning your code inside out, but it's not impossible because - as we've noted - you never leave a jpeg file open and return to the user code, i.e. the setjmp() can happen soon after the user calls into your code. I don't think that destructors will not be called when longjmp() "pops" the stack, so you need to be careful about what types you use. 3. (deleted - idea too horrible to share.) 4. Try to throw an exception from the error handler. This would be ideal, if you could be sure that the exception would propagate through the C code. I believe that gcc has an option to control that. I have a feeling that it is enabled for some libraries in Debian precisely to support this sort of thing. I know nothing about other compilers, and even on Linux it's probably not reasonable to expect that the user will use a libjpeg compiled in this way. 5. (Grasping at straws) run libjpeg in a co-routine, err, not sure exactly how that would work, but something about an extra stack... 6. This is what I'd really like to see: copy the libjpeg source into your project, and then do (4). You could do some other tidying-up at the same time. My recollection is that one of the other libraries also had a setjmp error handler, but that it could be configured to instead return error codes while libjpeg can't. Not sure if that's accurate though. Regards, Phil.