Skip to content

Commit

Permalink
Merge pull request EOSIO#7743 from EOSIO/fix-db-exhaustion-1.8.x
Browse files Browse the repository at this point in the history
Fix db exhaustion - 1.8.x
  • Loading branch information
heifner authored Aug 9, 2019
2 parents 163fa86 + 4c71fe5 commit 3f16468
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 33 deletions.
11 changes: 9 additions & 2 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,10 @@ struct controller_impl {
template<typename Signal, typename Arg>
void emit( const Signal& s, Arg&& a ) {
try {
s(std::forward<Arg>(a));
s( std::forward<Arg>( a ));
} catch (std::bad_alloc& e) {
wlog( "std::bad_alloc" );
throw e;
} catch (boost::interprocess::bad_alloc& e) {
wlog( "bad alloc" );
throw e;
Expand Down Expand Up @@ -1495,13 +1498,17 @@ struct controller_impl {
});
in_trx_requiring_checks = true;
push_transaction( onbtrx, fc::time_point::maximum(), self.get_global_properties().configuration.min_transaction_cpu_usage, true );
} catch( const boost::interprocess::bad_alloc& e ) {
} catch( const std::bad_alloc& e ) {
elog( "on block transaction failed due to a std::bad_alloc" );
throw;
} catch( const boost::interprocess::bad_alloc& e ) {
elog( "on block transaction failed due to a bad allocation" );
throw;
} catch( const fc::exception& e ) {
wlog( "on block transaction failed, but shouldn't impact block generation, system contract needs update" );
edump((e.to_detail_string()));
} catch( ... ) {
elog( "on block transaction failed due to unknown exception" );
}

clear_expired_input_transactions();
Expand Down
18 changes: 16 additions & 2 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1239,7 +1239,7 @@ fc::microseconds chain_plugin::get_abi_serializer_max_time() const {
return my->abi_serializer_max_time_ms;
}

void chain_plugin::log_guard_exception(const chain::guard_exception&e ) const {
void chain_plugin::log_guard_exception(const chain::guard_exception&e ) {
if (e.code() == chain::database_guard_exception::code_value) {
elog("Database has reached an unsafe level of usage, shutting down to avoid corrupting the database. "
"Please increase the value set for \"chain-state-db-size-mb\" and restart the process!");
Expand All @@ -1251,7 +1251,7 @@ void chain_plugin::log_guard_exception(const chain::guard_exception&e ) const {
dlog("Details: ${details}", ("details", e.to_detail_string()));
}

void chain_plugin::handle_guard_exception(const chain::guard_exception& e) const {
void chain_plugin::handle_guard_exception(const chain::guard_exception& e) {
log_guard_exception(e);

// quit the app
Expand All @@ -1264,6 +1264,12 @@ void chain_plugin::handle_db_exhaustion() {
std::_Exit(1);
}

void chain_plugin::handle_bad_alloc() {
elog("std::bad_alloc - memory exhausted");
//return -2 -- it's what programs/nodeos/main.cpp reports for std::exception
std::_Exit(-2);
}

namespace chain_apis {

const string read_only::KEYi64 = "i64";
Expand Down Expand Up @@ -1885,6 +1891,8 @@ void read_write::push_block(read_write::push_block_params&& params, next_functio
next(read_write::push_block_results{});
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
} catch ( const std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} CATCH_AND_CALL(next);
}

Expand Down Expand Up @@ -1966,6 +1974,8 @@ void read_write::push_transaction(const read_write::push_transaction_params& par
});
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
} catch ( const std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} CATCH_AND_CALL(next);
}

Expand Down Expand Up @@ -2000,6 +2010,8 @@ void read_write::push_transactions(const read_write::push_transactions_params& p
push_recurse(this, 0, params_copy, result, next);
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
} catch ( const std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} CATCH_AND_CALL(next);
}

Expand Down Expand Up @@ -2035,6 +2047,8 @@ void read_write::send_transaction(const read_write::send_transaction_params& par
});
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
} catch ( const std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} CATCH_AND_CALL(next);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,11 +715,11 @@ class chain_plugin : public plugin<chain_plugin> {
chain::chain_id_type get_chain_id() const;
fc::microseconds get_abi_serializer_max_time() const;

void handle_guard_exception(const chain::guard_exception& e) const;

static void handle_guard_exception(const chain::guard_exception& e);
static void handle_db_exhaustion();
static void handle_bad_alloc();
private:
void log_guard_exception(const chain::guard_exception& e) const;
static void log_guard_exception(const chain::guard_exception& e);

unique_ptr<class chain_plugin_impl> my;
};
Expand Down
71 changes: 45 additions & 26 deletions plugins/producer_plugin/producer_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,30 @@ using std::vector;
using std::deque;
using boost::signals2::scoped_connection;

