> On Jan 30, 2017, at 6:00 AM, Phil Rosenberg <p.d.rosenb...@gmail.com> wrote: > > Hi all > We have had this discussion in the past. But I would like to reopen it. > > We really really need to get id of the exit() calls in PLplot. I don't > think that we can really make any recommendation that our library is > "industrial strength" while they are their and I would be very nervous > about using PLplot in production software with them in - plus even > using PLplot for science work I have been caught out be these calls in > the past.
I have a patch that consolidated on the errors and warnings into a standardized function call. I was able to eliminate almost all the exit() calls that were scattered throughout the code (I think there were a couple that I left). I was thinking about having an internal API that allowed a driver to hook into that function to override the display and user dialog. For example, the GUI driver could display a dialog box instead of the I/O happening at the console. > > I think there are a few options we have got > > Firstly with our internal propagation we can either do > A1) Set up our functions so they return error codes and make sure we > check these. I feel there is a tendency for this to be bad because I > know that I am inherently lazy if I am frank (and I'm sure we all have > our lazy moments) and tend to write code without these checks then > (try to) go back and add them later. Missing checks are likely to > cause segfaults or memory corruptions which are even worse than the > exit calls(). > > A2) Set up an error flag in PLStream which can be set on error and > checked after every function call. This would avoid having to change > functions that already return values, but still relies on manual > checks which I think will be a big weak point. > > A3) Use setjmp/longjmp calls. In this case we call setjmp in the top > level of every API call and on error we call longjmp which returns the > execution point back to the point setjmp was called. There is some > extra setup time here to avoid memory leaks and other resource leaks, > but once that is done we can all write code with almost no worry > regarding error propagation. > My vote is for option A1 or A2. If the developer does not want to handle errors, then it might not be important. I think getting all the unwiding done right for the setjmp/longjmp will need a lot of work. The A2 option mimics the style used in the libc library, so it is a familar paradigm to developers. > Once we decide on our internal method we need to decide how we can > inform the user. We have a number of options again: > > B1) An API change so that all our functions return an error code. > > B2) Make use of our current plabort call and let the user pass in a > plabort handler. > > B3) If we have an error, store an error code in PLStream and add an > API function called plgeterr or similar which allows the user to check > for error after any other function call. > > B4) In the C++ binding we could throw an error. Not sure if other > languages have similar throw/catch style options. > > B4) Some combination of the above. > > I will add there are some specific things we need to think about for > our C++ drivers. These are not so much options, but things we need to > deal with anyway. > > C1) Our C++ drivers cannot be allowed to throw an error out of the > driver code and into the main C code. That would potentially end up > with the throw going all the way out to the user's top level code > which may be in C, Fortran, or any other language that can't deal with > it. Note that even if the driver doesn't call throw, it may call > either something in the stl or another driver (in Qt or wxWidgets for > example) that does throw. This is easy to avoid by wrapping the intry > points in try blocks. I have done this for wxWidgets, but haven't > checked the other C++ drivers to see if they are the same. > > C2) If we go for option A3, then we cannot allow longjmp over C++ > code. This is because nontrivial destructors are not called when > longjmp is called and if objects with these destructors are jumped > over then the result is undefined behaviour - which again is worse > than exit calls. > > The fix for C2 - and I think this would be a good thing anyway - would > be to have a specific driver API. This would allow us to have setjmp > calls when we enter that API and avoid jumping over drivers. I think > this would be nice in general as it is not well documented how to > write a driver and a proper driver API would address that. > > I am well aware that the use of setjmp and longjmp is very divisive. > So my intention is to work this code up only for the case of memory > allocation failures. This code will consist of: > D2)A set of plmalloc, plrealloc and plfree fuctions which will replace > the usual versions. As well as allocating/freeing memory these > functions will record the allocations in the PLstream. > D1)PLTRY, PLENDTRY macros which will go in each API call. PLTRY will > have the setjmp call. This will be followed by the current code in the > function as it is now then PLENDTRY will deal with what happens if > longjmp has been called - it will check for memory allocations > recorded in the PLStream and will free them. For now it will then just > call exit() so we get the same behaviour but this can be changed later > if we want to go down this route. Once we have this first look at how > setjmp/longjmp can work in our code then I think it will be easier for > us to make an informed choice about the A options. > > Does that sound sensible to people? If anyone would like to look at > what would be involved in doing a similar thing using the other > options then it would be really nice to be able to compare the work > and admin/code practices needed for those too. > > Phil > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, SlashDot.org! http://sdm.link/slashdot > _______________________________________________ > Plplot-devel mailing list > Plplot-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/plplot-devel ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel