From: Mikko Rasa Date: Wed, 7 May 2014 20:26:13 +0000 (+0300) Subject: Avoid segfault if an exception is thrown while loading X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=02c12263ac40289afc626156358ebb705ed84a5b;p=r2c2.git Avoid segfault if an exception is thrown while loading The Layout::add functions are called from object constructors. If an exception is thrown inside them, the constructor will abort and the object will be deleted. If that happens, it must be removed from the Layout as well, or an invalid memory access will occur later. --- diff --git a/source/libr2c2/layout.cpp b/source/libr2c2/layout.cpp index 0901382..af7304d 100644 --- a/source/libr2c2/layout.cpp +++ b/source/libr2c2/layout.cpp @@ -69,31 +69,69 @@ Driver &Layout::get_driver() const void Layout::add(Object &o) { if(objects.insert(o)) - signal_object_added.emit(o); + { + try + { + signal_object_added.emit(o); + } + catch(...) + { + objects.erase(o); + throw; + } + } } void Layout::add(Track &t) { if(objects.insert(t)) { - // Blocks must be recreated first - create_blocks(); - signal_object_added.emit(t); + try + { + // Blocks must be recreated first + create_blocks(); + signal_object_added.emit(t); + } + catch(...) + { + objects.erase(t); + create_blocks(); + throw; + } } } void Layout::add(TrackChain &g) { if(track_chains.insert(g)) - signal_track_chain_added.emit(g); + { + try + { + signal_track_chain_added.emit(g); + } + catch(...) + { + track_chains.erase(g); + throw; + } + } } void Layout::add(Block &b) { if(track_chains.insert(b)) { - b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b))); - signal_track_chain_added.emit(b); + sigc::connection conn = b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b))); + try + { + signal_track_chain_added.emit(b); + } + catch(...) + { + track_chains.erase(b); + conn.disconnect(); + throw; + } } }