fixed ancient p2p bug

This commit is contained in:
cryptozoidberg 2025-03-05 14:51:11 +04:00
parent a13eedf556
commit 09ddda7dba
No known key found for this signature in database
GPG key ID: 2E10CC61CAC8F36D
4 changed files with 60 additions and 7 deletions

View file

@ -44,6 +44,18 @@ namespace net_utils {
/************************************************************************/
DISABLE_VS_WARNINGS(4355)
template <typename, typename = std::void_t<>>
struct has_pre_destructor_handler : std::false_type {};
// This specialization is selected if T has a valid 'b()' that can be called
template <typename T>
struct has_pre_destructor_handler<T, std::void_t<decltype(std::declval<T&>().on_pre_destroy())>>
: std::true_type {};
template<class t_protocol_handler>
connection<t_protocol_handler>::connection(boost::asio::io_service& io_service,
typename t_protocol_handler::config_type& config, volatile uint32_t& sock_count, i_connection_filter*& pfilter)
@ -66,6 +78,12 @@ connection<t_protocol_handler>::~connection()
{
NESTED_TRY_ENTRY();
if constexpr (has_pre_destructor_handler<t_protocol_handler>::value)
{
m_protocol_handler.on_pre_destroy();
}
if(!m_was_shutdown) {
LOG_PRINT_L3("[sock " << socket_.native_handle() << "] Socket destroyed without shutdown.");
shutdown();

View file

@ -252,6 +252,7 @@ public:
LOG_PRINT_CC(m_connection_context, "[LEVIN_PROTOCOL" << this << "] CONSTRUCTED", LOG_LEVEL_4);
}
virtual ~async_protocol_handler()
{
NESTED_TRY_ENTRY();
@ -278,6 +279,11 @@ public:
NESTED_CATCH_ENTRY(__func__);
}
void on_pre_destroy()
{
m_config.del_connection(this);
}
bool start_outer_call()
{
LOG_PRINT_CC_L4(m_connection_context, "[LEVIN_PROTOCOL" << this << "] -->> start_outer_call");

View file

@ -277,7 +277,7 @@ namespace epee
#define POTENTIAL_HANG_PREVENT_LIMIT 1000
#define DEADLOCK_GUARD_JOURNAL_LIMIT 1000
/************************************************************************/
/* */
@ -290,11 +290,11 @@ namespace epee
struct thread_info
{
std::map<lock_reference_type, size_t> m_owned_objects;
bool is_blocked;
lock_reference_type blocker_lock;
const char* block_location;
const char* func_name;
const char* lock_name;
bool is_blocked = false;
lock_reference_type blocker_lock = nullptr;
const char* block_location = "unknown";
const char* func_name = "unknown";
const char* lock_name = "unknown";
std::string thread_name;
};
@ -307,6 +307,18 @@ namespace epee
std::map<lock_reference_type, thread_id_to_info_map::iterator> m_owned_locks_to_thread;
// deadlock journal
std::list<std::string> m_deadlock_journal;
//lock/unlock journal
struct journal_entry
{
std::thread::id tid;
lock_reference_type lock = nullptr;
bool is_lock_event = false;
const char* func_name = "unkonwn";
const char* lock_name = "unkonwn";
std::string thread_name;
};
std::list<journal_entry> m_journal;
public:
void on_before_lock(lock_reference_type lock, const char* func_name, const char* loction, const char* lock_name, const std::string& thread_name)
@ -363,6 +375,10 @@ namespace epee
}
else
{
m_journal.push_front(journal_entry{ this_id, lock, false, "", "", ""});
if (m_journal.size() > DEADLOCK_GUARD_JOURNAL_LIMIT)
m_journal.pop_back();
m_owned_locks_to_thread.erase(lock_to_thread_it);
}
it->second.m_owned_objects.erase(ownership_it);
@ -400,6 +416,15 @@ namespace epee
ss << "-----------------------------------------------------------------------" << std::endl << err << std::endl;
}
ss << "Ownership history history:" << std::endl;
size_t count = 0;
for (auto entry : m_journal)
{
ss << "tid(" << entry.thread_name << "): " << entry.tid << ", lock_addr: " << entry.lock << (entry.is_lock_event ? "-->":"<--") << ", func: " << (entry.func_name ? entry.func_name:"") << ", lock_name: " << (entry.lock_name ? entry.lock_name : "") << std::endl;
if (++count > 100)
break;
}
return ss.str();
}
@ -429,6 +454,10 @@ namespace epee
//need to add lock-to-thread reccord
m_owned_locks_to_thread[lock] = it;
DO_DEBUG_COUT("[" << std::this_thread::get_id() << "][ADDED_OWNERSHIP]: " << lock << std::endl);
m_journal.push_front(journal_entry{ this_id, lock, true, it->second.func_name, it->second.lock_name, it->second.thread_name });
if (m_journal.size() > DEADLOCK_GUARD_JOURNAL_LIMIT)
m_journal.pop_back();
}
else
{

View file

@ -59,7 +59,7 @@ namespace tools
}
// okay, let's download
LOG_PRINT_MAGENTA("Pre-download required: local db size: " << sz << ", pre_download.unpacked_size = " << pre_download.unpacked_size << ", flag_force_predownload: " << (flag_force_predownload ? "true":"false"), LOG_LEVEL_0);
std::string downloading_file_path = db_main_file_path + ".download";
if (!command_line::has_arg(vm, command_line::arg_process_predownload_from_path))
{