1 / 16

Proposal

Proposal. Add two special exceptions/return codes Result:: error (“errtype”) throw fwk::UserError(“errtype”,”description”) Result:: inputsNotSatisfied (“errtype”); throw fwk::UserInputsError(“errtype”,”desc”) Action taken specified in RCP By package name

bardia
Download Presentation

Proposal

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Proposal • Add two special exceptions/return codes • Result::error(“errtype”) • throw fwk::UserError(“errtype”,”description”) • Result::inputsNotSatisfied(“errtype”); • throw fwk::UserInputsError(“errtype”,”desc”) • Action taken specified in RCP • By package name • By Result type (error or inputsNotSatified) • By “errtype” string (user defined error code)

  2. Interals • Introduce set of framework actions • AbortPackageError (skip only this package) • AbortGroupError (skip all in hook group) • AbortEventError (skip further processing) • AbortJob (stops execution completely) • Actions taken by framework specified using RCP settings. • Each package/error/user error type can have associated framework action.

  3. Framework RCP Example Framework.rcp string Packages=“read hits clusters tracks” RCP read = < example readevents> RCP hits = < example findhits > RCP clusters = < example locateclusters > RCP tracks = < example findtracks > string hits_error ( too_little_data AbortGroup ) string hits_input ( missing_data AbortPackage ) string default_error ( invalid_reading AbortPackage ) string default_input ( no_raw_data AbortEvent ) string any_error “AbortPackage” string any_input “AbortPackage”

  4. Current Method in Framework try { current_pkg->processEvent(Event); } catch (const std::exception& e) { … } catch(const XRCP& e) { … } Any exception causes the framework to stop execution. Text from the exception and context information are printed.

  5. User Package (Observed) Fwk::Result processEvent(edm::Event& e) { algorithm(e); return Result::success;} int algorithm(edm::Event& e) { … do stuff … if(error or bad) { return -1; else return 0; }

  6. Problem Area Example Void func() { Clusters* x = new Clusters; } If new throw a “bad_alloc” exception, it is caught by the framework because not everyone catches this type of std::exception. The exact location of the exception throw is not known (core file stack information will not contain it).

  7. Not Catching Exceptions • Stack may be intact, indicating where it was originally thrown. • Other information (objects) in core file not reliable • Algorithms should handle exceptions and abort the program if necessary to get a reliable core dump. • With rethrows, stack will be where rethrow occurred

  8. More About Exceptions • The exception facility is not meant to be an excuse for not handling error in an algorithm. • Blocks of code should be fitted with try/catch blocks, especially where resources are being acquired such as memory. • Algorithm should throw exceptions when they cannot continue processing normally.

  9. Destructors and Exceptions struct thing { int value; } void func1(int x) { thing t; <- destroyed before abort throw runtime_error(“bad”); } void func0(int x) { auto_ptr<thing> t(new thing); <- destroyed before abort func1(x); } int main() { auto_ptr<thing> t(new thing); <- destroyed before abort func0(10);}

  10. Conclusion • No work has been completed • Does not solve the stack problem in core file • Does not solve the problem of handling exception from the standard library

  11. Discussion Question: Should users be throwing exceptions or passing return codes? It has been said that use of return code is easier because users do not need to write exception safe code everywhere. Routines that use exceptions and are not exception safe can leak memory when an exception is thrown. Is there a similar problem when return codes are rippled up? I claim that there is.

  12. Problem Areas ObjA* makeObjA(const Info* x) { ObjA* a = new ObjA(x); // can be leaked if(bad info in a) throw AbortPackage(“bad info in makeObjA”); return a; } ObjB* makeObjB(const Info* x) { ObjA* a = makeObjA(x); // a owns x ObjB* b = new ObjB(a); // b owns g (can be leaked) if(bad info in b) throw AbortPackage(“bad ObjB in makeObjB”); return b;} void doWork() { Info* x = new Info(…); // can be leaked ObjB* b = makeObjB(x); // b owns x … do stuff with b … delete b; } If return code used, you are subject to the same leaks.

  13. Doing it More Correctly? std::auto_ptr<ObjA> makeObjA(std::auto_ptr<Info> x) { std::auto_ptr<ObjA> a(new ObjA(x)); if(bad info in a) throw AbortPackage(“bad info in makeObjA”); return a; } // or ObjA* makeObjA(Info* x) { ObjA* a = 0; try { a = new ObjA(x); } catch(…) { delete x; throw; } if(bad info in a){ delete a; return 0; } return a; }

  14. Continued... std::auto_ptr<ObjB> makeObjB(std::auto_ptr<Info> x) { std::auto_ptr<ObjA> a(makeObjA(x)); std::auto_ptr<ObjB> b(new ObjB(a)); if(bad info in b) throw AbortPackage(“bad ObjB in makeObjB”); return b;} // or ObjB* makeObjB(const Info* x) { ObjA* a = 0; try { a = makeObjA(x); } catch(…) { delete x; throw; } if (a==0) return 0; ObjB* b = 0; try { b = new ObjB(a); } catch(…) { delete a; throw; } if(bad info in b) { delete b; // assume b owns a return 0; } return b;}

  15. Notes • If more then one object created, then the code becomes significantly worse • Return code use in code is ugly, because they must be checked everywhere. • With return codes, you must guarantee one return point or a set of known return points from every routine. • How do you guarantee that constuctors of objects (or methods) do not throw? • Cannot simply return from anywhere is a routine, cleanup must usually be done in any objects are allocated from heap.

  16. More Complex MakeObjB ObjB* makeObjB(const Info* x) { ObjA* a = 0; Guts* g = 0; try{ g = new Guts(x); } catch(…) { delete x; throw; } try { a = makeObjA(x); } catch(…) { delete x; delete g; throw; } if (a==0) { delete g; return 0; } ObjB* b = 0; try { b = new ObjB(a,g); } catch(…) { delete a; delete g; throw; } if(bad info in b) { delete b; // b owns a,g return 0; } return b;}

More Related