Hi John, There are two issues involved with exceptions and ROOT. You've identified one of them, which is getting rudimentary support for exceptions to "Do the Right Thing" with regards to the interpreter/compiled-code barrier. The other issue is exception safety w.r.t. the ROOT libraries themselves. Both of your proposed solutions address the first issue, and sound reasonable to me (i.e. both your "stop-gap" solution and your "elegant" solution). I experimented with ROOT and exceptions in the past (I believe it was with ROOT 2.22.x) and I made local changes to the ROOT source similar to what you are proposing (I used function try blocks instead of just try blocks). This "worked" for me, but I quickly found that the ROOT libraries themselves weren't exception safe. In particular I found several instances when an exception propagating through parts of the ROOT libraries would corrupt the local state of ROOT objects. As you may know, this is typical of libraries that haven't been designed for exception safety, and so is not just particular to ROOT. Perhaps ROOT 2.23.x is exception safe, but I haven't checked. There is nothing in the ROOT Release Notes about an exception audit, so I doubt that this issue has been addressed yet. Until it is, I would just offer a general warning that if users use exceptions with ROOT, then they should insure that exceptions not propagate through any part of the ROOT libraries. If they do, there are two possibilities: 1) The state of all ROOT objects is good. 2) The state of some or all ROOT objects are corrupt. The trouble is, you can't know unless you have looked at the ROOT source. -- Matthew D. Langston SLD, Stanford Linear Accelerator Center langston@SLAC.Stanford.EDU John Zweizig wrote: > > I'd like to revisit a previous the root-talk thread on exception > handling. In that thread one root user pointed out that any exception > thrown by a compiled function will cause root to terminate. I have just > run into the same problem and I agree that this is an unusually annoying > feature. At the time of the previous thread, there were two responses, one > from Fons and the other from Masa as follows: > 1) Fons added some code to TSystem::Run() which attempted to catch > exceptions at that level and restart the application. This doesn't > work for compiled functions called by the interpreter. I believe that > the reason it doesn't work is that CINT is written/compiled in C, so > the exceptions can't propagate up the stack past CINT. > > 2) Masa stated that problems implicit in the C++ definition make it > impossible to catch exceptions from compiled functions in the > interpreter. > > I think that in fact what is needed is not the handling of the exceptions > per se, but rather some stop-gap to prevent root from terminating if an > exception is thrown by a compiled function being interpreted. I believe > that this is possible and that it can be implemented in one of two ways. > > The most trivial way would be to put an additional layer between cint and > the compiled function, as follows: > > Right now Cint call compiled C++ functions in > > int G__call_cppfunc(...) { > --- stuff snipped --- > (*cppfun)(...); > --- stuff snipped > } > > The additional C++ layer could be added as follows: > > int G__call_cppfunc(...) { > --- stuff snipped --- > if (G__cpp_stopgap(cppfun, ...)) { > ---- function failed... stop interpreting --- > } > --- stuff snipped > } > > where G__cpp_stopgap must be a C++ function like: > > extern "C" { > typedef int (cppwrap)(G__value*, char*, G__param*, int); > > int > G__cpp_stopgap(cppwrap* cppfunc, G__value* a, char* b, G__param* c, int d) { > try { > (*cppfunc)(a, b, c, d); > return 0; > } catch (...) { > return 1; > } > } > } > > A more elegant way of handling the exceptions would be to put the > try...catch code into the cint wrappers themselves based on the throw() > clause of the function definition.
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:42 MET