#undef FC_LOG_AND_DROP
#define LOG_AND_DROP() \
catch ( const guard_exception& e ) { \
chain_plugin::handle_guard_exception(e); \
} catch ( const std::bad_alloc& ) { \
chain_plugin::handle_bad_alloc(); \
} catch ( boost::interprocess::bad_alloc& ) { \
chain_plugin::handle_db_exhaustion(); \
} catch( fc::exception& er ) { \
wlog( "${details}", ("details",er.to_detail_string()) ); \
} catch( const std::exception& e ) { \
fc::exception fce( \
FC_LOG_MESSAGE( warn, "std::exception: ${what}: ",("what",e.what()) ), \
fc::std_exception_code,\
BOOST_CORE_TYPEID(e).name(), \
e.what() ) ; \
wlog( "${details}", ("details",fce.to_detail_string()) ); \
} catch( ... ) { \
fc::unhandled_exception e( \
FC_LOG_MESSAGE( warn, "unknown: ", ), \
std::current_exception() ); \
wlog( "${details}", ("details",e.to_detail_string()) ); \
}

const fc::string logger_name("producer_plugin");
fc::logger _log;

Expand Down Expand Up @@ -354,14 +378,15 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
try {
chain.push_block( bsf );
} catch ( const guard_exception& e ) {
chain_plug->handle_guard_exception(e);
chain_plugin::handle_guard_exception(e);
return;
} catch( const fc::exception& e ) {
elog((e.to_detail_string()));
except = true;
} catch ( const std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
return;
}

if( except ) {
Expand Down Expand Up @@ -483,9 +508,11 @@ class producer_plugin_impl : public std::enable_shared_from_this<producer_plugin
}

} catch ( const guard_exception& e ) {
chain_plug->handle_guard_exception(e);
chain_plugin::handle_guard_exception(e);
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
} catch ( std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} CATCH_AND_CALL(send_response);
}

Expand Down Expand Up @@ -745,13 +772,13 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_
my->_incoming_block_subscription = app().get_channel<incoming::channels::block>().subscribe([this](const signed_block_ptr& block){
try {
my->on_incoming_block(block);
} FC_LOG_AND_DROP();
} LOG_AND_DROP();
});

my->_incoming_transaction_subscription = app().get_channel<incoming::channels::transaction>().subscribe([this](const transaction_metadata_ptr& trx){
try {
my->on_incoming_transaction_async(trx, false, [](const auto&){});
} FC_LOG_AND_DROP();
} LOG_AND_DROP();
});

my->_incoming_block_sync_provider = app().get_method<incoming::methods::block_sync>().register_provider([this](const signed_block_ptr& block){
Expand Down Expand Up @@ -1358,7 +1385,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
}

chain.start_block( block_time, blocks_to_confirm, features_to_activate );
} FC_LOG_AND_DROP();
} LOG_AND_DROP();

if( chain.is_building_block() ) {
auto pending_block_time = chain.pending_block_time();
Expand Down Expand Up @@ -1483,10 +1510,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
} else {
++num_applied;
}
} catch ( const guard_exception& e ) {
chain_plug->handle_guard_exception(e);
return start_block_result::failed;
} FC_LOG_AND_DROP();
} LOG_AND_DROP();
}

itr = itr_next;
Expand Down Expand Up @@ -1597,10 +1621,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
} else {
num_applied++;
}
} catch ( const guard_exception& e ) {
chain_plug->handle_guard_exception(e);
return start_block_result::failed;
} FC_LOG_AND_DROP();
} LOG_AND_DROP();

_incoming_trx_weight += _incoming_defer_ratio;
if (!orig_pending_txn_size) _incoming_trx_weight = 0.0;
Expand All @@ -1620,6 +1641,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {

}

if( app().is_quiting() ) // db guard exception above in LOG_AND_DROP could have called app().quit()
return start_block_result::failed;
if (exhausted || preprocess_deadline <= fc::time_point::now()) {
return start_block_result::exhausted;
} else {
Expand All @@ -1639,9 +1662,13 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() {
return start_block_result::succeeded;
}

} catch ( const guard_exception& e ) {
chain_plugin::handle_guard_exception(e);
return start_block_result::failed;
} catch ( std::bad_alloc& ) {
chain_plugin::handle_bad_alloc();
} catch ( boost::interprocess::bad_alloc& ) {
chain_plugin::handle_db_exhaustion();
return start_block_result::failed;
}

}
Expand Down Expand Up @@ -1763,17 +1790,9 @@ bool producer_plugin_impl::maybe_produce_block() {
});

try {
try {
produce_block();
return true;
} catch ( const guard_exception& e ) {
chain_plug->handle_guard_exception(e);
return false;
} FC_LOG_AND_DROP();
} catch ( boost::interprocess::bad_alloc&) {
raise(SIGUSR1);
return false;
}
produce_block();
return true;
} LOG_AND_DROP();

fc_dlog(_log, "Aborting block due to produce_block error");
chain::controller& chain = chain_plug->chain();
Expand Down

0 comments on commit 3f16468

Please sign in to comment.