From fff238ec94ac6d45fc18c315d7bc590ddfaad63d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 19 Mar 2016 21:48:36 +0000 Subject: Print stack trace upon exceptions Useful for debugging users' logs --- src/daemon/command_server.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/daemon/command_server.cpp') diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 206de9d4a..7e5139636 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -26,6 +26,7 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "common/exception.h" #include "cryptonote_config.h" #include "version.h" #include "daemon/command_server.h" -- cgit v1.2.3 From f7301c3563e7ae19b8d7c65d8bc88f3c42eefc09 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 21 Mar 2016 10:12:12 +0000 Subject: Revert "Print stack trace upon exceptions" Ain't nobody got time for link/cmake skullduggery. This reverts commit fff238ec94ac6d45fc18c315d7bc590ddfaad63d. --- CMakeLists.txt | 12 ---- cmake/FindLibunwind.cmake | 25 ------- contrib/epee/include/misc_log_ex.h | 2 +- contrib/epee/include/net/abstract_tcp_server2.inl | 2 +- .../include/storages/portable_storage_from_bin.h | 4 +- src/blockchain_db/blockchain_db.h | 3 +- src/blockchain_utilities/blockchain_export.cpp | 2 +- src/blockchain_utilities/blockchain_import.cpp | 6 +- src/blockchain_utilities/bootstrap_file.cpp | 44 ++++++------ src/blockchain_utilities/fake_core.h | 4 +- src/common/CMakeLists.txt | 3 - src/common/exception.cpp | 84 ---------------------- src/common/exception.h | 53 -------------- src/cryptonote_core/blockchain_storage.h | 3 +- src/cryptonote_core/checkpoints_create.cpp | 1 - src/cryptonote_core/cryptonote_core.cpp | 2 +- src/cryptonote_core/cryptonote_core.h | 1 - src/cryptonote_core/miner.cpp | 1 - .../cryptonote_protocol_handler.h | 1 - src/daemon/command_parser_executor.cpp | 1 - src/daemon/command_server.cpp | 1 - src/daemon/daemon.cpp | 6 +- src/daemon/p2p.h | 2 +- src/daemon/protocol.h | 2 +- src/daemon/rpc.h | 4 +- src/daemon/rpc_command_executor.cpp | 3 +- src/daemonizer/posix_fork.cpp | 3 +- src/miner/simpleminer.cpp | 1 - src/p2p/data_logger.cpp | 7 +- src/simplewallet/simplewallet.cpp | 2 +- src/wallet/wallet2.cpp | 5 +- src/wallet/wallet2.h | 1 - src/wallet/wallet2_api.cpp | 1 - tests/core_proxy/core_proxy.h | 2 +- tests/core_tests/chaingen.cpp | 12 ++-- tests/core_tests/chaingen.h | 6 +- tests/core_tests/tx_validation.cpp | 2 +- tests/net_load_tests/clt.cpp | 1 - tests/net_load_tests/srv.cpp | 1 - tests/unit_tests/ban.cpp | 2 +- tests/unit_tests/epee_boosted_tcp_server.cpp | 2 +- tests/unit_tests/mnemonics.cpp | 1 - tests/unit_tests/test_protocol_pack.cpp | 1 - 43 files changed, 63 insertions(+), 259 deletions(-) delete mode 100644 cmake/FindLibunwind.cmake delete mode 100644 src/common/exception.cpp delete mode 100644 src/common/exception.h (limited to 'src/daemon/command_server.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index ea1d5d7e5..9674404bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,14 +243,6 @@ endif() add_definitions("-DBLOCKCHAIN_DB=${BLOCKCHAIN_DB}") -find_package(Libunwind) -if(LIBUNWIND_FOUND) - message(STATUS "Using libunwind to provide stack traces") - add_definitions("-DHAVE_LIBUNWIND") -else() - message(STATUS "Stack traces disabled") -endif() - if (UNIX AND NOT APPLE) # Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -282,10 +274,6 @@ if (BERKELEY_DB) include_directories(${BDB_INCLUDE}) endif() -# Final setup for libunwind -include_directories(${LIBUNWIND_INCLUDE}) -link_directories(${LIBUNWIND_LIBRARY_DIRS}) - if(MSVC) add_definitions("/bigobj /MP /W3 /GS- /D_CRT_SECURE_NO_WARNINGS /wd4996 /wd4345 /D_WIN32_WINNT=0x0600 /DWIN32_LEAN_AND_MEAN /DGTEST_HAS_TR1_TUPLE=0 /FIinline_c.h /D__SSE4_1__") # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline") diff --git a/cmake/FindLibunwind.cmake b/cmake/FindLibunwind.cmake deleted file mode 100644 index 9946e7cdd..000000000 --- a/cmake/FindLibunwind.cmake +++ /dev/null @@ -1,25 +0,0 @@ -# - Try to find libunwind -# Once done this will define -# -# LIBUNWIND_FOUND - system has libunwind -# LIBUNWIND_INCLUDE_DIR - the libunwind include directory -# LIBUNWIND_LIBRARIES - Link these to use libunwind -# LIBUNWIND_DEFINITIONS - Compiler switches required for using libunwind - -# Copyright (c) 2006, Alexander Dymo, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -find_path(LIBUNWIND_INCLUDE_DIR libunwind.h - /usr/include - /usr/local/include -) - -find_library(LIBUNWIND_LIBRARIES NAMES unwind ) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Libunwind "Could not find libunwind" LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES) -# show the LIBUNWIND_INCLUDE_DIR and LIBUNWIND_LIBRARIES variables only in the advanced view -mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES ) - diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 58d47c472..d1451ff12 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -1426,7 +1426,7 @@ POP_WARNINGS #define CATCH_ENTRY_L4(lacation, return_val) CATCH_ENTRY(lacation, return_val) -#define ASSERT_MES_AND_THROW(message) {LOG_ERROR(message); std::stringstream ss; ss << message; throw tools::runtime_error(ss.str());} +#define ASSERT_MES_AND_THROW(message) {LOG_ERROR(message); std::stringstream ss; ss << message; throw std::runtime_error(ss.str());} #define CHECK_AND_ASSERT_THROW_MES(expr, message) {if(!(expr)) ASSERT_MES_AND_THROW(message);} diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 2f6e52a5b..1c854dfb7 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -777,7 +777,7 @@ POP_WARNINGS { m_thread_name_prefix = prefix_name; auto it = server_type_map.find(m_thread_name_prefix); - if (it==server_type_map.end()) throw tools::runtime_error("Unknown prefix/server type:" + std::string(prefix_name)); + if (it==server_type_map.end()) throw std::runtime_error("Unknown prefix/server type:" + std::string(prefix_name)); auto connection_type = it->second; // the value of type _info_c("net/RPClog", "Set server type to: " << connection_type << " from name: " << m_thread_name_prefix); _info_c("net/RPClog", "prefix_name = " << prefix_name); diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/storages/portable_storage_from_bin.h index 4cb2003e0..bc2fb1463 100644 --- a/contrib/epee/include/storages/portable_storage_from_bin.h +++ b/contrib/epee/include/storages/portable_storage_from_bin.h @@ -84,9 +84,9 @@ namespace epee inline throwable_buffer_reader::throwable_buffer_reader(const void* ptr, size_t sz) { if(!ptr) - throw tools::runtime_error("throwable_buffer_reader: ptr==nullptr"); + throw std::runtime_error("throwable_buffer_reader: ptr==nullptr"); if(!sz) - throw tools::runtime_error("throwable_buffer_reader: sz==0"); + throw std::runtime_error("throwable_buffer_reader: sz==0"); m_ptr = (uint8_t*)ptr; m_count = sz; m_recursion_count = 0; diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index b9db6d196..3396b8c20 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -33,7 +33,6 @@ #include #include #include -#include "common/exception.h" #include "crypto/hash.h" #include "cryptonote_core/cryptonote_basic.h" #include "cryptonote_core/difficulty.h" @@ -152,7 +151,7 @@ struct output_data_t /*********************************** * Exception Definitions ***********************************/ -class DB_EXCEPTION : public tools::exception +class DB_EXCEPTION : public std::exception { private: std::string m; diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 4c5e5fd02..964c610cd 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -198,7 +198,7 @@ int main(int argc, char* argv[]) else { LOG_ERROR("Attempted to use non-existent database type: " << db_type); - throw tools::runtime_error("Attempting to use non-existent database type"); + throw std::runtime_error("Attempting to use non-existent database type"); } LOG_PRINT_L0("database: " << db_type); diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 43f6af6d5..1aaf2bddc 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -359,14 +359,14 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, str1.assign(buffer1, sizeof(chunk_size)); if (! ::serialization::parse_binary(str1, chunk_size)) { - throw tools::runtime_error("Error in deserialization of chunk size"); + throw std::runtime_error("Error in deserialization of chunk size"); } LOG_PRINT_L3("chunk_size: " << chunk_size); if (chunk_size > BUFFER_SIZE) { LOG_PRINT_L0("WARNING: chunk_size " << chunk_size << " > BUFFER_SIZE " << BUFFER_SIZE); - throw tools::runtime_error("Aborting: chunk size exceeds buffer size"); + throw std::runtime_error("Aborting: chunk size exceeds buffer size"); } if (chunk_size > 100000) { @@ -406,7 +406,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path, str1.assign(buffer_block, chunk_size); bootstrap::block_package bp; if (! ::serialization::parse_binary(str1, bp)) - throw tools::runtime_error("Error in deserialization of chunk"); + throw std::runtime_error("Error in deserialization of chunk"); int display_interval = 1000; int progress_interval = 10; diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index 247709f57..da3b44593 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -117,7 +117,7 @@ bool BootstrapFile::initialize_file() std::string blob; if (! ::serialization::dump_binary(file_magic, blob)) { - throw tools::runtime_error("Error in serialization of file magic"); + throw std::runtime_error("Error in serialization of file magic"); } *m_raw_data_file << blob; @@ -143,7 +143,7 @@ bool BootstrapFile::initialize_file() if (! ::serialization::dump_binary(bd_size, blob)) { - throw tools::runtime_error("Error in serialization of bootstrap::file_info size"); + throw std::runtime_error("Error in serialization of bootstrap::file_info size"); } *output_stream_header << blob; *output_stream_header << bd; @@ -154,7 +154,7 @@ bool BootstrapFile::initialize_file() if (! ::serialization::dump_binary(bd_size, blob)) { - throw tools::runtime_error("Error in serialization of bootstrap::blocks_info size"); + throw std::runtime_error("Error in serialization of bootstrap::blocks_info size"); } *output_stream_header << blob; *output_stream_header << bd; @@ -181,7 +181,7 @@ void BootstrapFile::flush_chunk() std::string blob; if (! ::serialization::dump_binary(chunk_size, blob)) { - throw tools::runtime_error("Error in serialization of chunk size"); + throw std::runtime_error("Error in serialization of chunk size"); } *m_raw_data_file << blob; @@ -197,7 +197,7 @@ void BootstrapFile::flush_chunk() if (static_cast(num_chars_written) != chunk_size) { LOG_PRINT_RED_L0("Error writing chunk: height: " << m_cur_height << " chunk_size: " << chunk_size << " num chars written: " << num_chars_written); - throw tools::runtime_error("Error writing chunk"); + throw std::runtime_error("Error writing chunk"); } m_buffer.clear(); @@ -221,7 +221,7 @@ void BootstrapFile::write_block(block& block) { if (tx_id == null_hash) { - throw tools::runtime_error("Aborting: tx == null_hash"); + throw std::runtime_error("Aborting: tx == null_hash"); } #if SOURCE_DB == DB_MEMORY const transaction* tx = m_blockchain_storage->get_tx(tx_id); @@ -233,14 +233,14 @@ void BootstrapFile::write_block(block& block) if(tx == NULL) { if (! m_tx_pool) - throw tools::runtime_error("Aborting: tx == NULL, so memory pool required to get tx, but memory pool isn't enabled"); + throw std::runtime_error("Aborting: tx == NULL, so memory pool required to get tx, but memory pool isn't enabled"); else { transaction tx; if(m_tx_pool->get_transaction(tx_id, tx)) txs.push_back(tx); else - throw tools::runtime_error("Aborting: tx not found in pool"); + throw std::runtime_error("Aborting: tx not found in pool"); } } else @@ -362,16 +362,16 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file) char buf1[2048]; import_file.read(buf1, sizeof(file_magic)); if (! import_file) - throw tools::runtime_error("Error reading expected number of bytes"); + throw std::runtime_error("Error reading expected number of bytes"); str1.assign(buf1, sizeof(file_magic)); if (! ::serialization::parse_binary(str1, file_magic)) - throw tools::runtime_error("Error in deserialization of file_magic"); + throw std::runtime_error("Error in deserialization of file_magic"); if (file_magic != blockchain_raw_magic) { LOG_PRINT_RED_L0("bootstrap file not recognized"); - throw tools::runtime_error("Aborting"); + throw std::runtime_error("Aborting"); } else LOG_PRINT_L0("bootstrap file recognized"); @@ -381,20 +381,20 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file) import_file.read(buf1, sizeof(buflen_file_info)); str1.assign(buf1, sizeof(buflen_file_info)); if (! import_file) - throw tools::runtime_error("Error reading expected number of bytes"); + throw std::runtime_error("Error reading expected number of bytes"); if (! ::serialization::parse_binary(str1, buflen_file_info)) - throw tools::runtime_error("Error in deserialization of buflen_file_info"); + throw std::runtime_error("Error in deserialization of buflen_file_info"); LOG_PRINT_L1("bootstrap::file_info size: " << buflen_file_info); if (buflen_file_info > sizeof(buf1)) - throw tools::runtime_error("Error: bootstrap::file_info size exceeds buffer size"); + throw std::runtime_error("Error: bootstrap::file_info size exceeds buffer size"); import_file.read(buf1, buflen_file_info); if (! import_file) - throw tools::runtime_error("Error reading expected number of bytes"); + throw std::runtime_error("Error reading expected number of bytes"); str1.assign(buf1, buflen_file_info); bootstrap::file_info bfi; if (! ::serialization::parse_binary(str1, bfi)) - throw tools::runtime_error("Error in deserialization of bootstrap::file_info"); + throw std::runtime_error("Error in deserialization of bootstrap::file_info"); LOG_PRINT_L0("bootstrap file v" << unsigned(bfi.major_version) << "." << unsigned(bfi.minor_version)); LOG_PRINT_L0("bootstrap magic size: " << sizeof(file_magic)); LOG_PRINT_L0("bootstrap header size: " << bfi.header_size); @@ -412,7 +412,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) if (!boost::filesystem::exists(raw_file_path, ec)) { LOG_PRINT_L0("bootstrap file not found: " << raw_file_path); - throw tools::runtime_error("Aborting"); + throw std::runtime_error("Aborting"); } std::ifstream import_file; import_file.open(import_file_path, std::ios_base::binary | std::ifstream::in); @@ -421,7 +421,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) if (import_file.fail()) { LOG_PRINT_L0("import_file.open() fail"); - throw tools::runtime_error("Aborting"); + throw std::runtime_error("Aborting"); } uint64_t full_header_size; // 4 byte magic + length of header structures @@ -456,7 +456,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) str1.assign(buf1, sizeof(chunk_size)); if (! ::serialization::parse_binary(str1, chunk_size)) - throw tools::runtime_error("Error in deserialization of chunk_size"); + throw std::runtime_error("Error in deserialization of chunk_size"); LOG_PRINT_L3("chunk_size: " << chunk_size); if (chunk_size > BUFFER_SIZE) @@ -464,7 +464,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) std::cout << refresh_string; LOG_PRINT_L0("WARNING: chunk_size " << chunk_size << " > BUFFER_SIZE " << BUFFER_SIZE << " height: " << h-1); - throw tools::runtime_error("Aborting: chunk size exceeds buffer size"); + throw std::runtime_error("Aborting: chunk size exceeds buffer size"); } if (chunk_size > 100000) { @@ -475,7 +475,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) else if (chunk_size <= 0) { std::cout << refresh_string; LOG_PRINT_L0("ERROR: chunk_size " << chunk_size << " <= 0" << " height: " << h-1); - throw tools::runtime_error("Aborting"); + throw std::runtime_error("Aborting"); } // skip to next expected block size value import_file.seekg(chunk_size, std::ios_base::cur); @@ -483,7 +483,7 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) std::cout << refresh_string; LOG_PRINT_L0("ERROR: unexpected end of file: bytes read before error: " << import_file.gcount() << " of chunk_size " << chunk_size); - throw tools::runtime_error("Aborting"); + throw std::runtime_error("Aborting"); } bytes_read += chunk_size; diff --git a/src/blockchain_utilities/fake_core.h b/src/blockchain_utilities/fake_core.h index 3840a1c13..2fb5031d3 100644 --- a/src/blockchain_utilities/fake_core.h +++ b/src/blockchain_utilities/fake_core.h @@ -78,7 +78,7 @@ struct fake_core_db else { LOG_ERROR("Attempted to use non-existent database type: " << db_type); - throw tools::runtime_error("Attempting to use non-existent database type"); + throw std::runtime_error("Attempting to use non-existent database type"); } boost::filesystem::path folder(path); @@ -176,7 +176,7 @@ struct fake_core_memory { // TODO: // would need to refactor handle_block_to_main_chain() to have a direct add_block() method like Blockchain class - throw tools::runtime_error("direct add_block() method not implemented for in-memory db"); + throw std::runtime_error("direct add_block() method not implemented for in-memory db"); return 2; } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5537900ae..2289704e5 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -31,7 +31,6 @@ set(common_sources command_line.cpp dns_utils.cpp util.cpp - exception.cpp i18n.cpp) set(common_headers) @@ -49,7 +48,6 @@ set(common_private_headers unordered_containers_boost_serialization.h util.h varint.h - exception.h i18n.h) bitmonero_private_headers(common @@ -62,7 +60,6 @@ target_link_libraries(common LINK_PRIVATE crypto ${UNBOUND_LIBRARY} - ${LIBUNWIND_LIBRARIES} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} diff --git a/src/common/exception.cpp b/src/common/exception.cpp deleted file mode 100644 index f8954329f..000000000 --- a/src/common/exception.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2016, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/exception.h" -#include "misc_log_ex.h" -#define UNW_LOCAL_ONLY -#include -#include - -namespace tools -{ - -void log_stack_trace(const char *msg) -{ -#ifdef HAVE_LIBUNWIND - unw_context_t ctx; - unw_cursor_t cur; - unw_word_t ip, off; - unsigned level; - char sym[512], *dsym; - int status; - - if (msg) - LOG_PRINT_L0(msg); - LOG_PRINT_L0("Unwinded call stack:"); - if (unw_getcontext(&ctx) < 0) { - LOG_PRINT_L0("Failed to create unwind context"); - return; - } - if (unw_init_local(&cur, &ctx) < 0) { - LOG_PRINT_L0("Failed to find the first unwind frame"); - return; - } - for (level = 1; level < 999; ++level) { // 999 for safety - int ret = unw_step(&cur); - if (ret < 0) { - LOG_PRINT_L0("Failed to find the next frame"); - return; - } - if (ret == 0) - break; - if (unw_get_reg(&cur, UNW_REG_IP, &ip) < 0) { - LOG_PRINT_L0(" " << std::setw(4) << level); - continue; - } - if (unw_get_proc_name(&cur, sym, sizeof(sym), &off) < 0) { - LOG_PRINT_L0(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip); - continue; - } - dsym = abi::__cxa_demangle(sym, NULL, NULL, &status); - LOG_PRINT_L0(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off); - free(dsym); - } -#else -#warning libunwind disabled, no stack traces -#endif -} - -} // namespace tools diff --git a/src/common/exception.h b/src/common/exception.h deleted file mode 100644 index 93e0d4013..000000000 --- a/src/common/exception.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2016, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef MONERO_EXCEPTION_H -#define MONERO_EXCEPTION_H - -#include -#include - -namespace tools -{ - -void log_stack_trace(const char *msg); - -class exception: public std::exception { -public: - exception() { log_stack_trace(what()); } -}; - -class runtime_error: public std::runtime_error { -public: - explicit runtime_error(const std::string &s): std::runtime_error(s) { log_stack_trace(what()); } - explicit runtime_error(const char *s): std::runtime_error(s) { log_stack_trace(what()); } -}; - -} // namespace tools - -#endif diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h index e25f80116..878202cf1 100644 --- a/src/cryptonote_core/blockchain_storage.h +++ b/src/cryptonote_core/blockchain_storage.h @@ -41,7 +41,6 @@ #include "syncobj.h" #include "string_tools.h" -#include "common/exception.h" #include "tx_pool.h" #include "cryptonote_basic.h" #include "common/util.h" @@ -315,7 +314,7 @@ namespace cryptonote "m_invalid_blocks: " << m_invalid_blocks.size() << ENDL << "m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit); - throw tools::runtime_error("Blockchain data corruption"); + throw std::runtime_error("Blockchain data corruption"); } } } diff --git a/src/cryptonote_core/checkpoints_create.cpp b/src/cryptonote_core/checkpoints_create.cpp index 41246e8d8..41f2321d5 100644 --- a/src/cryptonote_core/checkpoints_create.cpp +++ b/src/cryptonote_core/checkpoints_create.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "common/exception.h" #include "checkpoints_create.h" #include "common/dns_utils.h" #include "include_base_utils.h" diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 907f9d803..6f0fe88a4 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -161,7 +161,7 @@ namespace cryptonote cryptonote::checkpoints checkpoints; if (!cryptonote::create_checkpoints(checkpoints)) { - throw tools::runtime_error("Failed to initialize checkpoints"); + throw std::runtime_error("Failed to initialize checkpoints"); } set_checkpoints(std::move(checkpoints)); diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 186c1c93b..32f0b2ad4 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -36,7 +36,6 @@ #include #include -#include #include "p2p/net_node_common.h" #include "cryptonote_protocol/cryptonote_protocol_handler_common.h" #include "storages/portable_storage_template_helper.h" diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp index 7bc126cd8..bad3f30bd 100644 --- a/src/cryptonote_core/miner.cpp +++ b/src/cryptonote_core/miner.cpp @@ -34,7 +34,6 @@ #include #include #include -#include "common/exception.h" #include "misc_language.h" #include "include_base_utils.h" #include "cryptonote_basic_impl.h" diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 2112b5082..1c92958c9 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -38,7 +38,6 @@ #include #include -#include "common/exception.h" #include "storages/levin_abstract_invoke2.h" #include "warnings.h" #include "cryptonote_protocol_defs.h" diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index c48b836e9..0b42257e7 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -26,7 +26,6 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "common/exception.h" #include "cryptonote_core/cryptonote_basic_impl.h" #include "daemon/command_parser_executor.h" diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 7e5139636..206de9d4a 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -26,7 +26,6 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "common/exception.h" #include "cryptonote_config.h" #include "version.h" #include "daemon/command_server.h" diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index d44538358..e79823d08 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -110,7 +110,7 @@ bool t_daemon::run(bool interactive) { if (nullptr == mp_internals) { - throw tools::runtime_error{"Can't run stopped daemon"}; + throw std::runtime_error{"Can't run stopped daemon"}; } tools::signal_handler::install(std::bind(&daemonize::t_daemon::stop_p2p, this)); @@ -155,7 +155,7 @@ void t_daemon::stop() { if (nullptr == mp_internals) { - throw tools::runtime_error{"Can't stop stopped daemon"}; + throw std::runtime_error{"Can't stop stopped daemon"}; } mp_internals->p2p.stop(); mp_internals->rpc.stop(); @@ -166,7 +166,7 @@ void t_daemon::stop_p2p() { if (nullptr == mp_internals) { - throw tools::runtime_error{"Can't send stop signal to a stopped daemon"}; + throw std::runtime_error{"Can't send stop signal to a stopped daemon"}; } mp_internals->p2p.get().send_stop_signal(); } diff --git a/src/daemon/p2p.h b/src/daemon/p2p.h index b74a5e72d..3858989ce 100644 --- a/src/daemon/p2p.h +++ b/src/daemon/p2p.h @@ -60,7 +60,7 @@ public: LOG_PRINT_L0("Initializing p2p server..."); if (!m_server.init(vm)) { - throw tools::runtime_error("Failed to initialize p2p server."); + throw std::runtime_error("Failed to initialize p2p server."); } LOG_PRINT_L0("P2p server initialized OK"); } diff --git a/src/daemon/protocol.h b/src/daemon/protocol.h index 5f6c317b1..8e2add4a2 100644 --- a/src/daemon/protocol.h +++ b/src/daemon/protocol.h @@ -50,7 +50,7 @@ public: LOG_PRINT_L0("Initializing cryptonote protocol..."); if (!m_protocol.init(vm)) { - throw tools::runtime_error("Failed to initialize cryptonote protocol."); + throw std::runtime_error("Failed to initialize cryptonote protocol."); } LOG_PRINT_L0("Cryptonote protocol initialized OK"); } diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h index caeae9a3d..bfd2afd84 100644 --- a/src/daemon/rpc.h +++ b/src/daemon/rpc.h @@ -55,7 +55,7 @@ public: LOG_PRINT_L0("Initializing core rpc server..."); if (!m_server.init(vm)) { - throw tools::runtime_error("Failed to initialize core rpc server."); + throw std::runtime_error("Failed to initialize core rpc server."); } LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << m_server.get_binded_port(), LOG_LEVEL_0); } @@ -65,7 +65,7 @@ public: LOG_PRINT_L0("Starting core rpc server..."); if (!m_server.run(2, false)) { - throw tools::runtime_error("Failed to start core rpc server."); + throw std::runtime_error("Failed to start core rpc server."); } LOG_PRINT_L0("Core rpc server started ok"); } diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index b57c60948..15ddc081f 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "common/exception.h" #include "string_tools.h" #include "common/scoped_message_writer.h" #include "daemon/rpc_command_executor.h" @@ -89,7 +88,7 @@ t_rpc_command_executor::t_rpc_command_executor( { if (rpc_server == NULL) { - throw tools::runtime_error("If not calling commands via RPC, rpc_server pointer must be non-null"); + throw std::runtime_error("If not calling commands via RPC, rpc_server pointer must be non-null"); } } diff --git a/src/daemonizer/posix_fork.cpp b/src/daemonizer/posix_fork.cpp index 84ff88869..c068912ec 100644 --- a/src/daemonizer/posix_fork.cpp +++ b/src/daemonizer/posix_fork.cpp @@ -4,7 +4,6 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "common/exception.h" #include "daemonizer/posix_fork.h" #include "misc_log_ex.h" @@ -21,7 +20,7 @@ namespace { void quit(std::string const & message) { LOG_ERROR(message); - throw tools::runtime_error(message); + throw std::runtime_error(message); } } diff --git a/src/miner/simpleminer.cpp b/src/miner/simpleminer.cpp index 19db3f534..ba956d90b 100644 --- a/src/miner/simpleminer.cpp +++ b/src/miner/simpleminer.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "common/exception.h" #include "common/command_line.h" #include "misc_log_ex.h" #include "simpleminer.h" diff --git a/src/p2p/data_logger.cpp b/src/p2p/data_logger.cpp index d3ff0ca8e..ca0726c5f 100644 --- a/src/p2p/data_logger.cpp +++ b/src/p2p/data_logger.cpp @@ -33,7 +33,6 @@ #include #include #include -#include "common/exception.h" #include "../../contrib/otshell_utils/utils.hpp" namespace epee @@ -44,7 +43,7 @@ namespace net_utils boost::call_once(m_singleton, [] { _info_c("dbg/data","Creating singleton of data_logger"); - if (m_state != data_logger_state::state_before_init) { _erro_c("dbg/data","Internal error in singleton"); throw tools::runtime_error("data_logger singleton"); } + if (m_state != data_logger_state::state_before_init) { _erro_c("dbg/data","Internal error in singleton"); throw std::runtime_error("data_logger singleton"); } m_state = data_logger_state::state_during_init; m_obj.reset(new data_logger()); m_state = data_logger_state::state_ready_to_use; @@ -53,7 +52,7 @@ namespace net_utils if (m_state != data_logger_state::state_ready_to_use) { _erro ("trying to use not working data_logger"); - throw tools::runtime_error("data_logger ctor state"); + throw std::runtime_error("data_logger ctor state"); } return * m_obj; @@ -61,7 +60,7 @@ namespace net_utils data_logger::data_logger() { _note_c("dbg/data","Starting data logger (for graphs data)"); - if (m_state != data_logger_state::state_during_init) { _erro_c("dbg/data","Singleton ctor state"); throw tools::runtime_error("data_logger ctor state"); } + if (m_state != data_logger_state::state_during_init) { _erro_c("dbg/data","Singleton ctor state"); throw std::runtime_error("data_logger ctor state"); } boost::lock_guard lock(mMutex); // lock // prepare all the files for given data channels: diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index eb12f52ed..ea1993c80 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -561,7 +561,7 @@ bool simple_wallet::set_variable(const std::vector &args) { if (args.empty()) { - fail_msg_writer() << tr("set: needs an argument. available options: seed, always-confirm-transfers, store-tx-info, default-mixin, auto-refresh, refresh-type"); + fail_msg_writer() << tr("set: needs an argument. available options: seed, always-confirm-transfers, default-mixin, auto-refresh, refresh-type"); return true; } else diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ef17a770b..2afe08cb1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -32,7 +32,6 @@ #include #include -#include "common/exception.h" #include "include_base_utils.h" using namespace epee; @@ -804,7 +803,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re // handle error from async fetching thread if (error) { - throw tools::runtime_error("proxy exception in refresh thread"); + throw std::runtime_error("proxy exception in refresh thread"); } } catch (const std::exception&) @@ -2013,7 +2012,7 @@ std::vector wallet2::create_transactions(std::vector ptx_vector; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 0961ad981..f798f404d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -35,7 +35,6 @@ #include #include -#include "common/exception.h" #include "include_base_utils.h" #include "cryptonote_core/account.h" #include "cryptonote_core/account_boost_serialization.h" diff --git a/src/wallet/wallet2_api.cpp b/src/wallet/wallet2_api.cpp index 0cb253398..0644e3690 100644 --- a/src/wallet/wallet2_api.cpp +++ b/src/wallet/wallet2_api.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "common/exception.h" #include "wallet2_api.h" #include "wallet2.h" #include "mnemonics/electrum-words.h" diff --git a/tests/core_proxy/core_proxy.h b/tests/core_proxy/core_proxy.h index 22f4c0421..0315fc8c8 100644 --- a/tests/core_proxy/core_proxy.h +++ b/tests/core_proxy/core_proxy.h @@ -82,7 +82,7 @@ namespace tests bool on_idle(){return true;} bool find_blockchain_supplement(const std::list& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;} bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;} - cryptonote::blockchain_storage &get_blockchain_storage() { throw tools::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); } + cryptonote::blockchain_storage &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); } bool get_test_drop_download() {return true;} bool get_test_drop_download_height() {return true;} bool prepare_handle_incoming_blocks(const std::list &blocks) { return true; } diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index b897d9237..4fdd0a600 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -58,7 +58,7 @@ void test_generator::get_block_chain(std::vector& blockchain, const auto it = m_blocks_info.find(curr); if (m_blocks_info.end() == it) { - throw tools::runtime_error("block hash wasn't found"); + throw std::runtime_error("block hash wasn't found"); } blockchain.push_back(it->second); @@ -82,7 +82,7 @@ uint64_t test_generator::get_already_generated_coins(const crypto::hash& blk_id) { auto it = m_blocks_info.find(blk_id); if (it == m_blocks_info.end()) - throw tools::runtime_error("block hash wasn't found"); + throw std::runtime_error("block hash wasn't found"); return it->second.already_generated_coins; } @@ -323,7 +323,7 @@ bool init_output_indices(map_output_idx_t& outs, std::mapsecond); } @@ -486,11 +486,11 @@ void fill_tx_sources_and_destinations(const std::vector& event destinations.clear(); if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix)) - throw tools::runtime_error("couldn't fill transaction sources"); + throw std::runtime_error("couldn't fill transaction sources"); tx_destination_entry de; if (!fill_tx_destination(de, to, amount)) - throw tools::runtime_error("couldn't fill transaction destination"); + throw std::runtime_error("couldn't fill transaction destination"); destinations.push_back(de); tx_destination_entry de_change; @@ -498,7 +498,7 @@ void fill_tx_sources_and_destinations(const std::vector& event if (0 < cache_back) { if (!fill_tx_destination(de_change, from, cache_back)) - throw tools::runtime_error("couldn't fill transaction cache back destination"); + throw std::runtime_error("couldn't fill transaction cache back destination"); destinations.push_back(de_change); } } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index d51d9d320..d0d912cbb 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -284,7 +284,7 @@ bool do_check_tx_verification_context(const cryptonote::tx_verification_context& { // Default block verification context check if (tvc.m_verifivation_failed) - throw tools::runtime_error("Transaction verification failed"); + throw std::runtime_error("Transaction verification failed"); return true; } //-------------------------------------------------------------------------- @@ -307,7 +307,7 @@ bool do_check_block_verification_context(const cryptonote::block_verification_co { // Default block verification context check if (bvc.m_verifivation_failed) - throw tools::runtime_error("Block verification failed"); + throw std::runtime_error("Block verification failed"); return true; } //-------------------------------------------------------------------------- @@ -621,7 +621,7 @@ inline bool do_replay_file(const std::string& filename) if (!tools::serialize_obj_to_file(events, filename)) \ { \ std::cout << concolor::magenta << "Failed to serialize data to file: " << filename << concolor::normal << std::endl; \ - throw tools::runtime_error("Failed to serialize data to file"); \ + throw std::runtime_error("Failed to serialize data to file"); \ } \ } diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 41d5f1e26..f72c906e5 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -156,7 +156,7 @@ namespace } } - throw tools::runtime_error("invalid public key wasn't found"); + throw std::runtime_error("invalid public key wasn't found"); return crypto::public_key(); } } diff --git a/tests/net_load_tests/clt.cpp b/tests/net_load_tests/clt.cpp index 360261676..56089a4da 100644 --- a/tests/net_load_tests/clt.cpp +++ b/tests/net_load_tests/clt.cpp @@ -37,7 +37,6 @@ #include "gtest/gtest.h" -#include "common/exception.h" #include "include_base_utils.h" #include "misc_language.h" #include "misc_log_ex.h" diff --git a/tests/net_load_tests/srv.cpp b/tests/net_load_tests/srv.cpp index 13b31215e..d8d3eae2e 100644 --- a/tests/net_load_tests/srv.cpp +++ b/tests/net_load_tests/srv.cpp @@ -31,7 +31,6 @@ #include #include -#include "common/exception.h" #include "include_base_utils.h" #include "misc_log_ex.h" #include "storages/levin_abstract_invoke2.h" diff --git a/tests/unit_tests/ban.cpp b/tests/unit_tests/ban.cpp index 5d40e90cf..a5ce244d9 100644 --- a/tests/unit_tests/ban.cpp +++ b/tests/unit_tests/ban.cpp @@ -56,7 +56,7 @@ public: bool on_idle(){return true;} bool find_blockchain_supplement(const std::list& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;} bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;} - cryptonote::blockchain_storage &get_blockchain_storage() { throw tools::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class test_core."); } + cryptonote::blockchain_storage &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class test_core."); } bool get_test_drop_download() const {return true;} bool get_test_drop_download_height() const {return true;} bool prepare_handle_incoming_blocks(const std::list &blocks) { return true; } diff --git a/tests/unit_tests/epee_boosted_tcp_server.cpp b/tests/unit_tests/epee_boosted_tcp_server.cpp index b68ce77bb..946db292d 100644 --- a/tests/unit_tests/epee_boosted_tcp_server.cpp +++ b/tests/unit_tests/epee_boosted_tcp_server.cpp @@ -104,7 +104,7 @@ TEST(boosted_tcp_server, worker_threads_are_exception_resistant) // 2 theads, but 4 exceptions ASSERT_TRUE(srv.run_server(2, false)); - ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw tools::runtime_error("test 1"); })); + ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw std::runtime_error("test 1"); })); ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw std::string("test 2"); })); ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw "test 3"; })); ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw 4; })); diff --git a/tests/unit_tests/mnemonics.cpp b/tests/unit_tests/mnemonics.cpp index 3bf1df7ed..3dc5db7d4 100644 --- a/tests/unit_tests/mnemonics.cpp +++ b/tests/unit_tests/mnemonics.cpp @@ -27,7 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gtest/gtest.h" -#include "common/exception.h" #include "mnemonics/electrum-words.h" #include "crypto/crypto.h" #include diff --git a/tests/unit_tests/test_protocol_pack.cpp b/tests/unit_tests/test_protocol_pack.cpp index 1ff70b4d9..a9a1a34a6 100644 --- a/tests/unit_tests/test_protocol_pack.cpp +++ b/tests/unit_tests/test_protocol_pack.cpp @@ -30,7 +30,6 @@ #include "gtest/gtest.h" -#include "common/exception.h" #include "include_base_utils.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "storages/portable_storage_template_helper.h" -- cgit v1.2.3 From 600a3cf0c0ca0a99dbdc91d32138db3c8aa4165c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 14:30:23 +0000 Subject: New RPC and daemon command to get output histogram This is a list of existing output amounts along with the number of outputs of that amount in the blockchain. The daemon command takes: - no parameters: all outputs with at least 3 instances - one parameter: all outputs with at least that many instances - two parameters: all outputs within that many instances The default starts at 3 to avoid massive spamming of all dust outputs in the blockchain, and is the current minimum mixin requirement. An optional vector of amounts may be passed, to request histogram only for those outputs. --- src/blockchain_db/berkeleydb/db_bdb.cpp | 6 ++++ src/blockchain_db/berkeleydb/db_bdb.h | 9 ++++++ src/blockchain_db/blockchain_db.h | 9 ++++++ src/blockchain_db/lmdb/db_lmdb.cpp | 57 +++++++++++++++++++++++++++++++++ src/blockchain_db/lmdb/db_lmdb.h | 10 ++++++ src/cryptonote_core/blockchain.cpp | 5 +++ src/cryptonote_core/blockchain.h | 9 ++++++ src/daemon/command_parser_executor.cpp | 18 +++++++++++ src/daemon/command_parser_executor.h | 2 ++ src/daemon/command_server.cpp | 5 +++ src/daemon/rpc_command_executor.cpp | 36 +++++++++++++++++++++ src/daemon/rpc_command_executor.h | 2 ++ src/rpc/core_rpc_server.cpp | 32 ++++++++++++++++++ src/rpc/core_rpc_server.h | 2 ++ src/rpc/core_rpc_server_commands_defs.h | 41 ++++++++++++++++++++++++ tests/unit_tests/hardfork.cpp | 1 + 16 files changed, 244 insertions(+) (limited to 'src/daemon/command_server.cpp') diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index 1fef9e619..a7fa556bd 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -2180,6 +2180,12 @@ void BlockchainBDB::get_output_tx_and_index(const uint64_t& amount, const std::v LOG_PRINT_L3("db3: " << db3); } +std::map::BlockchainBDB::get_output_histogram(const std::vector &amounts) const +{ + LOG_PRINT_L3("BlockchainBDB::" << __func__); + throw1(DB_ERROR("Not implemented.")); +} + void BlockchainBDB::set_hard_fork_starting_height(uint8_t version, uint64_t height) { LOG_PRINT_L3("BlockchainBDB::" << __func__); diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h index d7cbd24e7..5c6bda4eb 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.h +++ b/src/blockchain_db/berkeleydb/db_bdb.h @@ -341,6 +341,15 @@ public: virtual bool can_thread_bulk_indices() const { return false; } #endif + /** + * @brief return a histogram of outputs on the blockchain + * + * @param amounts optional set of amounts to lookup + * + * @return a set of amount/instances + */ + std::map get_output_histogram(const std::vector &amounts) const; + private: virtual void add_block( const block& blk , const size_t& block_size diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 3e0ca141e..3585bd061 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1288,6 +1288,15 @@ public: */ virtual void drop_hard_fork_info() = 0; + /** + * @brief return a histogram of outputs on the blockchain + * + * @param amounts optional set of amounts to lookup + * + * @return a set of amount/instances + */ + virtual std::map get_output_histogram(const std::vector &amounts) const = 0; + /** * @brief is BlockchainDB in read-only mode? * diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index e928ab803..9b99520a1 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -2692,6 +2692,63 @@ void BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const std:: LOG_PRINT_L3("db3: " << db3); } +std::map BlockchainLMDB::get_output_histogram(const std::vector &amounts) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(output_amounts); + + std::map histogram; + MDB_val k; + MDB_val v; + + if (amounts.empty()) + { + MDB_cursor_op op = MDB_FIRST; + while (1) + { + int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op); + op = MDB_NEXT_NODUP; + if (ret == MDB_NOTFOUND) + break; + if (ret) + throw0(DB_ERROR(lmdb_error("Failed to enumerate outputs: ", ret).c_str())); + mdb_size_t num_elems = 0; + mdb_cursor_count(m_cur_output_amounts, &num_elems); + uint64_t amount = *(const uint64_t*)k.mv_data; + histogram[amount] = num_elems; + } + } + else + { + for (const auto &amount: amounts) + { + MDB_val_copy k(amount); + int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, MDB_SET); + if (ret == MDB_NOTFOUND) + { + histogram[amount] = 0; + } + else if (ret == MDB_SUCCESS) + { + mdb_size_t num_elems = 0; + mdb_cursor_count(m_cur_output_amounts, &num_elems); + histogram[amount] = num_elems; + } + else + { + throw0(DB_ERROR(lmdb_error("Failed to enumerate outputs: ", ret).c_str())); + } + } + } + + TXN_POSTFIX_RDONLY(); + + return histogram; +} + void BlockchainLMDB::check_hard_fork_info() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index a3f32ffaa..6cd3e0e8f 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -280,6 +280,16 @@ public: virtual void pop_block(block& blk, std::vector& txs); virtual bool can_thread_bulk_indices() const { return true; } + + /** + * @brief return a histogram of outputs on the blockchain + * + * @param amounts optional set of amounts to lookup + * + * @return a set of amount/instances + */ + std::map get_output_histogram(const std::vector &amounts) const; + private: void do_resize(uint64_t size_increase=0); diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 2f42e1db5..035afc61e 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3313,6 +3313,11 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui return m_hardfork->get_voting_info(version, window, votes, threshold, earliest_height, voting); } +std::map Blockchain:: get_output_histogram(const std::vector &amounts) const +{ + return m_db->get_output_histogram(amounts); +} + void Blockchain::load_compiled_in_block_hashes() { if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 94def1aa9..36e0fedfc 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -682,6 +682,15 @@ namespace cryptonote */ bool flush_txes_from_pool(const std::list &txids); + /** + * @brief return a histogram of outputs on the blockchain + * + * @param amounts optional set of amounts to lookup + * + * @return a set of amount/instances + */ + std::map get_output_histogram(const std::vector &amounts) const; + /** * @brief perform a check on all key images in the blockchain * diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 0b42257e7..166fe04ca 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -439,5 +439,23 @@ bool t_command_parser_executor::flush_txpool(const std::vector& arg return m_executor.flush_txpool(txid); } +bool t_command_parser_executor::output_histogram(const std::vector& args) +{ + if (args.size() > 2) return false; + + uint64_t min_count = 3; + uint64_t max_count = 0; + + if (args.size() >= 1) + { + min_count = boost::lexical_cast(args[0]); + } + if (args.size() >= 2) + { + max_count = boost::lexical_cast(args[1]); + } + return m_executor.output_histogram(min_count, max_count); +} + } // namespace daemonize diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index 51c55a8c0..11df92a5e 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -114,6 +114,8 @@ public: bool unban(const std::vector& args); bool flush_txpool(const std::vector& args); + + bool output_histogram(const std::vector& args); }; } // namespace daemonize diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 206de9d4a..aabc2f09a 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -214,6 +214,11 @@ t_command_server::t_command_server( , std::bind(&t_command_parser_executor::flush_txpool, &m_parser, p::_1) , "Flush a transaction from the tx pool by its txid, or the whole tx pool" ); + m_command_lookup.set_handler( + "output_histogram" + , std::bind(&t_command_parser_executor::output_histogram, &m_parser, p::_1) + , "Print output histogram (amount, instances)" + ); } bool t_command_server::process_command_str(const std::string& cmd) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 15ddc081f..933c93ed7 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1203,5 +1203,41 @@ bool t_rpc_command_executor::flush_txpool(const std::string &txid) return true; } +bool t_rpc_command_executor::output_histogram(uint64_t min_count, uint64_t max_count) +{ + cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req; + cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response res; + std::string fail_message = "Unsuccessful"; + epee::json_rpc::error error_resp; + + req.min_count = min_count; + req.max_count = max_count; + + if (m_is_rpc) + { + if (!m_rpc_client->json_rpc_request(req, res, "get_output_histogram", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_get_output_histogram(req, res, error_resp)) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + + std::sort(res.histogram.begin(), res.histogram.end(), + [](const cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::entry &e1, const cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::entry &e2)->bool { return e1.instances < e2.instances; }); + for (const auto &e: res.histogram) + { + tools::msg_writer() << e.instances << " " << cryptonote::print_money(e.amount); + } + + return true; +} + }// namespace daemonize diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index bc3f2d5c5..7e73e7faf 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -132,6 +132,8 @@ public: bool unban(const std::string &ip); bool flush_txpool(const std::string &txid); + + bool output_histogram(uint64_t min_count, uint64_t max_count); }; } // namespace daemonize diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 6b625e77b..5350b6fe0 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1041,6 +1041,38 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp) + { + if(!check_core_busy()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + + std::map histogram; + try + { + histogram = m_core.get_blockchain_storage().get_output_histogram(req.amounts); + } + catch (const std::exception &e) + { + res.status = "Failed to get output histogram"; + return true; + } + + res.histogram.clear(); + res.histogram.reserve(histogram.size()); + for (const auto &i: histogram) + { + if (i.second >= req.min_count && (i.second <= req.max_count || req.max_count == 0)) + res.histogram.push_back(COMMAND_RPC_GET_OUTPUT_HISTOGRAM::entry(i.first, i.second)); + } + + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool core_rpc_server::on_fast_exit(const COMMAND_RPC_FAST_EXIT::request& req, COMMAND_RPC_FAST_EXIT::response& res) { cryptonote::core::set_fast_exit(); diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index f79087030..5c3707209 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -109,6 +109,7 @@ namespace cryptonote MAP_JON_RPC_WE("setbans", on_set_bans, COMMAND_RPC_SETBANS) MAP_JON_RPC_WE("getbans", on_get_bans, COMMAND_RPC_GETBANS) MAP_JON_RPC_WE("flush_txpool", on_flush_txpool, COMMAND_RPC_FLUSH_TRANSACTION_POOL) + MAP_JON_RPC_WE("get_output_histogram", on_get_output_histogram, COMMAND_RPC_GET_OUTPUT_HISTOGRAM) END_JSON_RPC_MAP() END_URI_MAP2() @@ -149,6 +150,7 @@ namespace cryptonote bool on_set_bans(const COMMAND_RPC_SETBANS::request& req, COMMAND_RPC_SETBANS::response& res, epee::json_rpc::error& error_resp); bool on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp); bool on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp); + bool on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp); //----------------------- private: diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 72e399ec4..6d4dd1252 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -986,5 +986,46 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct COMMAND_RPC_GET_OUTPUT_HISTOGRAM + { + struct request + { + std::vector amounts; + uint64_t min_count; + uint64_t max_count; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amounts); + KV_SERIALIZE(min_count); + KV_SERIALIZE(max_count); + END_KV_SERIALIZE_MAP() + }; + + struct entry + { + uint64_t amount; + uint64_t instances; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount); + KV_SERIALIZE(instances); + END_KV_SERIALIZE_MAP() + + entry(uint64_t amount, uint64_t instances): amount(amount), instances(instances) {} + entry() {} + }; + + struct response + { + std::string status; + std::vector histogram; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(status) + KV_SERIALIZE(histogram) + END_KV_SERIALIZE_MAP() + }; + }; } diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 50e0e5ae8..c0ee5fff8 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -108,6 +108,7 @@ public: virtual bool for_all_transactions(std::function) const { return true; } virtual bool for_all_outputs(std::function f) const { return true; } virtual bool is_read_only() const { return false; } + virtual std::map get_output_histogram() const { return std::map(); } virtual void add_block( const block& blk , const size_t& block_size -- cgit v1.2.3