Hi Hazen The approach of just don't call exit and see what happens was also my first thought. Then the first case i looked at was plscmap0n, which attempts to set the number of colours in cmap0, this is called by plspal0, which immediately assumes the call has succeeded and attempts to assign colours to cmap0. If the malloc call actually failed, then the memory is set to null and we'll get a segfault.
I'm not sure what all those libraries do, but I think most of them are C++, so they probably throw exceptions. Actually this could be even worse, because we probably dont catch them. I think if the calling program is C++ the throw could be caught, but it might leave a memory leak, or leave the plstream in some odd state which could cause an error later during running. Or if the caller is using C or another language which doesn't have exceptions I guess it causes a crash. But yes, you are right that the throw method in c++ is really great for dealing with errors. If it interests you at all try reading Milewski's C++in action, it is my bible for this kind of thing. It is a bit dated in terms of the std library now c++11 is out, but the principles are still sound. I think for c based libraries there is a split. From memory, libcurl returns error codes, but most of the windows api returns pointers or handles and require a call to a getlasterror type function if the return value is null. The important thing is that the errors can propagate back so that each function call is able to be checked an if an error has occurred so it can be passed back out. If we return errors, the highest negative i thought was that all the api functions would need to be changed. This means changing every function for every binding, which is a lot of work. I guess the alternative would be to forbid calling the api functions internally and have an internal version for each one, which returns an error code. I'm not sure that having a getlasterror function is much easier, but at least it doesn't introduce a rule about calling api functions. It's a bit of a rock and hard place situation. I guess it is why they introduced exceptions in c++. Phil -----Original Message----- From: "Hazen Babcock" <hbabc...@mac.com> Sent: 14/08/2014 20:27 To: "plplot-devel@lists.sourceforge.net" <plplot-devel@lists.sourceforge.net> Subject: Re: [Plplot-devel] exit() calls > > Hi All > I have had the exit() calls in Plplot rolling around in the back of my head > for a while. They were brought to the fore, recently when I had some code > which generated a lot of plots and displayed them all via wxWidgets - except > it didn't. The program exited half way through. It turned out that I ran out > of memory and this caused a call to plexit which exited my code without even > an unhandled exception error, which is what I usually expect with out of > memory problems. Also the move to git has got me excited about doing some > work. > > Obviously the API functions do not return an error code, but we do have the > plserror function which allows us to report errors back to the user. The > difficulty however is more internal. If the program runs out of memory, but > we allow things to continue, then when attempts are made to access the array > then we'll get a segfault or similar crash. > > As far as I can see we have two solutions: > 1) Change all internal functions so they return an error code. If another > internal function finds it is passed an error code then in must clean up and > return this error code - which passes down the chain. This sounds quite > difficult as some functions already return values. Also if an internal > function calls an API function we break the chain. > 2) Add an internalerrorcode variable to PLStream. This is reset to 0 when an > API call is made, and if a function generates an error then this code and the > user's code) get set and the calling function can check this. The downside > here is probably a lot of error checking, but?I don't think this can be > helped. > > I'm in favour of 2), mostly because I haven't thought of any killer problems > like 1). Has anyone got any thoughts before I start working on this? What fraction of the functions would have to changed for (1)? Glancing through the API it seems that only a small fraction of them return a value. I would guess that most of the work is going to be doing all the error checking, which is likely more or less the same for either (1) or (2). I thought (1) was the approach that most libraries used, but looking at the Cairo, Gtk, WxWidgets and Qt libraries it appears that they do not use either. Qt and WxWidgets probably throw more or less meaningful exceptions. I'm not sure what Cairo and GTK would do, maybe they just segfault? How about the minimalist change of just removing the exit() from plexit()? Yes the program will continue to run, but a modern OS can pretty easily deal with any trouble it is likely to cause. And if the user really wants the exit behavior then they can implement it in their own exit handler. -Hazen ------------------------------------------------------------------------------ _______________________________________________ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel
------------------------------------------------------------------------------
_______________________________________________ Plplot-devel mailing list Plplot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/plplot-devel