From a315ad4fdf60d72e874ae0bb88539d3d0211c17e Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 29 May 2025 18:15:30 +0300 Subject: [PATCH 01/21] test --- include/libp2p/muxer/yamux/yamux_stream.hpp | 2 +- .../libp2p/muxer/yamux/yamuxed_connection.hpp | 4 ++++ src/muxer/yamux/yamux_stream.cpp | 24 ++++++++++++++----- src/muxer/yamux/yamuxed_connection.cpp | 9 +++++-- src/network/impl/connection_manager_impl.cpp | 5 ++-- src/network/impl/listener_manager_impl.cpp | 4 ++++ 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/libp2p/muxer/yamux/yamux_stream.hpp b/include/libp2p/muxer/yamux/yamux_stream.hpp index 7ed91e8f..4d72ef84 100644 --- a/include/libp2p/muxer/yamux/yamux_stream.hpp +++ b/include/libp2p/muxer/yamux/yamux_stream.hpp @@ -133,7 +133,7 @@ namespace libp2p::connection { closeCompleted(); /// Underlying connection (secured) - std::shared_ptr connection_; + std::weak_ptr connection_; /// Yamux-specific interface of connection YamuxStreamFeedback &feedback_; diff --git a/include/libp2p/muxer/yamux/yamuxed_connection.hpp b/include/libp2p/muxer/yamux/yamuxed_connection.hpp index 6ac7dd59..393d2cd2 100644 --- a/include/libp2p/muxer/yamux/yamuxed_connection.hpp +++ b/include/libp2p/muxer/yamux/yamuxed_connection.hpp @@ -78,6 +78,8 @@ namespace libp2p::connection { ReadCallbackFunc cb) override; void deferWriteCallback(std::error_code ec, WriteCallbackFunc cb) override; + void markAsRegistered(); + private: using Streams = std::unordered_map>; @@ -241,6 +243,8 @@ namespace libp2p::connection { bool close_after_write_ = false; + bool registered_in_manager_ = false; + public: LIBP2P_METRICS_INSTANCE_COUNT_IF_ENABLED( libp2p::connection::YamuxedConnection); diff --git a/src/muxer/yamux/yamux_stream.cpp b/src/muxer/yamux/yamux_stream.cpp index 3dbe594e..6ae4a74a 100644 --- a/src/muxer/yamux/yamux_stream.cpp +++ b/src/muxer/yamux/yamux_stream.cpp @@ -30,14 +30,14 @@ namespace libp2p::connection { uint32_t stream_id, size_t maximum_window_size, size_t write_queue_limit) - : connection_(std::move(connection)), + : connection_(connection), feedback_(feedback), stream_id_(stream_id), window_size_(YamuxFrame::kInitialWindowSize), peers_window_size_(YamuxFrame::kInitialWindowSize), maximum_window_size_(maximum_window_size), write_queue_(write_queue_limit) { - assert(connection_); + assert(connection); assert(stream_id_ > 0); assert(window_size_ <= maximum_window_size_); assert(peers_window_size_ <= maximum_window_size_); @@ -151,19 +151,31 @@ namespace libp2p::connection { } outcome::result YamuxStream::remotePeerId() const { - return connection_->remotePeer(); + if (auto conn = connection_.lock()) { + return conn->remotePeer(); + } + return Error::STREAM_RESET_BY_HOST; } outcome::result YamuxStream::isInitiator() const { - return connection_->isInitiator(); + if (auto conn = connection_.lock()) { + return conn->isInitiator(); + } + return Error::STREAM_RESET_BY_HOST; } outcome::result YamuxStream::localMultiaddr() const { - return connection_->localMultiaddr(); + if (auto conn = connection_.lock()) { + return conn->localMultiaddr(); + } + return Error::STREAM_RESET_BY_HOST; } outcome::result YamuxStream::remoteMultiaddr() const { - return connection_->remoteMultiaddr(); + if (auto conn = connection_.lock()) { + return conn->remoteMultiaddr(); + } + return Error::STREAM_RESET_BY_HOST; } void YamuxStream::increaseSendWindow(size_t delta) { diff --git a/src/muxer/yamux/yamuxed_connection.cpp b/src/muxer/yamux/yamuxed_connection.cpp index 198cbd63..9307e366 100644 --- a/src/muxer/yamux/yamuxed_connection.cpp +++ b/src/muxer/yamux/yamuxed_connection.cpp @@ -553,7 +553,7 @@ namespace libp2p::connection { cb(notify_streams_code); } - if (closed_callback_) { + if (closed_callback_ && registered_in_manager_) { closed_callback_(remote_peer_, shared_from_this()); } @@ -744,7 +744,8 @@ namespace libp2p::connection { } std::vector abandoned; for (auto &[id, stream] : self->streams_) { - if (stream.use_count() == 1) { + auto stream_holder = stream; + if (stream_holder.use_count() == 2) { // 2 = our + в streams_ abandoned.push_back(id); self->enqueue(resetStreamMsg(id)); } @@ -779,4 +780,8 @@ namespace libp2p::connection { }, config_.ping_interval); } + + void YamuxedConnection::markAsRegistered() { + registered_in_manager_ = true; + } } // namespace libp2p::connection diff --git a/src/network/impl/connection_manager_impl.cpp b/src/network/impl/connection_manager_impl.cpp index 1b9d7d54..e7360f91 100644 --- a/src/network/impl/connection_manager_impl.cpp +++ b/src/network/impl/connection_manager_impl.cpp @@ -148,13 +148,14 @@ namespace libp2p::network { } auto it = connections_.find(peer_id); if (it == connections_.end()) { - log()->error("inconsistency in onConnectionClosed, peer not found"); + log()->warn("onConnectionClosed called for peer {} that was not in connection manager (connection may have been closed before being added)", peer_id.toBase58()); return; } [[maybe_unused]] auto erased = it->second.erase(conn); if (erased == 0) { - log()->error("inconsistency in onConnectionClosed, connection not found"); + log()->warn("onConnectionClosed called for connection to peer {} that was not in connection manager (connection may have been closed before being added)", peer_id.toBase58()); + return; } if (it->second.empty()) { diff --git a/src/network/impl/listener_manager_impl.cpp b/src/network/impl/listener_manager_impl.cpp index b2217826..374cc4fd 100644 --- a/src/network/impl/listener_manager_impl.cpp +++ b/src/network/impl/listener_manager_impl.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace libp2p::network { @@ -240,6 +241,9 @@ namespace libp2p::network { }); // store connection + if (auto yamux_conn = std::dynamic_pointer_cast(conn)) { + yamux_conn->markAsRegistered(); + } this->cmgr_->addConnectionToPeer(id, conn); } From 08611cec52e7b6792ca3ed5003e41925f42669b0 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 14:19:20 +0300 Subject: [PATCH 02/21] test --- .../libp2p/muxer/yamux/yamuxed_connection.hpp | 8 ++ src/muxer/yamux/yamuxed_connection.cpp | 79 ++++++++++++++++++- src/network/impl/connection_manager_impl.cpp | 68 +++++++++++++--- 3 files changed, 142 insertions(+), 13 deletions(-) diff --git a/include/libp2p/muxer/yamux/yamuxed_connection.hpp b/include/libp2p/muxer/yamux/yamuxed_connection.hpp index 393d2cd2..651c555e 100644 --- a/include/libp2p/muxer/yamux/yamuxed_connection.hpp +++ b/include/libp2p/muxer/yamux/yamuxed_connection.hpp @@ -80,6 +80,14 @@ namespace libp2p::connection { void markAsRegistered(); + size_t getStreamsCount() const { return streams_.size(); } + size_t getPendingStreamsCount() const { return pending_outbound_streams_.size(); } + long getSharedPtrUseCount() const { return shared_from_this().use_count(); } + + void debugPrintActiveStreams() const; + + void debugPrintMemoryLeakSources() const; + private: using Streams = std::unordered_map>; diff --git a/src/muxer/yamux/yamuxed_connection.cpp b/src/muxer/yamux/yamuxed_connection.cpp index 9307e366..12a606be 100644 --- a/src/muxer/yamux/yamuxed_connection.cpp +++ b/src/muxer/yamux/yamuxed_connection.cpp @@ -87,6 +87,11 @@ namespace libp2p::connection { return; } started_ = false; + + ping_handle_.reset(); + cleanup_handle_.reset(); + inactivity_handle_.reset(); + SL_INFO(log(), "=== ALL TIMERS CANCELLED IN stop() ==="); } outcome::result> YamuxedConnection::newStream() { @@ -537,6 +542,11 @@ namespace libp2p::connection { auto self = shared_from_this(); started_ = false; + ping_handle_.reset(); + cleanup_handle_.reset(); + inactivity_handle_.reset(); + SL_INFO(log(), "=== ALL TIMERS CANCELLED IN close() ==="); + SL_DEBUG(log(), "closing connection, reason: {}", notify_streams_code); Streams streams; @@ -554,7 +564,17 @@ namespace libp2p::connection { } if (closed_callback_ && registered_in_manager_) { - closed_callback_(remote_peer_, shared_from_this()); + auto self_ptr = shared_from_this(); + SL_INFO(log(), "=== CALLING closed_callback_ ==="); + SL_INFO(log(), "YamuxedConnection address: {}", (void*)this); + SL_INFO(log(), "shared_ptr address: {}", (void*)self_ptr.get()); + SL_INFO(log(), "shared_ptr use_count: {}", self_ptr.use_count()); + SL_INFO(log(), "remote_peer_: {}", remote_peer_.toBase58()); + + closed_callback_(remote_peer_, self_ptr); + + SL_INFO(log(), "=== closed_callback_ FINISHED ==="); + SL_INFO(log(), "shared_ptr use_count after callback: {}", self_ptr.use_count()); } close_after_write_ = true; @@ -784,4 +804,61 @@ namespace libp2p::connection { void YamuxedConnection::markAsRegistered() { registered_in_manager_ = true; } + + void YamuxedConnection::debugPrintActiveStreams() const { + log()->info("=== DEBUG: YamuxedConnection {} active streams analysis ===", + (void*)this); + log()->info("YamuxedConnection shared_ptr use_count: {}", + shared_from_this().use_count()); + log()->info("Total streams: {}, pending: {}", + streams_.size(), pending_outbound_streams_.size()); + + for (const auto& [id, stream] : streams_) { + log()->info("Stream {}: use_count={}, readable={}, writable={}", + id, stream.use_count(), + !stream->isClosedForRead(), !stream->isClosedForWrite()); + } + + for (const auto& [id, cb] : pending_outbound_streams_) { + log()->info("Pending stream {}: callback set", id); + } + log()->info("=== END DEBUG ==="); + } + + void YamuxedConnection::debugPrintMemoryLeakSources() const { + log()->info("=== MEMORY LEAK DIAGNOSTIC for YamuxedConnection {} ===", (void*)this); + log()->info("shared_ptr use_count: {}", shared_from_this().use_count()); + log()->info("started_: {}", started_); + log()->info("registered_in_manager_: {}", registered_in_manager_); + log()->info("is_writing_: {}", is_writing_); + log()->info("close_after_write_: {}", close_after_write_); + + log()->info("Active streams: {}", streams_.size()); + log()->info("Pending outbound streams: {}", pending_outbound_streams_.size()); + log()->info("Fresh streams (awaiting handlers): {}", fresh_streams_.size()); + log()->info("Write queue size: {}", write_queue_.size()); + + log()->info("Timer handles active:"); + log()->info(" ping_handle_ active: {}", ping_handle_.has_value()); + log()->info(" cleanup_handle_ active: {}", cleanup_handle_.has_value()); + log()->info(" inactivity_handle_ active: {}", inactivity_handle_.has_value()); + + log()->info("Connection state:"); + log()->info(" connection_.use_count(): {}", connection_.use_count()); + log()->info(" connection_->isClosed(): {}", connection_->isClosed()); + + log()->info("Callbacks registered:"); + log()->info(" closed_callback_ set: {}", static_cast(closed_callback_)); + log()->info(" new_stream_handler_ set: {}", static_cast(new_stream_handler_)); + + for (const auto& [id, stream] : streams_) { + log()->info("Stream {} detailed info:", id); + log()->info(" use_count: {}", stream.use_count()); + log()->info(" is closed: {}", stream->isClosed()); + log()->info(" closed for read: {}", stream->isClosedForRead()); + log()->info(" closed for write: {}", stream->isClosedForWrite()); + } + + log()->info("=== END MEMORY LEAK DIAGNOSTIC ==="); + } } // namespace libp2p::connection diff --git a/src/network/impl/connection_manager_impl.cpp b/src/network/impl/connection_manager_impl.cpp index e7360f91..2b351e01 100644 --- a/src/network/impl/connection_manager_impl.cpp +++ b/src/network/impl/connection_manager_impl.cpp @@ -51,6 +51,11 @@ namespace libp2p::network { void ConnectionManagerImpl::addConnectionToPeer( const peer::PeerId &p, ConnectionManager::ConnectionSPtr c) { + SL_INFO(log_, "=== addConnectionToPeer CALLED ==="); + SL_INFO(log_, "peer: {}", p.toBase58()); + SL_INFO(log_, "connection address: {}", (void*)c.get()); + SL_INFO(log_, "connection use_count: {}", c.use_count()); + if (c == nullptr) { log()->error("inconsistency: not adding nullptr to active connections"); return; @@ -58,11 +63,22 @@ namespace libp2p::network { auto it = connections_.find(p); if (it == connections_.end()) { + SL_INFO(log_, "Creating new peer entry in connections_"); connections_.insert({p, {c}}); } else { + SL_INFO(log_, "Adding to existing peer entry (current size: {})", it->second.size()); connections_[p].insert(c); } + + SL_INFO(log_, "Connection successfully added. Total peers: {}", connections_.size()); + auto it_check = connections_.find(p); + if (it_check != connections_.end()) { + SL_INFO(log_, "Verification: peer {} now has {} connections", + p.toBase58(), it_check->second.size()); + } + bus_->getChannel().publish(c); + SL_INFO(log_, "=== addConnectionToPeer FINISHED ==="); } std::vector @@ -139,30 +155,58 @@ namespace libp2p::network { } } - void ConnectionManagerImpl::onConnectionClosed( - const peer::PeerId &peer_id, - const std::shared_ptr &conn) { + void ConnectionManagerImpl::onConnectionClosed(const peer::PeerId &peer, + CapableConnectionSPtr connection) { + SL_INFO(log_, "=== onConnectionClosed CALLED ==="); + SL_INFO(log_, "peer: {}", peer.toBase58()); + SL_INFO(log_, "connection address: {}", (void*)connection.get()); + SL_INFO(log_, "connection use_count: {}", connection.use_count()); + if (closing_connections_to_peer_.has_value() - && closing_connections_to_peer_.value() == peer_id) { + && closing_connections_to_peer_.value() == peer) { return; } - auto it = connections_.find(peer_id); + + auto it = connections_.find(peer); if (it == connections_.end()) { - log()->warn("onConnectionClosed called for peer {} that was not in connection manager (connection may have been closed before being added)", peer_id.toBase58()); + SL_WARN(log_, "onConnectionClosed called for peer {} that was not in connection manager (connection may have been closed before being added)", peer.toBase58()); return; } - [[maybe_unused]] auto erased = it->second.erase(conn); - if (erased == 0) { - log()->warn("onConnectionClosed called for connection to peer {} that was not in connection manager (connection may have been closed before being added)", peer_id.toBase58()); + SL_INFO(log_, "Found peer in connections_, set size: {}", it->second.size()); + + // Log all connections in set for comparison + for (const auto& conn : it->second) { + SL_INFO(log_, "Existing connection in set: address={}, use_count={}", + (void*)conn.get(), conn.use_count()); + } + + std::unique_lock lock(connection_mutex_); + if (connection_is_closing_.count(connection) != 0) { + SL_WARN(log_, "Connection {} is already being closed", (void*)connection.get()); return; } + connection_is_closing_.insert(connection); + lock.unlock(); + + auto erased = it->second.erase(connection); + SL_INFO(log_, "Erased count: {}", erased); + SL_INFO(log_, "Peer connection set size after erase: {}", it->second.size()); + + if (erased == 0) { + SL_WARN(log_, "Connection {} was not found in connections_ for peer {}", + (void*)connection.get(), peer.toBase58()); + } else { + SL_INFO(log_, "Connection {} was successfully removed", (void*)connection.get()); + } if (it->second.empty()) { - connections_.erase(peer_id); - bus_->getChannel().publish( - peer_id); + connections_.erase(peer); + SL_INFO(log_, "Peer {} removed from connections_ (no more connections)", peer.toBase58()); + bus_->getChannel().publish(peer); } + + SL_INFO(log_, "=== onConnectionClosed FINISHED ==="); } } // namespace libp2p::network From 629c727ff216bd7a523d47ad1b9d9eab43744ea9 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 15:29:59 +0300 Subject: [PATCH 03/21] test --- src/muxer/yamux/yamuxed_connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/muxer/yamux/yamuxed_connection.cpp b/src/muxer/yamux/yamuxed_connection.cpp index 12a606be..0dd62868 100644 --- a/src/muxer/yamux/yamuxed_connection.cpp +++ b/src/muxer/yamux/yamuxed_connection.cpp @@ -571,7 +571,7 @@ namespace libp2p::connection { SL_INFO(log(), "shared_ptr use_count: {}", self_ptr.use_count()); SL_INFO(log(), "remote_peer_: {}", remote_peer_.toBase58()); - closed_callback_(remote_peer_, self_ptr); + closed_callback_(remote_peer_, std::static_pointer_cast(self_ptr)); SL_INFO(log(), "=== closed_callback_ FINISHED ==="); SL_INFO(log(), "shared_ptr use_count after callback: {}", self_ptr.use_count()); From 2d4da680f61417b0618cc486fafde05fd13799ae Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 15:50:56 +0300 Subject: [PATCH 04/21] test --- src/network/impl/connection_manager_impl.cpp | 46 ++++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/network/impl/connection_manager_impl.cpp b/src/network/impl/connection_manager_impl.cpp index 2b351e01..6e06b813 100644 --- a/src/network/impl/connection_manager_impl.cpp +++ b/src/network/impl/connection_manager_impl.cpp @@ -51,10 +51,10 @@ namespace libp2p::network { void ConnectionManagerImpl::addConnectionToPeer( const peer::PeerId &p, ConnectionManager::ConnectionSPtr c) { - SL_INFO(log_, "=== addConnectionToPeer CALLED ==="); - SL_INFO(log_, "peer: {}", p.toBase58()); - SL_INFO(log_, "connection address: {}", (void*)c.get()); - SL_INFO(log_, "connection use_count: {}", c.use_count()); + SL_INFO(log(), "=== addConnectionToPeer CALLED ==="); + SL_INFO(log(), "peer: {}", p.toBase58()); + SL_INFO(log(), "connection address: {}", (void*)c.get()); + SL_INFO(log(), "connection use_count: {}", c.use_count()); if (c == nullptr) { log()->error("inconsistency: not adding nullptr to active connections"); @@ -63,22 +63,22 @@ namespace libp2p::network { auto it = connections_.find(p); if (it == connections_.end()) { - SL_INFO(log_, "Creating new peer entry in connections_"); + SL_INFO(log(), "Creating new peer entry in connections_"); connections_.insert({p, {c}}); } else { - SL_INFO(log_, "Adding to existing peer entry (current size: {})", it->second.size()); + SL_INFO(log(), "Adding to existing peer entry (current size: {})", it->second.size()); connections_[p].insert(c); } - SL_INFO(log_, "Connection successfully added. Total peers: {}", connections_.size()); + SL_INFO(log(), "Connection successfully added. Total peers: {}", connections_.size()); auto it_check = connections_.find(p); if (it_check != connections_.end()) { - SL_INFO(log_, "Verification: peer {} now has {} connections", + SL_INFO(log(), "Verification: peer {} now has {} connections", p.toBase58(), it_check->second.size()); } bus_->getChannel().publish(c); - SL_INFO(log_, "=== addConnectionToPeer FINISHED ==="); + SL_INFO(log(), "=== addConnectionToPeer FINISHED ==="); } std::vector @@ -157,10 +157,10 @@ namespace libp2p::network { void ConnectionManagerImpl::onConnectionClosed(const peer::PeerId &peer, CapableConnectionSPtr connection) { - SL_INFO(log_, "=== onConnectionClosed CALLED ==="); - SL_INFO(log_, "peer: {}", peer.toBase58()); - SL_INFO(log_, "connection address: {}", (void*)connection.get()); - SL_INFO(log_, "connection use_count: {}", connection.use_count()); + SL_INFO(log(), "=== onConnectionClosed CALLED ==="); + SL_INFO(log(), "peer: {}", peer.toBase58()); + SL_INFO(log(), "connection address: {}", (void*)connection.get()); + SL_INFO(log(), "connection use_count: {}", connection.use_count()); if (closing_connections_to_peer_.has_value() && closing_connections_to_peer_.value() == peer) { @@ -169,44 +169,44 @@ namespace libp2p::network { auto it = connections_.find(peer); if (it == connections_.end()) { - SL_WARN(log_, "onConnectionClosed called for peer {} that was not in connection manager (connection may have been closed before being added)", peer.toBase58()); + SL_WARN(log(), "onConnectionClosed called for peer {} that was not in connection manager (connection may have been closed before being added)", peer.toBase58()); return; } - SL_INFO(log_, "Found peer in connections_, set size: {}", it->second.size()); + SL_INFO(log(), "Found peer in connections_, set size: {}", it->second.size()); // Log all connections in set for comparison for (const auto& conn : it->second) { - SL_INFO(log_, "Existing connection in set: address={}, use_count={}", + SL_INFO(log(), "Existing connection in set: address={}, use_count={}", (void*)conn.get(), conn.use_count()); } std::unique_lock lock(connection_mutex_); if (connection_is_closing_.count(connection) != 0) { - SL_WARN(log_, "Connection {} is already being closed", (void*)connection.get()); + SL_WARN(log(), "Connection {} is already being closed", (void*)connection.get()); return; } connection_is_closing_.insert(connection); lock.unlock(); auto erased = it->second.erase(connection); - SL_INFO(log_, "Erased count: {}", erased); - SL_INFO(log_, "Peer connection set size after erase: {}", it->second.size()); + SL_INFO(log(), "Erased count: {}", erased); + SL_INFO(log(), "Peer connection set size after erase: {}", it->second.size()); if (erased == 0) { - SL_WARN(log_, "Connection {} was not found in connections_ for peer {}", + SL_WARN(log(), "Connection {} was not found in connections_ for peer {}", (void*)connection.get(), peer.toBase58()); } else { - SL_INFO(log_, "Connection {} was successfully removed", (void*)connection.get()); + SL_INFO(log(), "Connection {} was successfully removed", (void*)connection.get()); } if (it->second.empty()) { connections_.erase(peer); - SL_INFO(log_, "Peer {} removed from connections_ (no more connections)", peer.toBase58()); + SL_INFO(log(), "Peer {} removed from connections_ (no more connections)", peer.toBase58()); bus_->getChannel().publish(peer); } - SL_INFO(log_, "=== onConnectionClosed FINISHED ==="); + SL_INFO(log(), "=== onConnectionClosed FINISHED ==="); } } // namespace libp2p::network From 63fac046470d59c3004bf1bc5ebb9dbaf9e3cab1 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 16:10:26 +0300 Subject: [PATCH 05/21] fix --- include/libp2p/network/impl/connection_manager_impl.hpp | 7 +++++++ src/network/impl/connection_manager_impl.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/libp2p/network/impl/connection_manager_impl.hpp b/include/libp2p/network/impl/connection_manager_impl.hpp index 629ce4d4..f207ba1c 100644 --- a/include/libp2p/network/impl/connection_manager_impl.hpp +++ b/include/libp2p/network/impl/connection_manager_impl.hpp @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include @@ -46,6 +47,12 @@ namespace libp2p::network { /// Reentrancy resolver between closeConnectionsToPeer and /// onConnectionClosed boost::optional closing_connections_to_peer_; + + /// Mutex to protect connection_is_closing_ set + std::mutex connection_mutex_; + + /// Set of connections currently being closed to prevent double closing + std::unordered_set connection_is_closing_; }; } // namespace libp2p::network diff --git a/src/network/impl/connection_manager_impl.cpp b/src/network/impl/connection_manager_impl.cpp index 6e06b813..e5bc21b2 100644 --- a/src/network/impl/connection_manager_impl.cpp +++ b/src/network/impl/connection_manager_impl.cpp @@ -7,6 +7,12 @@ #include #include +#include +#include +#include +#include +#include +#include namespace libp2p::network { @@ -156,7 +162,7 @@ namespace libp2p::network { } void ConnectionManagerImpl::onConnectionClosed(const peer::PeerId &peer, - CapableConnectionSPtr connection) { + const std::shared_ptr &connection) { SL_INFO(log(), "=== onConnectionClosed CALLED ==="); SL_INFO(log(), "peer: {}", peer.toBase58()); SL_INFO(log(), "connection address: {}", (void*)connection.get()); From eb5d10018c9ed34b3c5d7aa6d220569f5c6788b1 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 18:15:09 +0300 Subject: [PATCH 06/21] fix --- src/muxer/yamux/yamuxed_connection.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/muxer/yamux/yamuxed_connection.cpp b/src/muxer/yamux/yamuxed_connection.cpp index 0dd62868..172e5587 100644 --- a/src/muxer/yamux/yamuxed_connection.cpp +++ b/src/muxer/yamux/yamuxed_connection.cpp @@ -839,9 +839,9 @@ namespace libp2p::connection { log()->info("Write queue size: {}", write_queue_.size()); log()->info("Timer handles active:"); - log()->info(" ping_handle_ active: {}", ping_handle_.has_value()); - log()->info(" cleanup_handle_ active: {}", cleanup_handle_.has_value()); - log()->info(" inactivity_handle_ active: {}", inactivity_handle_.has_value()); + log()->info(" ping_handle_ active: {}", static_cast(ping_handle_)); + log()->info(" cleanup_handle_ active: {}", static_cast(cleanup_handle_)); + log()->info(" inactivity_handle_ active: {}", static_cast(inactivity_handle_)); log()->info("Connection state:"); log()->info(" connection_.use_count(): {}", connection_.use_count()); From e07b03d91d1ac64c97b9cdefe06c9643eaa9eb0f Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 20:43:51 +0300 Subject: [PATCH 07/21] fix --- src/network/impl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/impl/CMakeLists.txt b/src/network/impl/CMakeLists.txt index 274ab550..c794e1db 100644 --- a/src/network/impl/CMakeLists.txt +++ b/src/network/impl/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(p2p_listener_manager p2p_multiaddress p2p_peer_id p2p_logger + p2p_yamuxed_connection ) From 35e3ff686d716967702cfc38f2e54f0dc15cff35 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 21:00:58 +0300 Subject: [PATCH 08/21] tests --- debug_yamux_leaks | Bin 0 -> 113832 bytes debug_yamux_leaks.cpp | 185 ++++++++++ test_compilation_check | Bin 0 -> 62256 bytes test_final_verification | Bin 0 -> 75880 bytes test_final_verification.cpp | 82 +++++ test_fix_verification | Bin 0 -> 76440 bytes test_yamux_100_connections | Bin 0 -> 79032 bytes test_yamux_100_connections.cpp | 618 ++++++++++++++++++++++++++++++++ test_yamux_10_simple | Bin 0 -> 60384 bytes test_yamux_10_simple.cpp | 456 +++++++++++++++++++++++ test_yamux_complete | Bin 0 -> 366736 bytes test_yamux_complete.cpp | 637 +++++++++++++++++++++++++++++++++ test_yamux_leaks | Bin 0 -> 239088 bytes test_yamux_leaks.cpp | 319 +++++++++++++++++ test_yamux_realistic | Bin 0 -> 275096 bytes test_yamux_realistic.cpp | 495 +++++++++++++++++++++++++ 16 files changed, 2792 insertions(+) create mode 100755 debug_yamux_leaks create mode 100644 debug_yamux_leaks.cpp create mode 100755 test_compilation_check create mode 100755 test_final_verification create mode 100644 test_final_verification.cpp create mode 100755 test_fix_verification create mode 100755 test_yamux_100_connections create mode 100644 test_yamux_100_connections.cpp create mode 100755 test_yamux_10_simple create mode 100644 test_yamux_10_simple.cpp create mode 100755 test_yamux_complete create mode 100644 test_yamux_complete.cpp create mode 100755 test_yamux_leaks create mode 100644 test_yamux_leaks.cpp create mode 100755 test_yamux_realistic create mode 100644 test_yamux_realistic.cpp diff --git a/debug_yamux_leaks b/debug_yamux_leaks new file mode 100755 index 0000000000000000000000000000000000000000..b68676825395f8ca65b199b390c5f9bbd9a04843 GIT binary patch literal 113832 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 literal 0 HcmV?d00001 diff --git a/debug_yamux_leaks.cpp b/debug_yamux_leaks.cpp new file mode 100644 index 00000000..cc09d475 --- /dev/null +++ b/debug_yamux_leaks.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include + +// Простая диагностика утечек для shared_ptr +class LeakDetector { +public: + static LeakDetector& instance() { + static LeakDetector detector; + return detector; + } + + void registerPointer(void* ptr, const char* type) { + std::lock_guard lock(mutex_); + active_pointers_[ptr] = type; + std::cout << "[LEAK_DEBUG] Created " << type << " at " << ptr << std::endl; + } + + void unregisterPointer(void* ptr) { + std::lock_guard lock(mutex_); + auto it = active_pointers_.find(ptr); + if (it != active_pointers_.end()) { + std::cout << "[LEAK_DEBUG] Destroyed " << it->second << " at " << ptr << std::endl; + active_pointers_.erase(it); + } + } + + void printActivePointers() { + std::lock_guard lock(mutex_); + if (active_pointers_.empty()) { + std::cout << "[LEAK_DEBUG] No active pointers detected!" << std::endl; + } else { + std::cout << "[LEAK_DEBUG] Active pointers (" << active_pointers_.size() << "):" << std::endl; + for (const auto& [ptr, type] : active_pointers_) { + std::cout << " " << type << " at " << ptr << std::endl; + } + } + } + +private: + std::mutex mutex_; + std::unordered_map active_pointers_; +}; + +// Макросы для отладки утечек +#define REGISTER_LEAK_DEBUG(ptr, type) LeakDetector::instance().registerPointer(ptr, type) +#define UNREGISTER_LEAK_DEBUG(ptr) LeakDetector::instance().unregisterPointer(ptr) +#define PRINT_ACTIVE_LEAKS() LeakDetector::instance().printActivePointers() + +// Пример использования для диагностики YamuxedConnection +class YamuxedConnectionDebug : public std::enable_shared_from_this { +public: + YamuxedConnectionDebug() { + REGISTER_LEAK_DEBUG(this, "YamuxedConnection"); + } + + ~YamuxedConnectionDebug() { + UNREGISTER_LEAK_DEBUG(this); + } + + void debugSharedPtrReferences() { + auto self = shared_from_this(); + std::cout << "[DEBUG] shared_ptr use_count: " << self.use_count() << std::endl; + + // Симулируем различные места, где могут держаться ссылки: + + // 1. В streams_ (как было ранее) + streams_["test"] = std::make_shared(42); + std::cout << "[DEBUG] After adding to streams_, use_count: " << self.use_count() << std::endl; + + // 2. В callback'ах + auto callback = [self](){ /* do something */ }; + std::cout << "[DEBUG] After capturing in callback, use_count: " << self.use_count() << std::endl; + + // 3. В timer'ах + auto timer_callback = [weak_self = std::weak_ptr(self)](){ + if (auto strong = weak_self.lock()) { + /* do something */ + } + }; + std::cout << "[DEBUG] After weak capture in timer, use_count: " << self.use_count() << std::endl; + + // Очистка + streams_.clear(); + std::cout << "[DEBUG] After clearing streams_, use_count: " << self.use_count() << std::endl; + } + +private: + std::unordered_map> streams_; +}; + +// Mock classes for simple testing +namespace libp2p { +namespace peer { +struct PeerId { + std::string id; + std::string toBase58() const { return id; } +}; +} + +namespace connection { +struct CapableConnection { + virtual ~CapableConnection() = default; + virtual bool isClosed() const = 0; +}; +} + +namespace muxer::yamux { +// Simple test for shared_ptr behavior in unordered_set +class YamuxedConnection { +public: + void debugPrintMemoryLeakSources() { + std::cout << "=== MEMORY LEAK DEBUG INFO ===" << std::endl; + std::cout << "This is a test method" << std::endl; + } +}; +} +} + +// Test shared_ptr behavior in unordered_set +void testSharedPtrInSet() { + std::cout << "\n=== Testing shared_ptr behavior in unordered_set ===" << std::endl; + + auto obj = std::make_shared(42); + auto obj2 = obj; // same object, different shared_ptr instance + + std::unordered_set> set; + + // Add first shared_ptr + set.insert(obj); + std::cout << "Added obj to set, size: " << set.size() << std::endl; + + // Try to find with different shared_ptr to same object + auto found = set.find(obj2); + if (found != set.end()) { + std::cout << "SUCCESS: obj2 found in set (pointing to same object)" << std::endl; + } else { + std::cout << "FAIL: obj2 NOT found in set" << std::endl; + } + + // Try to erase with different shared_ptr to same object + auto erased = set.erase(obj2); + std::cout << "Erased count using obj2: " << erased << std::endl; + std::cout << "Set size after erase: " << set.size() << std::endl; + + // Test with shared_from_this equivalent + struct TestClass : std::enable_shared_from_this { + int value = 123; + }; + + auto test_obj = std::make_shared(); + auto self_ptr = test_obj->shared_from_this(); + + std::unordered_set> test_set; + test_set.insert(test_obj); + + auto found2 = test_set.find(self_ptr); + if (found2 != test_set.end()) { + std::cout << "SUCCESS: shared_from_this() found in set" << std::endl; + } else { + std::cout << "FAIL: shared_from_this() NOT found in set" << std::endl; + } + + auto erased2 = test_set.erase(self_ptr); + std::cout << "Erased count using shared_from_this(): " << erased2 << std::endl; + std::cout << "Test set size after erase: " << test_set.size() << std::endl; +} + +int main() { + std::cout << "=== Yamux Memory Leak Debug Tool ===" << std::endl; + + // Test shared_ptr behavior + testSharedPtrInSet(); + + // Test our debug method + auto yamux_conn = std::make_shared(); + yamux_conn->debugPrintMemoryLeakSources(); + + std::cout << "\n=== Debug tool completed ===" << std::endl; + return 0; +} \ No newline at end of file diff --git a/test_compilation_check b/test_compilation_check new file mode 100755 index 0000000000000000000000000000000000000000..0bdb33a15ba933f7fad41e438301605d73659b70 GIT binary patch literal 62256 zcmeHQePC48m46AKQ4k`6rAl?MXi+g{k^liw1Ifb)gb?$g_{C$GOvp$+#>pfE#gZCp zNn>o*szvKsy6d`Z*H+rKmTfIYWJz?bMoTqyS({pGhr()Bsm)e&_IK_*_q{i7W*`ZO z{*ech^X@tKo_p`P=bU@)eP5gOq9v&*DPuG~#%Nb)DL7A`ArX0u&pf~<0C`%jHW7ba z+PT_ENRJgbNzao2RC%N`X9d$3PiQLlB-5R6I_Fc6+C&FIDwpi&`J$vKsHMv^l^aK= zF8YJRCH|W5*$ZS^L3=q-UkT@T!0FsT1?}ZXHrsEL<(#mOJ29v_!|hB(b}F~!c3I8| z(0M~0&9xb9J8`N zhAXL@vwbR^$K@1M?JVJPky4q#3HNcs6y&6KHOi4ZhkEcZXr)}AbKF$Agey>x^otHc zXW~b?c2#kOmfE6q5l+!lv=os(1volVIj!iFcM5(q98~_JeH$ixbKS46pMGK9;Kg6w zTs2X@zW>siz?!)^m)2BXQWL0aY`&y9ckU%~b21w0GqSYPQSL1Kh>wun1y5?)UE5Q& z=e4ovDK0Jbq_2&2rD{{grl+P&NWWz@Oq z-^KXRaS48x;^)TihHve@Kj+@d@0|KCzF&Sk_x#33m$npde)e0pUtIXuC5;{}by_uf8qNIna#WM>_%rNbastXtN$@iv6zZSz7!Q0RJ{=f{ zMED>WB*O1Ty)*{SBXDx!{F9T^TZ92j#6LSp{vRjFzXFPth|eFAv}X+Zo2dN@lGOWH z68Y>%BL5{2Od|edcP^*Ukk*s%*_)*OWJihk%tkvCjr;5*`5%DOI8QrG+m(R~IOa>B zU5g3`zmSX^$5g5i#~8Ge@SS87ILM~x7|(n@m?zWu5@?4pUX=fVY>DV$d_N%J!wx>@ zp}&OB;r5WN(s4fOpP`+pwQQ8>SrTZ!5dA$(DV=3m12XSiQk+@4Ct zmvj5~wf)m-m1#(xix+IcO^BnEWgQKMU9&#=?z9ND4RhFj{ ze=FxNWjWMy{wuk^JGkCF#y`vX4|9Gchc~!i+qhp!o`)dk(=mEmTO

UhOWHzmxyZ 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 wyAXe>->P571E*w{CFQ@apGtUgg%vApWyR3 +#include +#include +#include + +// Финальная проверка исправлений компиляции + +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id = "test_peer"; + std::string toBase58() const { return id; } + bool operator==(const PeerId& other) const { return id == other.id; } +}; +} + +namespace connection { +class CapableConnection { +public: + virtual ~CapableConnection() = default; + virtual bool isClosed() const = 0; +}; + +class YamuxedConnection : public CapableConnection, public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function&)>; + + YamuxedConnection(ConnectionClosedCallback callback) : closed_callback_(callback) {} + + bool isClosed() const override { return false; } + + void simulateCloseCallback() { + peer::PeerId remote_peer; + auto self_ptr = shared_from_this(); + + // ИСПРАВЛЕНИЕ 1: Приведение типа в yamuxed_connection.cpp (строка 574) + closed_callback_(remote_peer, std::static_pointer_cast(self_ptr)); + } + +private: + ConnectionClosedCallback closed_callback_; +}; +} + +namespace network { +class ConnectionManagerImpl { +public: + // ИСПРАВЛЕНИЕ 2: Правильная сигнатура в connection_manager_impl.cpp (строка 158) + void onConnectionClosed(const peer::PeerId& peer, + const std::shared_ptr& connection) { + std::cout << "ConnectionManagerImpl::onConnectionClosed called for peer: " + << peer.toBase58() << std::endl; + std::cout << "Connection address: " << (void*)connection.get() << std::endl; + } +}; +} + +} + +int main() { + std::cout << "=== ПРОВЕРКА ВСЕХ ИСПРАВЛЕНИЙ КОМПИЛЯЦИИ ===" << std::endl; + + auto manager = std::make_shared(); + + auto callback = [manager](const libp2p::peer::PeerId& peer, + const std::shared_ptr& conn) { + manager->onConnectionClosed(peer, conn); + }; + + auto connection = std::make_shared(callback); + + std::cout << "1. Тестирование yamuxed_connection.cpp - приведение типа..." << std::endl; + connection->simulateCloseCallback(); + + std::cout << "2. Тестирование connection_manager_impl.cpp - сигнатура метода..." << std::endl; + libp2p::peer::PeerId peer; + manager->onConnectionClosed(peer, connection); + + std::cout << "=== ВСЕ ИСПРАВЛЕНИЯ РАБОТАЮТ КОРРЕКТНО ===" << std::endl; + return 0; +} \ No newline at end of file diff --git a/test_fix_verification b/test_fix_verification new file mode 100755 index 0000000000000000000000000000000000000000..ec898d6d018bd60692eef225111e4c3727f68ee6 GIT binary patch literal 76440 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 D_iW(U literal 0 HcmV?d00001 diff --git a/test_yamux_100_connections b/test_yamux_100_connections new file mode 100755 index 0000000000000000000000000000000000000000..72eb49dbf27ae4bd4a64343c8bfa5b12034a5428 GIT binary patch literal 79032 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Нагрузочный тест с 100 соединениями и исправлением мертвых колбэков + +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id; + PeerId(const std::string& id_) : id(id_) {} + std::string toBase58() const { return id; } + bool operator==(const PeerId& other) const { return id == other.id; } +}; +} +} + +namespace std { +template <> +struct hash { + size_t operator()(const libp2p::peer::PeerId& peer) const { + return hash()(peer.id); + } +}; +} + +namespace libp2p { + +namespace basic { + +// ИСПРАВЛЕННЫЙ Scheduler с очисткой мертвых колбэков +class ImprovedScheduler : public std::enable_shared_from_this { +public: + struct Handle { + int id = -1; + std::weak_ptr scheduler; + + void reset() { + if (auto sched = scheduler.lock()) { + sched->cancelHandle(id); + } + id = -1; + } + + bool has_value() const { return id >= 0; } + + Handle() = default; + Handle(int id_, std::weak_ptr sched) + : id(id_), scheduler(sched) {} + }; + + Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { + std::lock_guard lock(mutex_); + + int handle_id = next_id_++; + + scheduled_callbacks_[handle_id] = { + .callback = std::move(cb), + .execute_time = std::chrono::steady_clock::now() + delay, + .cancelled = false + }; + + total_scheduled_++; + return Handle(handle_id, weak_from_this()); + } + + void cancelHandle(int handle_id) { + std::lock_guard lock(mutex_); + + auto it = scheduled_callbacks_.find(handle_id); + if (it != scheduled_callbacks_.end()) { + it->second.cancelled = true; + total_cancelled_++; + } + } + + void processCallbacks() { + std::lock_guard lock(mutex_); + + auto now = std::chrono::steady_clock::now(); + std::vector to_execute; + std::vector to_remove; + + for (auto& [id, info] : scheduled_callbacks_) { + if (info.cancelled) { + to_remove.push_back(id); + } else if (info.execute_time <= now) { + to_execute.push_back(id); + } + } + + // ИСПРАВЛЕНИЕ: Удаляем отмененные колбэки + for (int id : to_remove) { + scheduled_callbacks_.erase(id); + } + + // Выполняем готовые колбэки + for (int id : to_execute) { + auto it = scheduled_callbacks_.find(id); + if (it != scheduled_callbacks_.end()) { + auto callback = std::move(it->second.callback); + scheduled_callbacks_.erase(it); // ИСПРАВЛЕНИЕ: удаляем сразу после выполнения + + mutex_.unlock(); + callback(); + mutex_.lock(); + + total_executed_++; + } + } + } + + void printStats() const { + std::lock_guard lock(mutex_); + std::cout << "[Scheduler] Stats: scheduled=" << total_scheduled_ + << ", executed=" << total_executed_ + << ", cancelled=" << total_cancelled_ + << ", active=" << scheduled_callbacks_.size() << std::endl; + + if (!scheduled_callbacks_.empty()) { + std::cout << " WARNING: " << scheduled_callbacks_.size() << " active callbacks!" << std::endl; + } + } + + size_t getActiveCallbacksCount() const { + std::lock_guard lock(mutex_); + return scheduled_callbacks_.size(); + } + +private: + mutable std::mutex mutex_; + + struct CallbackInfo { + std::function callback; + std::chrono::steady_clock::time_point execute_time; + bool cancelled; + }; + + std::unordered_map scheduled_callbacks_; + int next_id_ = 1; + int total_scheduled_ = 0; + int total_executed_ = 0; + int total_cancelled_ = 0; +}; + +using Scheduler = ImprovedScheduler; + +} // namespace basic + +namespace connection { + +// Оптимизированная эмуляция Stream +class OptimizedYamuxStream : public std::enable_shared_from_this { +public: + OptimizedYamuxStream(std::shared_ptr connection, uint32_t stream_id) + : connection_(connection), stream_id_(stream_id) {} + + ~OptimizedYamuxStream() = default; + + void simulateAsyncRead() { + auto conn = connection_.lock(); + if (conn) { + // Меньше логирования для производительности + } + } + + void close() { + connection_.reset(); + } + + uint32_t getId() const { return stream_id_; } + +private: + std::weak_ptr connection_; + uint32_t stream_id_; +}; + +struct SecureConnection { + peer::PeerId remote_peer; + bool closed = false; + std::atomic async_operations_count{0}; + + SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} + + peer::PeerId remotePeer() const { return remote_peer; } + bool isClosed() const { return closed; } + void close() { + closed = true; + } + + // Оптимизированное асинхронное чтение + void readSome(std::vector& buffer, size_t size, + std::function callback) { + async_operations_count++; + + // Симулируем асинхронную операцию с более коротким временем + std::thread([this, callback]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // Быстрее для 100 соединений + + if (!closed) { + callback(42); // 42 байта прочитано + } else { + callback(-1); // Ошибка при закрытии + } + + async_operations_count--; + }).detach(); + } + + void writeSome(const std::vector& data, + std::function callback) { + async_operations_count++; + + std::thread([this, callback]() { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + callback(closed ? -1 : 100); + async_operations_count--; + }).detach(); + } +}; + +// Оптимизированная версия YamuxedConnection +class YamuxedConnection : public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function)>; + + explicit YamuxedConnection( + std::shared_ptr connection, + std::shared_ptr scheduler, + ConnectionClosedCallback closed_callback, + int connection_id) + : connection_(std::move(connection)) + , scheduler_(std::move(scheduler)) + , closed_callback_(std::move(closed_callback)) + , remote_peer_(connection_->remotePeer()) + , raw_read_buffer_(1024) + , connection_id_(connection_id) {} + + ~YamuxedConnection() { + // Меньше логирования для 100 соединений + destroyed_count_++; + } + + void start() { + started_ = true; + + // Запускаем таймеры + setTimerCleanup(); + setTimerPing(); + + // Запускаем чтение + continueReading(); + + // Создаем меньше потоков для производительности + createMockStreams(); + } + + void stop() { + if (!started_) return; + + started_ = false; + + // ИСПРАВЛЕНИЕ: отменяем все таймеры + cancelAllTimers(); + + // Закрываем потоки + closeAllStreams(); + } + + void close() { + if (closed_) return; + + auto self_ptr = shared_from_this(); + + closed_ = true; + connection_->close(); + + // ИСПРАВЛЕНИЕ: отменяем все таймеры + cancelAllTimers(); + + // Закрываем потоки + closeAllStreams(); + + // Вызываем callback для ConnectionManager + if (closed_callback_ && registered_in_manager_) { + closed_callback_(remote_peer_, self_ptr); + } + } + + bool isClosed() const { return closed_; } + peer::PeerId remotePeer() const { return remote_peer_; } + + void markAsRegistered() { + registered_in_manager_ = true; + } + + long getSharedPtrUseCount() const { + auto self_ptr = shared_from_this(); + return self_ptr.use_count(); + } + + int getConnectionId() const { return connection_id_; } + + static int getDestroyedCount() { return destroyed_count_; } + +private: + // ИСПРАВЛЕННОЕ continueReading с проверкой состояния + void continueReading() { + if (!started_ || closed_) return; + + auto weak_self = std::weak_ptr(shared_from_this()); + + connection_->readSome(raw_read_buffer_, raw_read_buffer_.size(), + [weak_self](int bytes_read) { + auto self = weak_self.lock(); + if (!self) { + // ИСПРАВЛЕНИЕ: не создаем лишних операций для мертвых объектов + return; + } + self->onRead(bytes_read); + }); + } + + void onRead(int bytes_read) { + if (!started_ || closed_) return; // ИСПРАВЛЕНИЕ: дополнительная проверка + + if (bytes_read < 0) { + close(); + return; + } + + // Продолжаем чтение только если соединение активно + if (started_ && !closed_) { + continueReading(); + } + } + + void createMockStreams() { + // Создаем только 1 поток для производительности + auto stream = std::make_shared(shared_from_this(), 1); + streams_[1] = stream; + stream->simulateAsyncRead(); + } + + void closeAllStreams() { + for (auto& [id, stream] : streams_) { + if (stream) { + stream->close(); + } + } + streams_.clear(); + } + + void setTimerCleanup() { + auto weak_self = std::weak_ptr(shared_from_this()); + + cleanup_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self || !self->started_) return; + + // Очистка потоков + self->cleanupAbandonedStreams(); + + // Рекурсивный вызов только если соединение активно + if (self->started_ && !self->closed_) { + self->setTimerCleanup(); + } + }, + std::chrono::milliseconds(200) // Увеличили интервал для производительности + ); + } + + void setTimerPing() { + auto weak_self = std::weak_ptr(shared_from_this()); + + ping_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self || !self->started_) return; + + // Отправляем ping + self->sendPing(); + + // Рекурсивный вызов только если соединение активно + if (self->started_ && !self->closed_) { + self->setTimerPing(); + } + }, + std::chrono::milliseconds(150) // Увеличили интервал + ); + } + + void cleanupAbandonedStreams() { + // Оптимизированная очистка + } + + void sendPing() { + std::vector ping_data = {0x01}; + auto weak_self = std::weak_ptr(shared_from_this()); + + connection_->writeSome(ping_data, [weak_self](int result) { + // Минимальная обработка для производительности + }); + } + + void cancelAllTimers() { + ping_handle_.reset(); + cleanup_handle_.reset(); + } + +private: + std::shared_ptr connection_; + std::shared_ptr scheduler_; + ConnectionClosedCallback closed_callback_; + peer::PeerId remote_peer_; + bool started_ = false; + bool closed_ = false; + bool registered_in_manager_ = false; + int connection_id_; + + std::vector raw_read_buffer_; + std::unordered_map> streams_; + + basic::Scheduler::Handle ping_handle_; + basic::Scheduler::Handle cleanup_handle_; + + static std::atomic destroyed_count_; +}; + +std::atomic YamuxedConnection::destroyed_count_{0}; + +} // namespace connection + +namespace network { + +class ConnectionManagerTest { +public: + using ConnectionSPtr = std::shared_ptr; + + void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { + std::lock_guard lock(mutex_); + connections_[peer].insert(conn); + total_connections_++; + } + + void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { + std::lock_guard lock(mutex_); + + auto it = connections_.find(peer); + if (it != connections_.end()) { + it->second.erase(connection); + if (it->second.empty()) { + connections_.erase(it); + } + } + + total_connections_--; + closed_connections_++; + } + + size_t getTotalConnections() const { + std::lock_guard lock(mutex_); + size_t total = 0; + for (const auto& [peer, conns] : connections_) { + total += conns.size(); + } + return total; + } + + void printStats() const { + std::lock_guard lock(mutex_); + std::cout << "[ConnectionManager] Active: " << getTotalConnections() + << ", Closed: " << closed_connections_ << std::endl; + } + +private: + mutable std::mutex mutex_; + std::unordered_map> connections_; + int total_connections_ = 0; + int closed_connections_ = 0; +}; + +} // namespace network +} // namespace libp2p + +class LoadTestYamux100Connections { +public: + void runTest() { + std::cout << "\n=== YAMUX LOAD TEST: 100 CONNECTIONS ===" << std::endl; + + auto scheduler = std::make_shared(); + auto connection_manager = std::make_shared(); + + std::vector> connections; + + auto start_time = std::chrono::high_resolution_clock::now(); + + // Создаем 100 соединений + std::cout << "\n--- Creating 100 connections ---" << std::endl; + { + for (int i = 0; i < 100; ++i) { + std::ostringstream oss; + oss << "peer_" << std::setfill('0') << std::setw(3) << i; + auto peer_id = oss.str(); + + auto secure_conn = std::make_shared(peer_id); + + auto callback = [connection_manager](const libp2p::peer::PeerId& peer, + std::shared_ptr conn) { + connection_manager->onConnectionClosed(peer, conn); + }; + + auto yamux_conn = std::make_shared( + secure_conn, scheduler, callback, i); + + yamux_conn->markAsRegistered(); + connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); + + yamux_conn->start(); + connections.push_back(yamux_conn); + + if ((i + 1) % 20 == 0) { + std::cout << "Created " << (i + 1) << " connections..." << std::endl; + } + } + } + + auto creation_time = std::chrono::high_resolution_clock::now(); + auto creation_duration = std::chrono::duration_cast(creation_time - start_time); + + std::cout << "\n--- Initial state ---" << std::endl; + std::cout << "Created 100 connections in " << creation_duration.count() << "ms" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Даем время на работу системы + std::cout << "\n--- Running system for 1 second ---" << std::endl; + for (int i = 0; i < 20; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + std::cout << "\n--- After initial workload ---" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Закрываем все соединения + std::cout << "\n--- Closing all connections ---" << std::endl; + auto close_start = std::chrono::high_resolution_clock::now(); + + for (auto& conn : connections) { + conn->close(); + } + + auto close_time = std::chrono::high_resolution_clock::now(); + auto close_duration = std::chrono::duration_cast(close_time - close_start); + + std::cout << "Closed 100 connections in " << close_duration.count() << "ms" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Очищаем локальные ссылки + connections.clear(); + + std::cout << "\n--- After clearing local references ---" << std::endl; + std::cout << "Destroyed objects: " << libp2p::connection::YamuxedConnection::getDestroyedCount() << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Финальная очистка + std::cout << "\n--- Final cleanup (2 seconds) ---" << std::endl; + for (int i = 0; i < 40; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + auto end_time = std::chrono::high_resolution_clock::now(); + auto total_duration = std::chrono::duration_cast(end_time - start_time); + + std::cout << "\n=== FINAL RESULTS ===" << std::endl; + std::cout << "Total test time: " << total_duration.count() << "ms" << std::endl; + std::cout << "Destroyed objects: " << libp2p::connection::YamuxedConnection::getDestroyedCount() << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + if (scheduler->getActiveCallbacksCount() > 0) { + std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; + std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; + } else { + std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; + std::cout << "All callbacks properly cleaned up!" << std::endl; + } + + if (libp2p::connection::YamuxedConnection::getDestroyedCount() == 100) { + std::cout << "✅ All 100 connections properly destroyed!" << std::endl; + } else { + std::cout << "❌ Some connections were not destroyed!" << std::endl; + } + } +}; + +int main() { + LoadTestYamux100Connections test; + test.runTest(); + return 0; +} \ No newline at end of file diff --git a/test_yamux_10_simple b/test_yamux_10_simple new file mode 100755 index 0000000000000000000000000000000000000000..3d8a23a55f336d2229f90a3e354cec0a0596c658 GIT binary patch literal 60384 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 literal 0 HcmV?d00001 diff --git a/test_yamux_10_simple.cpp b/test_yamux_10_simple.cpp new file mode 100644 index 00000000..6748a404 --- /dev/null +++ b/test_yamux_10_simple.cpp @@ -0,0 +1,456 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Простой тест с 10 соединениями для демонстрации исправления + +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id; + PeerId(const std::string& id_) : id(id_) {} + std::string toBase58() const { return id; } + bool operator==(const PeerId& other) const { return id == other.id; } +}; +} +} + +namespace std { +template <> +struct hash { + size_t operator()(const libp2p::peer::PeerId& peer) const { + return hash()(peer.id); + } +}; +} + +namespace libp2p { + +namespace basic { + +// ИСПРАВЛЕННЫЙ Scheduler с правильной очисткой +class FixedScheduler : public std::enable_shared_from_this { +public: + struct Handle { + int id = -1; + std::weak_ptr scheduler; + + void reset() { + if (auto sched = scheduler.lock()) { + sched->cancelHandle(id); + } + id = -1; + } + + bool has_value() const { return id >= 0; } + + Handle() = default; + Handle(int id_, std::weak_ptr sched) + : id(id_), scheduler(sched) {} + }; + + Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { + std::lock_guard lock(mutex_); + + int handle_id = next_id_++; + + scheduled_callbacks_[handle_id] = { + .callback = std::move(cb), + .execute_time = std::chrono::steady_clock::now() + delay, + .cancelled = false + }; + + total_scheduled_++; + std::cout << "[Scheduler] Scheduled " << handle_id << " (total active: " << scheduled_callbacks_.size() << ")" << std::endl; + + return Handle(handle_id, weak_from_this()); + } + + void cancelHandle(int handle_id) { + std::lock_guard lock(mutex_); + + auto it = scheduled_callbacks_.find(handle_id); + if (it != scheduled_callbacks_.end()) { + it->second.cancelled = true; + total_cancelled_++; + std::cout << "[Scheduler] Cancelled " << handle_id << std::endl; + } + } + + void processCallbacks() { + std::lock_guard lock(mutex_); + + auto now = std::chrono::steady_clock::now(); + std::vector to_execute; + std::vector to_remove; + + // Собираем ID для удаления и выполнения + for (auto& [id, info] : scheduled_callbacks_) { + if (info.cancelled) { + to_remove.push_back(id); + } else if (info.execute_time <= now) { + to_execute.push_back(id); + } + } + + // ИСПРАВЛЕНИЕ 1: Удаляем отмененные колбэки СРАЗУ + for (int id : to_remove) { + scheduled_callbacks_.erase(id); + std::cout << "[Scheduler] Removed cancelled callback " << id << std::endl; + } + + // ИСПРАВЛЕНИЕ 2: Выполняем и удаляем колбэки + for (int id : to_execute) { + auto it = scheduled_callbacks_.find(id); + if (it != scheduled_callbacks_.end()) { + auto callback = std::move(it->second.callback); + scheduled_callbacks_.erase(it); // Удаляем ПЕРЕД выполнением + + mutex_.unlock(); + std::cout << "[Scheduler] Executing " << id << std::endl; + callback(); + mutex_.lock(); + + total_executed_++; + } + } + } + + void printStats() const { + std::lock_guard lock(mutex_); + std::cout << "[Scheduler] Total: sched=" << total_scheduled_ + << ", exec=" << total_executed_ + << ", canc=" << total_cancelled_ + << ", active=" << scheduled_callbacks_.size() << std::endl; + + if (!scheduled_callbacks_.empty()) { + std::cout << " ⚠️ LEAK: " << scheduled_callbacks_.size() << " active callbacks!" << std::endl; + } + } + + size_t getActiveCallbacksCount() const { + std::lock_guard lock(mutex_); + return scheduled_callbacks_.size(); + } + +private: + mutable std::mutex mutex_; + + struct CallbackInfo { + std::function callback; + std::chrono::steady_clock::time_point execute_time; + bool cancelled; + }; + + std::unordered_map scheduled_callbacks_; + int next_id_ = 1; + int total_scheduled_ = 0; + int total_executed_ = 0; + int total_cancelled_ = 0; +}; + +using Scheduler = FixedScheduler; + +} // namespace basic + +namespace connection { + +// Простая версия без многопоточности +class SimpleYamuxedConnection : public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function)>; + + explicit SimpleYamuxedConnection( + const std::string& peer_id, + std::shared_ptr scheduler, + ConnectionClosedCallback closed_callback, + int connection_id) + : scheduler_(std::move(scheduler)) + , closed_callback_(std::move(closed_callback)) + , remote_peer_(peer_id) + , connection_id_(connection_id) { + + std::cout << "[Connection-" << connection_id_ << "] Created for " << peer_id << std::endl; + } + + ~SimpleYamuxedConnection() { + std::cout << "[Connection-" << connection_id_ << "] *** DESTROYED ***" << std::endl; + destroyed_count_++; + } + + void start() { + started_ = true; + std::cout << "[Connection-" << connection_id_ << "] Started" << std::endl; + + // Запускаем таймеры + setTimerCleanup(); + setTimerPing(); + } + + void close() { + if (closed_) return; + + auto self_ptr = shared_from_this(); + std::cout << "[Connection-" << connection_id_ << "] Closing (use_count: " << self_ptr.use_count() << ")" << std::endl; + + closed_ = true; + started_ = false; // Останавливаем таймеры + + // ИСПРАВЛЕНИЕ: отменяем все таймеры + cancelAllTimers(); + + // Вызываем callback для ConnectionManager + if (closed_callback_ && registered_in_manager_) { + std::cout << "[Connection-" << connection_id_ << "] Calling closed_callback_" << std::endl; + closed_callback_(remote_peer_, self_ptr); + } + + std::cout << "[Connection-" << connection_id_ << "] Closed (final use_count: " << self_ptr.use_count() << ")" << std::endl; + } + + bool isClosed() const { return closed_; } + peer::PeerId remotePeer() const { return remote_peer_; } + + void markAsRegistered() { + registered_in_manager_ = true; + } + + int getConnectionId() const { return connection_id_; } + + static int getDestroyedCount() { return destroyed_count_; } + +private: + void setTimerCleanup() { + auto weak_self = std::weak_ptr(shared_from_this()); + + cleanup_handle_ = scheduler_->scheduleWithHandle( + [weak_self, id = connection_id_]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Cleanup-" << id << ": object destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Cleanup-" << id << ": connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Cleanup-" << id << ": executed" << std::endl; + + // Рекурсивный вызов только если активно + if (self->started_ && !self->closed_) { + self->setTimerCleanup(); + } + }, + std::chrono::milliseconds(300) + ); + } + + void setTimerPing() { + auto weak_self = std::weak_ptr(shared_from_this()); + + ping_handle_ = scheduler_->scheduleWithHandle( + [weak_self, id = connection_id_]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Ping-" << id << ": object destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Ping-" << id << ": connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Ping-" << id << ": executed" << std::endl; + + // Рекурсивный вызов только если активно + if (self->started_ && !self->closed_) { + self->setTimerPing(); + } + }, + std::chrono::milliseconds(200) + ); + } + + void cancelAllTimers() { + std::cout << "[Connection-" << connection_id_ << "] === CANCELLING TIMERS ===" << std::endl; + + ping_handle_.reset(); + cleanup_handle_.reset(); + + std::cout << "[Connection-" << connection_id_ << "] === TIMERS CANCELLED ===" << std::endl; + } + +private: + std::shared_ptr scheduler_; + ConnectionClosedCallback closed_callback_; + peer::PeerId remote_peer_; + bool started_ = false; + bool closed_ = false; + bool registered_in_manager_ = false; + int connection_id_; + + basic::Scheduler::Handle ping_handle_; + basic::Scheduler::Handle cleanup_handle_; + + static std::atomic destroyed_count_; +}; + +std::atomic SimpleYamuxedConnection::destroyed_count_{0}; + +} // namespace connection + +namespace network { + +class ConnectionManagerTest { +public: + using ConnectionSPtr = std::shared_ptr; + + void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { + connections_[peer].insert(conn); + std::cout << "[Manager] Added connection " << conn->getConnectionId() << " for " << peer.toBase58() << std::endl; + } + + void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { + std::cout << "[Manager] onConnectionClosed for " << peer.toBase58() + << " (connection " << connection->getConnectionId() << ")" << std::endl; + + auto it = connections_.find(peer); + if (it != connections_.end()) { + it->second.erase(connection); + if (it->second.empty()) { + connections_.erase(it); + std::cout << "[Manager] Removed peer " << peer.toBase58() << std::endl; + } + } + } + + size_t getTotalConnections() const { + size_t total = 0; + for (const auto& [peer, conns] : connections_) { + total += conns.size(); + } + return total; + } + + void printStats() const { + std::cout << "[Manager] Active connections: " << getTotalConnections() << std::endl; + } + +private: + std::unordered_map> connections_; +}; + +} // namespace network +} // namespace libp2p + +class SimpleTest10Connections { +public: + void runTest() { + std::cout << "\n=== SIMPLE YAMUX TEST: 10 CONNECTIONS ===" << std::endl; + + auto scheduler = std::make_shared(); + auto connection_manager = std::make_shared(); + + std::vector> connections; + + // Создаем 10 соединений + std::cout << "\n--- Creating 10 connections ---" << std::endl; + { + for (int i = 0; i < 10; ++i) { + std::ostringstream oss; + oss << "peer_" << std::setfill('0') << std::setw(2) << i; + auto peer_id = oss.str(); + + auto callback = [connection_manager](const libp2p::peer::PeerId& peer, + std::shared_ptr conn) { + connection_manager->onConnectionClosed(peer, conn); + }; + + auto yamux_conn = std::make_shared( + peer_id, scheduler, callback, i); + + yamux_conn->markAsRegistered(); + connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); + + yamux_conn->start(); + connections.push_back(yamux_conn); + } + } + + std::cout << "\n--- Initial state ---" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Работа системы + std::cout << "\n--- Running system (500ms) ---" << std::endl; + for (int i = 0; i < 5; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + scheduler->processCallbacks(); + } + + std::cout << "\n--- After workload ---" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Закрываем все соединения + std::cout << "\n--- Closing all connections ---" << std::endl; + for (auto& conn : connections) { + conn->close(); + } + + std::cout << "\n--- After close() calls ---" << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Очищаем локальные ссылки + connections.clear(); + + std::cout << "\n--- After clearing local references ---" << std::endl; + std::cout << "Destroyed objects: " << libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + // Финальная очистка + std::cout << "\n--- Final cleanup (1 second) ---" << std::endl; + for (int i = 0; i < 10; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + scheduler->processCallbacks(); + } + + std::cout << "\n=== FINAL RESULTS ===" << std::endl; + std::cout << "Destroyed objects: " << libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() << std::endl; + connection_manager->printStats(); + scheduler->printStats(); + + if (scheduler->getActiveCallbacksCount() > 0) { + std::cout << "\n❌ MEMORY LEAK DETECTED!" << std::endl; + std::cout << "Active callbacks: " << scheduler->getActiveCallbacksCount() << std::endl; + } else { + std::cout << "\n✅ NO MEMORY LEAKS!" << std::endl; + std::cout << "All callbacks properly cleaned up!" << std::endl; + } + + if (libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() == 10) { + std::cout << "✅ All 10 connections properly destroyed!" << std::endl; + } else { + std::cout << "❌ Some connections were not destroyed!" << std::endl; + } + } +}; + +int main() { + SimpleTest10Connections test; + test.runTest(); + return 0; +} \ No newline at end of file diff --git a/test_yamux_complete b/test_yamux_complete new file mode 100755 index 0000000000000000000000000000000000000000..b2f90f9abf262f02df07833934492493342b2642 GIT binary patch literal 366736 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%0A6M(`E%+Y4l;>4H{7m3> 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 literal 0 HcmV?d00001 diff --git a/test_yamux_complete.cpp b/test_yamux_complete.cpp new file mode 100644 index 00000000..cc207567 --- /dev/null +++ b/test_yamux_complete.cpp @@ -0,0 +1,637 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Полный тест утечек памяти в YamuxedConnection с максимальной точностью + +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id; + PeerId(const std::string& id_) : id(id_) {} + std::string toBase58() const { return id; } + bool operator==(const PeerId& other) const { return id == other.id; } +}; +} +} + +namespace std { +template <> +struct hash { + size_t operator()(const libp2p::peer::PeerId& peer) const { + return hash()(peer.id); + } +}; +} + +namespace libp2p { + +namespace basic { + +// Полная эмуляция Scheduler +class CompleteScheduler : public std::enable_shared_from_this { +public: + struct Handle { + int id = -1; + std::weak_ptr scheduler; + + void reset() { + if (auto sched = scheduler.lock()) { + sched->cancelHandle(id); + } + id = -1; + } + + bool has_value() const { return id >= 0; } + + Handle() = default; + Handle(int id_, std::weak_ptr sched) + : id(id_), scheduler(sched) {} + }; + + Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { + std::lock_guard lock(mutex_); + + int handle_id = next_id_++; + + scheduled_callbacks_[handle_id] = { + .callback = std::move(cb), + .execute_time = std::chrono::steady_clock::now() + delay, + .cancelled = false + }; + + total_scheduled_++; + std::cout << "[Scheduler] Scheduled callback " << handle_id + << ", total active: " << scheduled_callbacks_.size() << std::endl; + + return Handle(handle_id, weak_from_this()); + } + + void cancelHandle(int handle_id) { + std::lock_guard lock(mutex_); + + auto it = scheduled_callbacks_.find(handle_id); + if (it != scheduled_callbacks_.end()) { + it->second.cancelled = true; + total_cancelled_++; + std::cout << "[Scheduler] Cancelled callback " << handle_id + << ", total active: " << scheduled_callbacks_.size() << std::endl; + } + } + + void processCallbacks() { + std::lock_guard lock(mutex_); + + auto now = std::chrono::steady_clock::now(); + std::vector to_execute; + + for (auto& [id, info] : scheduled_callbacks_) { + if (!info.cancelled && info.execute_time <= now) { + to_execute.push_back(id); + } + } + + for (int id : to_execute) { + auto it = scheduled_callbacks_.find(id); + if (it != scheduled_callbacks_.end() && !it->second.cancelled) { + auto callback = std::move(it->second.callback); + scheduled_callbacks_.erase(it); + + mutex_.unlock(); + std::cout << "[Scheduler] Executing callback " << id << std::endl; + callback(); + mutex_.lock(); + + total_executed_++; + } + } + } + + void printStats() const { + std::lock_guard lock(mutex_); + std::cout << "[Scheduler] Stats:" << std::endl; + std::cout << " Total scheduled: " << total_scheduled_ << std::endl; + std::cout << " Total executed: " << total_executed_ << std::endl; + std::cout << " Total cancelled: " << total_cancelled_ << std::endl; + std::cout << " Currently active: " << scheduled_callbacks_.size() << std::endl; + + if (!scheduled_callbacks_.empty()) { + std::cout << " WARNING: Non-zero active callbacks - potential memory leak!" << std::endl; + } + } + + size_t getActiveCallbacksCount() const { + std::lock_guard lock(mutex_); + return scheduled_callbacks_.size(); + } + +private: + mutable std::mutex mutex_; + + struct CallbackInfo { + std::function callback; + std::chrono::steady_clock::time_point execute_time; + bool cancelled; + }; + + std::unordered_map scheduled_callbacks_; + int next_id_ = 1; + int total_scheduled_ = 0; + int total_executed_ = 0; + int total_cancelled_ = 0; +}; + +using Scheduler = CompleteScheduler; + +} // namespace basic + +namespace connection { + +// Эмуляция Stream +class MockYamuxStream : public std::enable_shared_from_this { +public: + MockYamuxStream(std::shared_ptr connection, uint32_t stream_id) + : connection_(connection), stream_id_(stream_id) { + std::cout << "[MockYamuxStream] Created stream " << stream_id_ << std::endl; + } + + ~MockYamuxStream() { + std::cout << "[MockYamuxStream] Destroyed stream " << stream_id_ << std::endl; + } + + void simulateAsyncRead() { + // Симулируем асинхронное чтение, которое держит ссылку на соединение + auto conn = connection_.lock(); + if (conn) { + std::cout << "[MockYamuxStream] Stream " << stream_id_ << " performing async read" << std::endl; + // В реальном коде здесь были бы колбэки с shared_ptr + } + } + + void close() { + std::cout << "[MockYamuxStream] Closing stream " << stream_id_ << std::endl; + connection_.reset(); + } + + uint32_t getId() const { return stream_id_; } + +private: + std::weak_ptr connection_; // Важно: weak_ptr! + uint32_t stream_id_; +}; + +struct SecureConnection { + peer::PeerId remote_peer; + bool closed = false; + std::atomic async_operations_count{0}; + + SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} + + peer::PeerId remotePeer() const { return remote_peer; } + bool isClosed() const { return closed; } + void close() { + closed = true; + std::cout << "[SecureConnection] Closed, pending operations: " + << async_operations_count.load() << std::endl; + } + + // Симуляция асинхронного чтения (как continueReading) + void readSome(std::vector& buffer, size_t size, + std::function callback) { + async_operations_count++; + std::cout << "[SecureConnection] Starting async read operation (total: " + << async_operations_count.load() << ")" << std::endl; + + // Симулируем асинхронную операцию + std::thread([this, callback]() { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + if (!closed) { + // Симулируем успешное чтение + callback(42); // 42 байта прочитано + } else { + // Симулируем ошибку при закрытии + callback(-1); + } + + async_operations_count--; + std::cout << "[SecureConnection] Async read completed (remaining: " + << async_operations_count.load() << ")" << std::endl; + }).detach(); + } + + void writeSome(const std::vector& data, + std::function callback) { + async_operations_count++; + std::cout << "[SecureConnection] Starting async write operation" << std::endl; + + std::thread([this, callback]() { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + callback(closed ? -1 : 100); // 100 байт записано + async_operations_count--; + }).detach(); + } +}; + +// Полная версия YamuxedConnection +class YamuxedConnection : public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function)>; + + explicit YamuxedConnection( + std::shared_ptr connection, + std::shared_ptr scheduler, + ConnectionClosedCallback closed_callback) + : connection_(std::move(connection)) + , scheduler_(std::move(scheduler)) + , closed_callback_(std::move(closed_callback)) + , remote_peer_(connection_->remotePeer()) + , raw_read_buffer_(1024) { + + std::cout << "[YamuxedConnection] Created connection to " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + ~YamuxedConnection() { + std::cout << "[YamuxedConnection] *** DESTRUCTOR *** for " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + void start() { + started_ = true; + std::cout << "[YamuxedConnection] Started connection to " + << remote_peer_.toBase58() << std::endl; + + // Запускаем таймеры (как в реальном коде) + setTimerCleanup(); + setTimerPing(); + + // ВАЖНО: запускаем чтение (как в реальном коде!) + continueReading(); + + // Симулируем создание потоков + createMockStreams(); + } + + void stop() { + if (!started_) return; + + started_ = false; + std::cout << "[YamuxedConnection] Stopping connection to " + << remote_peer_.toBase58() << std::endl; + + // ИСПРАВЛЕНИЕ: отменяем все таймеры + cancelAllTimers(); + + // Закрываем потоки + closeAllStreams(); + } + + void close() { + if (closed_) return; + + auto self_ptr = shared_from_this(); + std::cout << "[YamuxedConnection] Closing connection to " + << remote_peer_.toBase58() + << " (use_count: " << self_ptr.use_count() << ")" << std::endl; + + closed_ = true; + connection_->close(); + + // ИСПРАВЛЕНИЕ: отменяем все таймеры + cancelAllTimers(); + + // Закрываем потоки + closeAllStreams(); + + // Вызываем callback для ConnectionManager + if (closed_callback_ && registered_in_manager_) { + std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " + << self_ptr.use_count() << std::endl; + + closed_callback_(remote_peer_, self_ptr); + } + } + + bool isClosed() const { return closed_; } + peer::PeerId remotePeer() const { return remote_peer_; } + + void markAsRegistered() { + registered_in_manager_ = true; + } + + long getSharedPtrUseCount() const { + auto self_ptr = shared_from_this(); + return self_ptr.use_count(); + } + +private: + // Эмуляция continueReading (КЛЮЧЕВОЕ отличие от простого теста!) + void continueReading() { + if (!started_ || closed_) return; + + std::cout << "[YamuxedConnection] continueReading() called" << std::endl; + + // В реальном коде здесь weak_from_this() захватывается в колбэк + auto weak_self = std::weak_ptr(shared_from_this()); + + connection_->readSome(raw_read_buffer_, raw_read_buffer_.size(), + [weak_self](int bytes_read) { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[ReadCallback] Connection already destroyed" << std::endl; + return; + } + self->onRead(bytes_read); + }); + } + + void onRead(int bytes_read) { + if (!started_) return; + + std::cout << "[YamuxedConnection] onRead: " << bytes_read << " bytes" << std::endl; + + if (bytes_read < 0) { + // Ошибка чтения - закрываем соединение + close(); + return; + } + + // Симулируем обработку данных + processReceivedData(); + + // ВАЖНО: продолжаем чтение (создает новую асинхронную операцию!) + continueReading(); + } + + void processReceivedData() { + // Симулируем создание новых потоков при получении данных + std::cout << "[YamuxedConnection] Processing received data" << std::endl; + } + + void createMockStreams() { + // Симулируем создание потоков + for (uint32_t i = 1; i <= 3; ++i) { + auto stream = std::make_shared(shared_from_this(), i); + streams_[i] = stream; + + // Симулируем асинхронные операции потоков + stream->simulateAsyncRead(); + } + + std::cout << "[YamuxedConnection] Created " << streams_.size() << " streams" << std::endl; + } + + void closeAllStreams() { + std::cout << "[YamuxedConnection] Closing " << streams_.size() << " streams" << std::endl; + + for (auto& [id, stream] : streams_) { + if (stream) { + stream->close(); + } + } + streams_.clear(); + } + + void setTimerCleanup() { + auto weak_self = std::weak_ptr(shared_from_this()); + + cleanup_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Cleanup: object already destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Cleanup: connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Cleanup executed for " << self->remote_peer_.toBase58() << std::endl; + + // Очистка потоков + self->cleanupAbandonedStreams(); + + // ПРОБЛЕМА: рекурсивный вызов! + self->setTimerCleanup(); + }, + std::chrono::milliseconds(150) + ); + + std::cout << "[YamuxedConnection] Set cleanup timer for " << remote_peer_.toBase58() << std::endl; + } + + void setTimerPing() { + auto weak_self = std::weak_ptr(shared_from_this()); + + ping_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Ping: object already destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Ping: connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Ping executed for " << self->remote_peer_.toBase58() << std::endl; + + // Симулируем отправку ping + self->sendPing(); + + // ПРОБЛЕМА: рекурсивный вызов! + self->setTimerPing(); + }, + std::chrono::milliseconds(100) + ); + + std::cout << "[YamuxedConnection] Set ping timer for " << remote_peer_.toBase58() << std::endl; + } + + void cleanupAbandonedStreams() { + std::cout << "[YamuxedConnection] Cleanup: checking " << streams_.size() << " streams" << std::endl; + // В реальном коде здесь проверяется use_count потоков + } + + void sendPing() { + // Симулируем асинхронную отправку ping + std::vector ping_data = {0x01, 0x02, 0x03}; + auto weak_self = std::weak_ptr(shared_from_this()); + + connection_->writeSome(ping_data, [weak_self](int result) { + auto self = weak_self.lock(); + if (self) { + std::cout << "[YamuxedConnection] Ping sent, result: " << result << std::endl; + } + }); + } + + void cancelAllTimers() { + std::cout << "[YamuxedConnection] === CANCELLING ALL TIMERS === for " << remote_peer_.toBase58() << std::endl; + + ping_handle_.reset(); + cleanup_handle_.reset(); + + std::cout << "[YamuxedConnection] === ALL TIMERS CANCELLED ===" << std::endl; + } + +private: + std::shared_ptr connection_; + std::shared_ptr scheduler_; + ConnectionClosedCallback closed_callback_; + peer::PeerId remote_peer_; + bool started_ = false; + bool closed_ = false; + bool registered_in_manager_ = false; + + // Буфер для чтения (как в реальном коде) + std::vector raw_read_buffer_; + + // Потоки (как streams_ в реальном коде) + std::unordered_map> streams_; + + // Таймеры + basic::Scheduler::Handle ping_handle_; + basic::Scheduler::Handle cleanup_handle_; +}; + +} // namespace connection + +namespace network { + +class ConnectionManagerTest { +public: + using ConnectionSPtr = std::shared_ptr; + + void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { + connections_[peer].insert(conn); + std::cout << "[ConnectionManager] Added connection for " << peer.toBase58() + << " (total: " << connections_[peer].size() << ")" << std::endl; + } + + void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { + std::cout << "[ConnectionManager] onConnectionClosed for " << peer.toBase58() + << " (use_count: " << connection.use_count() << ")" << std::endl; + + auto it = connections_.find(peer); + if (it != connections_.end()) { + it->second.erase(connection); + if (it->second.empty()) { + connections_.erase(it); + std::cout << "[ConnectionManager] Removed peer " << peer.toBase58() << std::endl; + } + } + + std::cout << "[ConnectionManager] Final use_count: " << connection.use_count() << std::endl; + } + + size_t getTotalConnections() const { + size_t total = 0; + for (const auto& [peer, conns] : connections_) { + total += conns.size(); + } + return total; + } + +private: + std::unordered_map> connections_; +}; + +} // namespace network +} // namespace libp2p + +class CompleteYamuxLeakTest { +public: + void runTest() { + std::cout << "\n=== COMPLETE YAMUX MEMORY LEAK TEST ===" << std::endl; + + auto scheduler = std::make_shared(); + auto connection_manager = std::make_shared(); + + auto peer_id = "complete_test_peer"; + auto secure_conn = std::make_shared(peer_id); + + auto callback = [connection_manager](const libp2p::peer::PeerId& peer, + std::shared_ptr conn) { + connection_manager->onConnectionClosed(peer, conn); + }; + + { + auto yamux_conn = std::make_shared( + secure_conn, scheduler, callback); + + yamux_conn->markAsRegistered(); + connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); + + std::cout << "\n--- Starting connection (full simulation) ---" << std::endl; + yamux_conn->start(); + + std::cout << "\n--- Initial state ---" << std::endl; + std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; + std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; + scheduler->printStats(); + + // Даем время на выполнение асинхронных операций + std::cout << "\n--- Running async operations (500ms) ---" << std::endl; + for (int i = 0; i < 10; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + std::cout << "\n--- After async operations ---" << std::endl; + std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; + scheduler->printStats(); + + std::cout << "\n--- Closing connection ---" << std::endl; + yamux_conn->close(); + + std::cout << "\n--- After close() call ---" << std::endl; + std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; + scheduler->printStats(); + } + + std::cout << "\n--- After yamux_conn goes out of scope ---" << std::endl; + std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; + scheduler->printStats(); + + // Финальная очистка + std::cout << "\n--- Final cleanup (1000ms) ---" << std::endl; + for (int i = 0; i < 20; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + std::cout << "\n=== FINAL RESULTS ===" << std::endl; + std::cout << "Active connections: " << connection_manager->getTotalConnections() << std::endl; + scheduler->printStats(); + + if (scheduler->getActiveCallbacksCount() > 0) { + std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; + std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; + std::cout << "This indicates that timers were not properly cancelled!" << std::endl; + } else { + std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; + std::cout << "All async operations completed and timers cancelled properly." << std::endl; + } + } +}; + +int main() { + CompleteYamuxLeakTest test; + test.runTest(); + return 0; +} \ No newline at end of file diff --git a/test_yamux_leaks b/test_yamux_leaks new file mode 100755 index 0000000000000000000000000000000000000000..42c93cb373d87421d5b57b61c88a760ee165f7a6 GIT binary patch literal 239088 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Реалистичный тест утечек памяти в YamuxedConnection + +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id; + PeerId(const std::string& id_) : id(id_) {} + std::string toBase58() const { return id; } + bool operator==(const PeerId& other) const { return id == other.id; } +}; +} +} + +namespace std { +template <> +struct hash { + size_t operator()(const libp2p::peer::PeerId& peer) const { + return hash()(peer.id); + } +}; +} + +namespace libp2p { + +namespace basic { + +// Реалистичная эмуляция Scheduler с накоплением колбэков +class RealisticScheduler : public std::enable_shared_from_this { +public: + struct Handle { + int id = -1; + std::weak_ptr scheduler; + + void reset() { + if (auto sched = scheduler.lock()) { + sched->cancelHandle(id); + } + id = -1; + } + + bool has_value() const { return id >= 0; } + + Handle() = default; + Handle(int id_, std::weak_ptr sched) + : id(id_), scheduler(sched) {} + }; + + Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { + std::lock_guard lock(mutex_); + + int handle_id = next_id_++; + + // Эмулируем хранение колбэков в Scheduler (это источник утечки!) + scheduled_callbacks_[handle_id] = { + .callback = std::move(cb), + .execute_time = std::chrono::steady_clock::now() + delay, + .cancelled = false + }; + + total_scheduled_++; + std::cout << "[Scheduler] Scheduled callback " << handle_id + << ", total active: " << scheduled_callbacks_.size() << std::endl; + + return Handle(handle_id, weak_from_this()); + } + + void cancelHandle(int handle_id) { + std::lock_guard lock(mutex_); + + auto it = scheduled_callbacks_.find(handle_id); + if (it != scheduled_callbacks_.end()) { + it->second.cancelled = true; + // В реальном Scheduler отмененные колбэки могут не удаляться сразу! + // scheduled_callbacks_.erase(it); // Закомментировано для эмуляции проблемы + total_cancelled_++; + std::cout << "[Scheduler] Cancelled callback " << handle_id + << ", total active: " << scheduled_callbacks_.size() << std::endl; + } + } + + // Эмулируем выполнение колбэков + void processCallbacks() { + std::lock_guard lock(mutex_); + + auto now = std::chrono::steady_clock::now(); + std::vector to_execute; + + for (auto& [id, info] : scheduled_callbacks_) { + if (!info.cancelled && info.execute_time <= now) { + to_execute.push_back(id); + } + } + + for (int id : to_execute) { + auto it = scheduled_callbacks_.find(id); + if (it != scheduled_callbacks_.end() && !it->second.cancelled) { + auto callback = std::move(it->second.callback); + scheduled_callbacks_.erase(it); + + // Выполняем callback без блокировки + mutex_.unlock(); + std::cout << "[Scheduler] Executing callback " << id << std::endl; + callback(); + mutex_.lock(); + + total_executed_++; + } + } + } + + void printStats() const { + std::lock_guard lock(mutex_); + std::cout << "[Scheduler] Stats:" << std::endl; + std::cout << " Total scheduled: " << total_scheduled_ << std::endl; + std::cout << " Total executed: " << total_executed_ << std::endl; + std::cout << " Total cancelled: " << total_cancelled_ << std::endl; + std::cout << " Currently active: " << scheduled_callbacks_.size() << std::endl; + + // Проблема: активные колбэки могут держать weak_ptr, которые при выполнении + // становятся shared_ptr и продлевают жизнь объектов! + if (!scheduled_callbacks_.empty()) { + std::cout << " WARNING: Non-zero active callbacks - potential memory leak!" << std::endl; + } + } + + size_t getActiveCallbacksCount() const { + std::lock_guard lock(mutex_); + return scheduled_callbacks_.size(); + } + +private: + mutable std::mutex mutex_; + + struct CallbackInfo { + std::function callback; + std::chrono::steady_clock::time_point execute_time; + bool cancelled; + }; + + std::unordered_map scheduled_callbacks_; + int next_id_ = 1; + int total_scheduled_ = 0; + int total_executed_ = 0; + int total_cancelled_ = 0; +}; + +using Scheduler = RealisticScheduler; + +} // namespace basic + +namespace connection { + +struct SecureConnection { + peer::PeerId remote_peer; + bool closed = false; + + SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} + + peer::PeerId remotePeer() const { return remote_peer; } + bool isClosed() const { return closed; } + void close() { closed = true; } +}; + +// Реалистичная версия YamuxedConnection с таймерами +class YamuxedConnection : public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function)>; + + explicit YamuxedConnection( + std::shared_ptr connection, + std::shared_ptr scheduler, + ConnectionClosedCallback closed_callback) + : connection_(std::move(connection)) + , scheduler_(std::move(scheduler)) + , closed_callback_(std::move(closed_callback)) + , remote_peer_(connection_->remotePeer()) { + + std::cout << "[YamuxedConnection] Created connection to " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + ~YamuxedConnection() { + std::cout << "[YamuxedConnection] *** DESTRUCTOR *** for " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + void start() { + started_ = true; + std::cout << "[YamuxedConnection] Started connection to " + << remote_peer_.toBase58() << std::endl; + + // Запускаем таймеры (источник проблемы!) + setTimerCleanup(); + setTimerPing(); + setTimerInactivity(); + } + + void stop() { + if (!started_) return; + + started_ = false; + std::cout << "[YamuxedConnection] Stopping connection to " + << remote_peer_.toBase58() << std::endl; + + // ДО ИСПРАВЛЕНИЯ: таймеры не отменялись! + // ПОСЛЕ ИСПРАВЛЕНИЯ: отменяем все таймеры + cancelAllTimers(); + } + + void close() { + if (closed_) return; + + auto self_ptr = shared_from_this(); + std::cout << "[YamuxedConnection] Closing connection to " + << remote_peer_.toBase58() + << " (use_count: " << self_ptr.use_count() << ")" << std::endl; + + closed_ = true; + connection_->close(); + + // ДО ИСПРАВЛЕНИЯ: таймеры не отменялись! + // ПОСЛЕ ИСПРАВЛЕНИЯ: отменяем все таймеры + cancelAllTimers(); + + // Вызываем callback для ConnectionManager + if (closed_callback_ && registered_in_manager_) { + std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " + << self_ptr.use_count() << std::endl; + + closed_callback_(remote_peer_, self_ptr); + } + } + + bool isClosed() const { return closed_; } + peer::PeerId remotePeer() const { return remote_peer_; } + + void markAsRegistered() { + registered_in_manager_ = true; + } + + long getSharedPtrUseCount() const { + auto self_ptr = shared_from_this(); + return self_ptr.use_count(); + } + +private: + void setTimerCleanup() { + auto weak_self = std::weak_ptr(shared_from_this()); + + cleanup_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Cleanup: object already destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Cleanup: connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Cleanup executed for " << self->remote_peer_.toBase58() << std::endl; + + // ПРОБЛЕМА: рекурсивный вызов создает новый таймер! + self->setTimerCleanup(); + }, + std::chrono::milliseconds(150) + ); + + std::cout << "[YamuxedConnection] Set cleanup timer for " << remote_peer_.toBase58() << std::endl; + } + + void setTimerPing() { + auto weak_self = std::weak_ptr(shared_from_this()); + + ping_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Ping: object already destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Ping: connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Ping executed for " << self->remote_peer_.toBase58() << std::endl; + + // ПРОБЛЕМА: рекурсивный вызов создает новый таймер! + self->setTimerPing(); + }, + std::chrono::milliseconds(100) + ); + + std::cout << "[YamuxedConnection] Set ping timer for " << remote_peer_.toBase58() << std::endl; + } + + void setTimerInactivity() { + auto weak_self = std::weak_ptr(shared_from_this()); + + inactivity_handle_ = scheduler_->scheduleWithHandle( + [weak_self]() { + auto self = weak_self.lock(); + if (!self) { + std::cout << "[Timer] Inactivity: object already destroyed" << std::endl; + return; + } + if (!self->started_) { + std::cout << "[Timer] Inactivity: connection stopped" << std::endl; + return; + } + + std::cout << "[Timer] Inactivity executed for " << self->remote_peer_.toBase58() << std::endl; + + // Этот таймер может закрыть соединение + self->close(); + }, + std::chrono::milliseconds(500) + ); + + std::cout << "[YamuxedConnection] Set inactivity timer for " << remote_peer_.toBase58() << std::endl; + } + + void cancelAllTimers() { + std::cout << "[YamuxedConnection] === CANCELLING ALL TIMERS === for " << remote_peer_.toBase58() << std::endl; + + ping_handle_.reset(); + cleanup_handle_.reset(); + inactivity_handle_.reset(); + + std::cout << "[YamuxedConnection] === ALL TIMERS CANCELLED ===" << std::endl; + } + +private: + std::shared_ptr connection_; + std::shared_ptr scheduler_; + ConnectionClosedCallback closed_callback_; + peer::PeerId remote_peer_; + bool started_ = false; + bool closed_ = false; + bool registered_in_manager_ = false; + + // Таймеры + basic::Scheduler::Handle ping_handle_; + basic::Scheduler::Handle cleanup_handle_; + basic::Scheduler::Handle inactivity_handle_; +}; + +} // namespace connection + +namespace network { + +class ConnectionManagerTest { +public: + using ConnectionSPtr = std::shared_ptr; + + void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { + connections_[peer].insert(conn); + std::cout << "[ConnectionManager] Added connection for " << peer.toBase58() + << " (total: " << connections_[peer].size() << ")" << std::endl; + } + + void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { + std::cout << "[ConnectionManager] onConnectionClosed for " << peer.toBase58() + << " (use_count: " << connection.use_count() << ")" << std::endl; + + auto it = connections_.find(peer); + if (it != connections_.end()) { + it->second.erase(connection); + if (it->second.empty()) { + connections_.erase(it); + std::cout << "[ConnectionManager] Removed peer " << peer.toBase58() << std::endl; + } + } + + // ВАЖНО: в этом месте connection должен быть единственной ссылкой! + // Если use_count > 1, значит есть утечка + std::cout << "[ConnectionManager] Final use_count: " << connection.use_count() << std::endl; + } + + size_t getTotalPeers() const { return connections_.size(); } + + size_t getTotalConnections() const { + size_t total = 0; + for (const auto& [peer, conns] : connections_) { + total += conns.size(); + } + return total; + } + +private: + std::unordered_map> connections_; +}; + +} // namespace network +} // namespace libp2p + +class YamuxMemoryLeakTest { +public: + void runTest() { + std::cout << "\n=== YAMUX MEMORY LEAK TEST (REALISTIC) ===" << std::endl; + + auto scheduler = std::make_shared(); + auto connection_manager = std::make_shared(); + + // Создаем соединение + auto peer_id = "leak_test_peer"; + auto secure_conn = std::make_shared(peer_id); + + auto callback = [connection_manager](const libp2p::peer::PeerId& peer, + std::shared_ptr conn) { + connection_manager->onConnectionClosed(peer, conn); + }; + + { + // Область видимости для соединения + auto yamux_conn = std::make_shared( + secure_conn, scheduler, callback); + + yamux_conn->markAsRegistered(); + connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); + + std::cout << "\n--- Starting connection (timers will be created) ---" << std::endl; + yamux_conn->start(); + + std::cout << "\n--- Initial state ---" << std::endl; + std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; + std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; + scheduler->printStats(); + + // Даем время таймерам сработать + std::cout << "\n--- Waiting for timers (250ms) ---" << std::endl; + for (int i = 0; i < 5; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + std::cout << "\n--- After timer execution ---" << std::endl; + scheduler->printStats(); + + std::cout << "\n--- Closing connection ---" << std::endl; + yamux_conn->close(); + + std::cout << "\n--- After close() call ---" << std::endl; + std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; + scheduler->printStats(); + } + + std::cout << "\n--- After yamux_conn goes out of scope ---" << std::endl; + std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; + scheduler->printStats(); + + // Даем время на финальную очистку + std::cout << "\n--- Final cleanup (500ms) ---" << std::endl; + for (int i = 0; i < 10; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + scheduler->processCallbacks(); + } + + std::cout << "\n=== FINAL RESULTS ===" << std::endl; + std::cout << "Active connections: " << connection_manager->getTotalConnections() << std::endl; + scheduler->printStats(); + + if (scheduler->getActiveCallbacksCount() > 0) { + std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; + std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; + std::cout << "This indicates that timers were not properly cancelled!" << std::endl; + } else { + std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; + std::cout << "All timers were properly cancelled." << std::endl; + } + } +}; + +int main() { + YamuxMemoryLeakTest test; + test.runTest(); + return 0; +} \ No newline at end of file From ba357ef5e3a04458152211279978c3f57331e5e7 Mon Sep 17 00:00:00 2001 From: iceseer Date: Thu, 5 Jun 2025 22:06:02 +0300 Subject: [PATCH 09/21] Revert "tests" This reverts commit 35e3ff686d716967702cfc38f2e54f0dc15cff35. --- debug_yamux_leaks | Bin 113832 -> 0 bytes debug_yamux_leaks.cpp | 185 ---------- test_compilation_check | Bin 62256 -> 0 bytes test_final_verification | Bin 75880 -> 0 bytes test_final_verification.cpp | 82 ----- test_fix_verification | Bin 76440 -> 0 bytes test_yamux_100_connections | Bin 79032 -> 0 bytes test_yamux_100_connections.cpp | 618 -------------------------------- test_yamux_10_simple | Bin 60384 -> 0 bytes test_yamux_10_simple.cpp | 456 ----------------------- test_yamux_complete | Bin 366736 -> 0 bytes test_yamux_complete.cpp | 637 --------------------------------- test_yamux_leaks | Bin 239088 -> 0 bytes test_yamux_leaks.cpp | 319 ----------------- test_yamux_realistic | Bin 275096 -> 0 bytes test_yamux_realistic.cpp | 495 ------------------------- 16 files changed, 2792 deletions(-) delete mode 100755 debug_yamux_leaks delete mode 100644 debug_yamux_leaks.cpp delete mode 100755 test_compilation_check delete mode 100755 test_final_verification delete mode 100644 test_final_verification.cpp delete mode 100755 test_fix_verification delete mode 100755 test_yamux_100_connections delete mode 100644 test_yamux_100_connections.cpp delete mode 100755 test_yamux_10_simple delete mode 100644 test_yamux_10_simple.cpp delete mode 100755 test_yamux_complete delete mode 100644 test_yamux_complete.cpp delete mode 100755 test_yamux_leaks delete mode 100644 test_yamux_leaks.cpp delete mode 100755 test_yamux_realistic delete mode 100644 test_yamux_realistic.cpp diff --git a/debug_yamux_leaks b/debug_yamux_leaks deleted file mode 100755 index b68676825395f8ca65b199b390c5f9bbd9a04843..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 113832 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 diff --git a/debug_yamux_leaks.cpp b/debug_yamux_leaks.cpp deleted file mode 100644 index cc09d475..00000000 --- a/debug_yamux_leaks.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -// Простая диагностика утечек для shared_ptr -class LeakDetector { -public: - static LeakDetector& instance() { - static LeakDetector detector; - return detector; - } - - void registerPointer(void* ptr, const char* type) { - std::lock_guard lock(mutex_); - active_pointers_[ptr] = type; - std::cout << "[LEAK_DEBUG] Created " << type << " at " << ptr << std::endl; - } - - void unregisterPointer(void* ptr) { - std::lock_guard lock(mutex_); - auto it = active_pointers_.find(ptr); - if (it != active_pointers_.end()) { - std::cout << "[LEAK_DEBUG] Destroyed " << it->second << " at " << ptr << std::endl; - active_pointers_.erase(it); - } - } - - void printActivePointers() { - std::lock_guard lock(mutex_); - if (active_pointers_.empty()) { - std::cout << "[LEAK_DEBUG] No active pointers detected!" << std::endl; - } else { - std::cout << "[LEAK_DEBUG] Active pointers (" << active_pointers_.size() << "):" << std::endl; - for (const auto& [ptr, type] : active_pointers_) { - std::cout << " " << type << " at " << ptr << std::endl; - } - } - } - -private: - std::mutex mutex_; - std::unordered_map active_pointers_; -}; - -// Макросы для отладки утечек -#define REGISTER_LEAK_DEBUG(ptr, type) LeakDetector::instance().registerPointer(ptr, type) -#define UNREGISTER_LEAK_DEBUG(ptr) LeakDetector::instance().unregisterPointer(ptr) -#define PRINT_ACTIVE_LEAKS() LeakDetector::instance().printActivePointers() - -// Пример использования для диагностики YamuxedConnection -class YamuxedConnectionDebug : public std::enable_shared_from_this { -public: - YamuxedConnectionDebug() { - REGISTER_LEAK_DEBUG(this, "YamuxedConnection"); - } - - ~YamuxedConnectionDebug() { - UNREGISTER_LEAK_DEBUG(this); - } - - void debugSharedPtrReferences() { - auto self = shared_from_this(); - std::cout << "[DEBUG] shared_ptr use_count: " << self.use_count() << std::endl; - - // Симулируем различные места, где могут держаться ссылки: - - // 1. В streams_ (как было ранее) - streams_["test"] = std::make_shared(42); - std::cout << "[DEBUG] After adding to streams_, use_count: " << self.use_count() << std::endl; - - // 2. В callback'ах - auto callback = [self](){ /* do something */ }; - std::cout << "[DEBUG] After capturing in callback, use_count: " << self.use_count() << std::endl; - - // 3. В timer'ах - auto timer_callback = [weak_self = std::weak_ptr(self)](){ - if (auto strong = weak_self.lock()) { - /* do something */ - } - }; - std::cout << "[DEBUG] After weak capture in timer, use_count: " << self.use_count() << std::endl; - - // Очистка - streams_.clear(); - std::cout << "[DEBUG] After clearing streams_, use_count: " << self.use_count() << std::endl; - } - -private: - std::unordered_map> streams_; -}; - -// Mock classes for simple testing -namespace libp2p { -namespace peer { -struct PeerId { - std::string id; - std::string toBase58() const { return id; } -}; -} - -namespace connection { -struct CapableConnection { - virtual ~CapableConnection() = default; - virtual bool isClosed() const = 0; -}; -} - -namespace muxer::yamux { -// Simple test for shared_ptr behavior in unordered_set -class YamuxedConnection { -public: - void debugPrintMemoryLeakSources() { - std::cout << "=== MEMORY LEAK DEBUG INFO ===" << std::endl; - std::cout << "This is a test method" << std::endl; - } -}; -} -} - -// Test shared_ptr behavior in unordered_set -void testSharedPtrInSet() { - std::cout << "\n=== Testing shared_ptr behavior in unordered_set ===" << std::endl; - - auto obj = std::make_shared(42); - auto obj2 = obj; // same object, different shared_ptr instance - - std::unordered_set> set; - - // Add first shared_ptr - set.insert(obj); - std::cout << "Added obj to set, size: " << set.size() << std::endl; - - // Try to find with different shared_ptr to same object - auto found = set.find(obj2); - if (found != set.end()) { - std::cout << "SUCCESS: obj2 found in set (pointing to same object)" << std::endl; - } else { - std::cout << "FAIL: obj2 NOT found in set" << std::endl; - } - - // Try to erase with different shared_ptr to same object - auto erased = set.erase(obj2); - std::cout << "Erased count using obj2: " << erased << std::endl; - std::cout << "Set size after erase: " << set.size() << std::endl; - - // Test with shared_from_this equivalent - struct TestClass : std::enable_shared_from_this { - int value = 123; - }; - - auto test_obj = std::make_shared(); - auto self_ptr = test_obj->shared_from_this(); - - std::unordered_set> test_set; - test_set.insert(test_obj); - - auto found2 = test_set.find(self_ptr); - if (found2 != test_set.end()) { - std::cout << "SUCCESS: shared_from_this() found in set" << std::endl; - } else { - std::cout << "FAIL: shared_from_this() NOT found in set" << std::endl; - } - - auto erased2 = test_set.erase(self_ptr); - std::cout << "Erased count using shared_from_this(): " << erased2 << std::endl; - std::cout << "Test set size after erase: " << test_set.size() << std::endl; -} - -int main() { - std::cout << "=== Yamux Memory Leak Debug Tool ===" << std::endl; - - // Test shared_ptr behavior - testSharedPtrInSet(); - - // Test our debug method - auto yamux_conn = std::make_shared(); - yamux_conn->debugPrintMemoryLeakSources(); - - std::cout << "\n=== Debug tool completed ===" << std::endl; - return 0; -} \ No newline at end of file diff --git a/test_compilation_check b/test_compilation_check deleted file mode 100755 index 0bdb33a15ba933f7fad41e438301605d73659b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62256 zcmeHQePC48m46AKQ4k`6rAl?MXi+g{k^liw1Ifb)gb?$g_{C$GOvp$+#>pfE#gZCp zNn>o*szvKsy6d`Z*H+rKmTfIYWJz?bMoTqyS({pGhr()Bsm)e&_IK_*_q{i7W*`ZO z{*ech^X@tKo_p`P=bU@)eP5gOq9v&*DPuG~#%Nb)DL7A`ArX0u&pf~<0C`%jHW7ba z+PT_ENRJgbNzao2RC%N`X9d$3PiQLlB-5R6I_Fc6+C&FIDwpi&`J$vKsHMv^l^aK= zF8YJRCH|W5*$ZS^L3=q-UkT@T!0FsT1?}ZXHrsEL<(#mOJ29v_!|hB(b}F~!c3I8| z(0M~0&9xb9J8`N zhAXL@vwbR^$K@1M?JVJPky4q#3HNcs6y&6KHOi4ZhkEcZXr)}AbKF$Agey>x^otHc zXW~b?c2#kOmfE6q5l+!lv=os(1volVIj!iFcM5(q98~_JeH$ixbKS46pMGK9;Kg6w zTs2X@zW>siz?!)^m)2BXQWL0aY`&y9ckU%~b21w0GqSYPQSL1Kh>wun1y5?)UE5Q& z=e4ovDK0Jbq_2&2rD{{grl+P&NWWz@Oq z-^KXRaS48x;^)TihHve@Kj+@d@0|KCzF&Sk_x#33m$npde)e0pUtIXuC5;{}by_uf8qNIna#WM>_%rNbastXtN$@iv6zZSz7!Q0RJ{=f{ zMED>WB*O1Ty)*{SBXDx!{F9T^TZ92j#6LSp{vRjFzXFPth|eFAv}X+Zo2dN@lGOWH z68Y>%BL5{2Od|edcP^*Ukk*s%*_)*OWJihk%tkvCjr;5*`5%DOI8QrG+m(R~IOa>B zU5g3`zmSX^$5g5i#~8Ge@SS87ILM~x7|(n@m?zWu5@?4pUX=fVY>DV$d_N%J!wx>@ zp}&OB;r5WN(s4fOpP`+pwQQ8>SrTZ!5dA$(DV=3m12XSiQk+@4Ct zmvj5~wf)m-m1#(xix+IcO^BnEWgQKMU9&#=?z9ND4RhFj{ ze=FxNWjWMy{wuk^JGkCF#y`vX4|9Gchc~!i+qhp!o`)dk(=mEmTO

UhOWHzmxyZ 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 wyAXe>->P571E*w{CFQ@apGtUgg%vApWyR3 -#include -#include -#include - -// Финальная проверка исправлений компиляции - -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id = "test_peer"; - std::string toBase58() const { return id; } - bool operator==(const PeerId& other) const { return id == other.id; } -}; -} - -namespace connection { -class CapableConnection { -public: - virtual ~CapableConnection() = default; - virtual bool isClosed() const = 0; -}; - -class YamuxedConnection : public CapableConnection, public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function&)>; - - YamuxedConnection(ConnectionClosedCallback callback) : closed_callback_(callback) {} - - bool isClosed() const override { return false; } - - void simulateCloseCallback() { - peer::PeerId remote_peer; - auto self_ptr = shared_from_this(); - - // ИСПРАВЛЕНИЕ 1: Приведение типа в yamuxed_connection.cpp (строка 574) - closed_callback_(remote_peer, std::static_pointer_cast(self_ptr)); - } - -private: - ConnectionClosedCallback closed_callback_; -}; -} - -namespace network { -class ConnectionManagerImpl { -public: - // ИСПРАВЛЕНИЕ 2: Правильная сигнатура в connection_manager_impl.cpp (строка 158) - void onConnectionClosed(const peer::PeerId& peer, - const std::shared_ptr& connection) { - std::cout << "ConnectionManagerImpl::onConnectionClosed called for peer: " - << peer.toBase58() << std::endl; - std::cout << "Connection address: " << (void*)connection.get() << std::endl; - } -}; -} - -} - -int main() { - std::cout << "=== ПРОВЕРКА ВСЕХ ИСПРАВЛЕНИЙ КОМПИЛЯЦИИ ===" << std::endl; - - auto manager = std::make_shared(); - - auto callback = [manager](const libp2p::peer::PeerId& peer, - const std::shared_ptr& conn) { - manager->onConnectionClosed(peer, conn); - }; - - auto connection = std::make_shared(callback); - - std::cout << "1. Тестирование yamuxed_connection.cpp - приведение типа..." << std::endl; - connection->simulateCloseCallback(); - - std::cout << "2. Тестирование connection_manager_impl.cpp - сигнатура метода..." << std::endl; - libp2p::peer::PeerId peer; - manager->onConnectionClosed(peer, connection); - - std::cout << "=== ВСЕ ИСПРАВЛЕНИЯ РАБОТАЮТ КОРРЕКТНО ===" << std::endl; - return 0; -} \ No newline at end of file diff --git a/test_fix_verification b/test_fix_verification deleted file mode 100755 index ec898d6d018bd60692eef225111e4c3727f68ee6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76440 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 D_iW(U diff --git a/test_yamux_100_connections b/test_yamux_100_connections deleted file mode 100755 index 72eb49dbf27ae4bd4a64343c8bfa5b12034a5428..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79032 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Нагрузочный тест с 100 соединениями и исправлением мертвых колбэков - -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id; - PeerId(const std::string& id_) : id(id_) {} - std::string toBase58() const { return id; } - bool operator==(const PeerId& other) const { return id == other.id; } -}; -} -} - -namespace std { -template <> -struct hash { - size_t operator()(const libp2p::peer::PeerId& peer) const { - return hash()(peer.id); - } -}; -} - -namespace libp2p { - -namespace basic { - -// ИСПРАВЛЕННЫЙ Scheduler с очисткой мертвых колбэков -class ImprovedScheduler : public std::enable_shared_from_this { -public: - struct Handle { - int id = -1; - std::weak_ptr scheduler; - - void reset() { - if (auto sched = scheduler.lock()) { - sched->cancelHandle(id); - } - id = -1; - } - - bool has_value() const { return id >= 0; } - - Handle() = default; - Handle(int id_, std::weak_ptr sched) - : id(id_), scheduler(sched) {} - }; - - Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { - std::lock_guard lock(mutex_); - - int handle_id = next_id_++; - - scheduled_callbacks_[handle_id] = { - .callback = std::move(cb), - .execute_time = std::chrono::steady_clock::now() + delay, - .cancelled = false - }; - - total_scheduled_++; - return Handle(handle_id, weak_from_this()); - } - - void cancelHandle(int handle_id) { - std::lock_guard lock(mutex_); - - auto it = scheduled_callbacks_.find(handle_id); - if (it != scheduled_callbacks_.end()) { - it->second.cancelled = true; - total_cancelled_++; - } - } - - void processCallbacks() { - std::lock_guard lock(mutex_); - - auto now = std::chrono::steady_clock::now(); - std::vector to_execute; - std::vector to_remove; - - for (auto& [id, info] : scheduled_callbacks_) { - if (info.cancelled) { - to_remove.push_back(id); - } else if (info.execute_time <= now) { - to_execute.push_back(id); - } - } - - // ИСПРАВЛЕНИЕ: Удаляем отмененные колбэки - for (int id : to_remove) { - scheduled_callbacks_.erase(id); - } - - // Выполняем готовые колбэки - for (int id : to_execute) { - auto it = scheduled_callbacks_.find(id); - if (it != scheduled_callbacks_.end()) { - auto callback = std::move(it->second.callback); - scheduled_callbacks_.erase(it); // ИСПРАВЛЕНИЕ: удаляем сразу после выполнения - - mutex_.unlock(); - callback(); - mutex_.lock(); - - total_executed_++; - } - } - } - - void printStats() const { - std::lock_guard lock(mutex_); - std::cout << "[Scheduler] Stats: scheduled=" << total_scheduled_ - << ", executed=" << total_executed_ - << ", cancelled=" << total_cancelled_ - << ", active=" << scheduled_callbacks_.size() << std::endl; - - if (!scheduled_callbacks_.empty()) { - std::cout << " WARNING: " << scheduled_callbacks_.size() << " active callbacks!" << std::endl; - } - } - - size_t getActiveCallbacksCount() const { - std::lock_guard lock(mutex_); - return scheduled_callbacks_.size(); - } - -private: - mutable std::mutex mutex_; - - struct CallbackInfo { - std::function callback; - std::chrono::steady_clock::time_point execute_time; - bool cancelled; - }; - - std::unordered_map scheduled_callbacks_; - int next_id_ = 1; - int total_scheduled_ = 0; - int total_executed_ = 0; - int total_cancelled_ = 0; -}; - -using Scheduler = ImprovedScheduler; - -} // namespace basic - -namespace connection { - -// Оптимизированная эмуляция Stream -class OptimizedYamuxStream : public std::enable_shared_from_this { -public: - OptimizedYamuxStream(std::shared_ptr connection, uint32_t stream_id) - : connection_(connection), stream_id_(stream_id) {} - - ~OptimizedYamuxStream() = default; - - void simulateAsyncRead() { - auto conn = connection_.lock(); - if (conn) { - // Меньше логирования для производительности - } - } - - void close() { - connection_.reset(); - } - - uint32_t getId() const { return stream_id_; } - -private: - std::weak_ptr connection_; - uint32_t stream_id_; -}; - -struct SecureConnection { - peer::PeerId remote_peer; - bool closed = false; - std::atomic async_operations_count{0}; - - SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} - - peer::PeerId remotePeer() const { return remote_peer; } - bool isClosed() const { return closed; } - void close() { - closed = true; - } - - // Оптимизированное асинхронное чтение - void readSome(std::vector& buffer, size_t size, - std::function callback) { - async_operations_count++; - - // Симулируем асинхронную операцию с более коротким временем - std::thread([this, callback]() { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // Быстрее для 100 соединений - - if (!closed) { - callback(42); // 42 байта прочитано - } else { - callback(-1); // Ошибка при закрытии - } - - async_operations_count--; - }).detach(); - } - - void writeSome(const std::vector& data, - std::function callback) { - async_operations_count++; - - std::thread([this, callback]() { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - callback(closed ? -1 : 100); - async_operations_count--; - }).detach(); - } -}; - -// Оптимизированная версия YamuxedConnection -class YamuxedConnection : public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function)>; - - explicit YamuxedConnection( - std::shared_ptr connection, - std::shared_ptr scheduler, - ConnectionClosedCallback closed_callback, - int connection_id) - : connection_(std::move(connection)) - , scheduler_(std::move(scheduler)) - , closed_callback_(std::move(closed_callback)) - , remote_peer_(connection_->remotePeer()) - , raw_read_buffer_(1024) - , connection_id_(connection_id) {} - - ~YamuxedConnection() { - // Меньше логирования для 100 соединений - destroyed_count_++; - } - - void start() { - started_ = true; - - // Запускаем таймеры - setTimerCleanup(); - setTimerPing(); - - // Запускаем чтение - continueReading(); - - // Создаем меньше потоков для производительности - createMockStreams(); - } - - void stop() { - if (!started_) return; - - started_ = false; - - // ИСПРАВЛЕНИЕ: отменяем все таймеры - cancelAllTimers(); - - // Закрываем потоки - closeAllStreams(); - } - - void close() { - if (closed_) return; - - auto self_ptr = shared_from_this(); - - closed_ = true; - connection_->close(); - - // ИСПРАВЛЕНИЕ: отменяем все таймеры - cancelAllTimers(); - - // Закрываем потоки - closeAllStreams(); - - // Вызываем callback для ConnectionManager - if (closed_callback_ && registered_in_manager_) { - closed_callback_(remote_peer_, self_ptr); - } - } - - bool isClosed() const { return closed_; } - peer::PeerId remotePeer() const { return remote_peer_; } - - void markAsRegistered() { - registered_in_manager_ = true; - } - - long getSharedPtrUseCount() const { - auto self_ptr = shared_from_this(); - return self_ptr.use_count(); - } - - int getConnectionId() const { return connection_id_; } - - static int getDestroyedCount() { return destroyed_count_; } - -private: - // ИСПРАВЛЕННОЕ continueReading с проверкой состояния - void continueReading() { - if (!started_ || closed_) return; - - auto weak_self = std::weak_ptr(shared_from_this()); - - connection_->readSome(raw_read_buffer_, raw_read_buffer_.size(), - [weak_self](int bytes_read) { - auto self = weak_self.lock(); - if (!self) { - // ИСПРАВЛЕНИЕ: не создаем лишних операций для мертвых объектов - return; - } - self->onRead(bytes_read); - }); - } - - void onRead(int bytes_read) { - if (!started_ || closed_) return; // ИСПРАВЛЕНИЕ: дополнительная проверка - - if (bytes_read < 0) { - close(); - return; - } - - // Продолжаем чтение только если соединение активно - if (started_ && !closed_) { - continueReading(); - } - } - - void createMockStreams() { - // Создаем только 1 поток для производительности - auto stream = std::make_shared(shared_from_this(), 1); - streams_[1] = stream; - stream->simulateAsyncRead(); - } - - void closeAllStreams() { - for (auto& [id, stream] : streams_) { - if (stream) { - stream->close(); - } - } - streams_.clear(); - } - - void setTimerCleanup() { - auto weak_self = std::weak_ptr(shared_from_this()); - - cleanup_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self || !self->started_) return; - - // Очистка потоков - self->cleanupAbandonedStreams(); - - // Рекурсивный вызов только если соединение активно - if (self->started_ && !self->closed_) { - self->setTimerCleanup(); - } - }, - std::chrono::milliseconds(200) // Увеличили интервал для производительности - ); - } - - void setTimerPing() { - auto weak_self = std::weak_ptr(shared_from_this()); - - ping_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self || !self->started_) return; - - // Отправляем ping - self->sendPing(); - - // Рекурсивный вызов только если соединение активно - if (self->started_ && !self->closed_) { - self->setTimerPing(); - } - }, - std::chrono::milliseconds(150) // Увеличили интервал - ); - } - - void cleanupAbandonedStreams() { - // Оптимизированная очистка - } - - void sendPing() { - std::vector ping_data = {0x01}; - auto weak_self = std::weak_ptr(shared_from_this()); - - connection_->writeSome(ping_data, [weak_self](int result) { - // Минимальная обработка для производительности - }); - } - - void cancelAllTimers() { - ping_handle_.reset(); - cleanup_handle_.reset(); - } - -private: - std::shared_ptr connection_; - std::shared_ptr scheduler_; - ConnectionClosedCallback closed_callback_; - peer::PeerId remote_peer_; - bool started_ = false; - bool closed_ = false; - bool registered_in_manager_ = false; - int connection_id_; - - std::vector raw_read_buffer_; - std::unordered_map> streams_; - - basic::Scheduler::Handle ping_handle_; - basic::Scheduler::Handle cleanup_handle_; - - static std::atomic destroyed_count_; -}; - -std::atomic YamuxedConnection::destroyed_count_{0}; - -} // namespace connection - -namespace network { - -class ConnectionManagerTest { -public: - using ConnectionSPtr = std::shared_ptr; - - void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { - std::lock_guard lock(mutex_); - connections_[peer].insert(conn); - total_connections_++; - } - - void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { - std::lock_guard lock(mutex_); - - auto it = connections_.find(peer); - if (it != connections_.end()) { - it->second.erase(connection); - if (it->second.empty()) { - connections_.erase(it); - } - } - - total_connections_--; - closed_connections_++; - } - - size_t getTotalConnections() const { - std::lock_guard lock(mutex_); - size_t total = 0; - for (const auto& [peer, conns] : connections_) { - total += conns.size(); - } - return total; - } - - void printStats() const { - std::lock_guard lock(mutex_); - std::cout << "[ConnectionManager] Active: " << getTotalConnections() - << ", Closed: " << closed_connections_ << std::endl; - } - -private: - mutable std::mutex mutex_; - std::unordered_map> connections_; - int total_connections_ = 0; - int closed_connections_ = 0; -}; - -} // namespace network -} // namespace libp2p - -class LoadTestYamux100Connections { -public: - void runTest() { - std::cout << "\n=== YAMUX LOAD TEST: 100 CONNECTIONS ===" << std::endl; - - auto scheduler = std::make_shared(); - auto connection_manager = std::make_shared(); - - std::vector> connections; - - auto start_time = std::chrono::high_resolution_clock::now(); - - // Создаем 100 соединений - std::cout << "\n--- Creating 100 connections ---" << std::endl; - { - for (int i = 0; i < 100; ++i) { - std::ostringstream oss; - oss << "peer_" << std::setfill('0') << std::setw(3) << i; - auto peer_id = oss.str(); - - auto secure_conn = std::make_shared(peer_id); - - auto callback = [connection_manager](const libp2p::peer::PeerId& peer, - std::shared_ptr conn) { - connection_manager->onConnectionClosed(peer, conn); - }; - - auto yamux_conn = std::make_shared( - secure_conn, scheduler, callback, i); - - yamux_conn->markAsRegistered(); - connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); - - yamux_conn->start(); - connections.push_back(yamux_conn); - - if ((i + 1) % 20 == 0) { - std::cout << "Created " << (i + 1) << " connections..." << std::endl; - } - } - } - - auto creation_time = std::chrono::high_resolution_clock::now(); - auto creation_duration = std::chrono::duration_cast(creation_time - start_time); - - std::cout << "\n--- Initial state ---" << std::endl; - std::cout << "Created 100 connections in " << creation_duration.count() << "ms" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Даем время на работу системы - std::cout << "\n--- Running system for 1 second ---" << std::endl; - for (int i = 0; i < 20; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - std::cout << "\n--- After initial workload ---" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Закрываем все соединения - std::cout << "\n--- Closing all connections ---" << std::endl; - auto close_start = std::chrono::high_resolution_clock::now(); - - for (auto& conn : connections) { - conn->close(); - } - - auto close_time = std::chrono::high_resolution_clock::now(); - auto close_duration = std::chrono::duration_cast(close_time - close_start); - - std::cout << "Closed 100 connections in " << close_duration.count() << "ms" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Очищаем локальные ссылки - connections.clear(); - - std::cout << "\n--- After clearing local references ---" << std::endl; - std::cout << "Destroyed objects: " << libp2p::connection::YamuxedConnection::getDestroyedCount() << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Финальная очистка - std::cout << "\n--- Final cleanup (2 seconds) ---" << std::endl; - for (int i = 0; i < 40; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - auto end_time = std::chrono::high_resolution_clock::now(); - auto total_duration = std::chrono::duration_cast(end_time - start_time); - - std::cout << "\n=== FINAL RESULTS ===" << std::endl; - std::cout << "Total test time: " << total_duration.count() << "ms" << std::endl; - std::cout << "Destroyed objects: " << libp2p::connection::YamuxedConnection::getDestroyedCount() << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - if (scheduler->getActiveCallbacksCount() > 0) { - std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; - std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; - } else { - std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; - std::cout << "All callbacks properly cleaned up!" << std::endl; - } - - if (libp2p::connection::YamuxedConnection::getDestroyedCount() == 100) { - std::cout << "✅ All 100 connections properly destroyed!" << std::endl; - } else { - std::cout << "❌ Some connections were not destroyed!" << std::endl; - } - } -}; - -int main() { - LoadTestYamux100Connections test; - test.runTest(); - return 0; -} \ No newline at end of file diff --git a/test_yamux_10_simple b/test_yamux_10_simple deleted file mode 100755 index 3d8a23a55f336d2229f90a3e354cec0a0596c658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60384 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 diff --git a/test_yamux_10_simple.cpp b/test_yamux_10_simple.cpp deleted file mode 100644 index 6748a404..00000000 --- a/test_yamux_10_simple.cpp +++ /dev/null @@ -1,456 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Простой тест с 10 соединениями для демонстрации исправления - -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id; - PeerId(const std::string& id_) : id(id_) {} - std::string toBase58() const { return id; } - bool operator==(const PeerId& other) const { return id == other.id; } -}; -} -} - -namespace std { -template <> -struct hash { - size_t operator()(const libp2p::peer::PeerId& peer) const { - return hash()(peer.id); - } -}; -} - -namespace libp2p { - -namespace basic { - -// ИСПРАВЛЕННЫЙ Scheduler с правильной очисткой -class FixedScheduler : public std::enable_shared_from_this { -public: - struct Handle { - int id = -1; - std::weak_ptr scheduler; - - void reset() { - if (auto sched = scheduler.lock()) { - sched->cancelHandle(id); - } - id = -1; - } - - bool has_value() const { return id >= 0; } - - Handle() = default; - Handle(int id_, std::weak_ptr sched) - : id(id_), scheduler(sched) {} - }; - - Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { - std::lock_guard lock(mutex_); - - int handle_id = next_id_++; - - scheduled_callbacks_[handle_id] = { - .callback = std::move(cb), - .execute_time = std::chrono::steady_clock::now() + delay, - .cancelled = false - }; - - total_scheduled_++; - std::cout << "[Scheduler] Scheduled " << handle_id << " (total active: " << scheduled_callbacks_.size() << ")" << std::endl; - - return Handle(handle_id, weak_from_this()); - } - - void cancelHandle(int handle_id) { - std::lock_guard lock(mutex_); - - auto it = scheduled_callbacks_.find(handle_id); - if (it != scheduled_callbacks_.end()) { - it->second.cancelled = true; - total_cancelled_++; - std::cout << "[Scheduler] Cancelled " << handle_id << std::endl; - } - } - - void processCallbacks() { - std::lock_guard lock(mutex_); - - auto now = std::chrono::steady_clock::now(); - std::vector to_execute; - std::vector to_remove; - - // Собираем ID для удаления и выполнения - for (auto& [id, info] : scheduled_callbacks_) { - if (info.cancelled) { - to_remove.push_back(id); - } else if (info.execute_time <= now) { - to_execute.push_back(id); - } - } - - // ИСПРАВЛЕНИЕ 1: Удаляем отмененные колбэки СРАЗУ - for (int id : to_remove) { - scheduled_callbacks_.erase(id); - std::cout << "[Scheduler] Removed cancelled callback " << id << std::endl; - } - - // ИСПРАВЛЕНИЕ 2: Выполняем и удаляем колбэки - for (int id : to_execute) { - auto it = scheduled_callbacks_.find(id); - if (it != scheduled_callbacks_.end()) { - auto callback = std::move(it->second.callback); - scheduled_callbacks_.erase(it); // Удаляем ПЕРЕД выполнением - - mutex_.unlock(); - std::cout << "[Scheduler] Executing " << id << std::endl; - callback(); - mutex_.lock(); - - total_executed_++; - } - } - } - - void printStats() const { - std::lock_guard lock(mutex_); - std::cout << "[Scheduler] Total: sched=" << total_scheduled_ - << ", exec=" << total_executed_ - << ", canc=" << total_cancelled_ - << ", active=" << scheduled_callbacks_.size() << std::endl; - - if (!scheduled_callbacks_.empty()) { - std::cout << " ⚠️ LEAK: " << scheduled_callbacks_.size() << " active callbacks!" << std::endl; - } - } - - size_t getActiveCallbacksCount() const { - std::lock_guard lock(mutex_); - return scheduled_callbacks_.size(); - } - -private: - mutable std::mutex mutex_; - - struct CallbackInfo { - std::function callback; - std::chrono::steady_clock::time_point execute_time; - bool cancelled; - }; - - std::unordered_map scheduled_callbacks_; - int next_id_ = 1; - int total_scheduled_ = 0; - int total_executed_ = 0; - int total_cancelled_ = 0; -}; - -using Scheduler = FixedScheduler; - -} // namespace basic - -namespace connection { - -// Простая версия без многопоточности -class SimpleYamuxedConnection : public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function)>; - - explicit SimpleYamuxedConnection( - const std::string& peer_id, - std::shared_ptr scheduler, - ConnectionClosedCallback closed_callback, - int connection_id) - : scheduler_(std::move(scheduler)) - , closed_callback_(std::move(closed_callback)) - , remote_peer_(peer_id) - , connection_id_(connection_id) { - - std::cout << "[Connection-" << connection_id_ << "] Created for " << peer_id << std::endl; - } - - ~SimpleYamuxedConnection() { - std::cout << "[Connection-" << connection_id_ << "] *** DESTROYED ***" << std::endl; - destroyed_count_++; - } - - void start() { - started_ = true; - std::cout << "[Connection-" << connection_id_ << "] Started" << std::endl; - - // Запускаем таймеры - setTimerCleanup(); - setTimerPing(); - } - - void close() { - if (closed_) return; - - auto self_ptr = shared_from_this(); - std::cout << "[Connection-" << connection_id_ << "] Closing (use_count: " << self_ptr.use_count() << ")" << std::endl; - - closed_ = true; - started_ = false; // Останавливаем таймеры - - // ИСПРАВЛЕНИЕ: отменяем все таймеры - cancelAllTimers(); - - // Вызываем callback для ConnectionManager - if (closed_callback_ && registered_in_manager_) { - std::cout << "[Connection-" << connection_id_ << "] Calling closed_callback_" << std::endl; - closed_callback_(remote_peer_, self_ptr); - } - - std::cout << "[Connection-" << connection_id_ << "] Closed (final use_count: " << self_ptr.use_count() << ")" << std::endl; - } - - bool isClosed() const { return closed_; } - peer::PeerId remotePeer() const { return remote_peer_; } - - void markAsRegistered() { - registered_in_manager_ = true; - } - - int getConnectionId() const { return connection_id_; } - - static int getDestroyedCount() { return destroyed_count_; } - -private: - void setTimerCleanup() { - auto weak_self = std::weak_ptr(shared_from_this()); - - cleanup_handle_ = scheduler_->scheduleWithHandle( - [weak_self, id = connection_id_]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Cleanup-" << id << ": object destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Cleanup-" << id << ": connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Cleanup-" << id << ": executed" << std::endl; - - // Рекурсивный вызов только если активно - if (self->started_ && !self->closed_) { - self->setTimerCleanup(); - } - }, - std::chrono::milliseconds(300) - ); - } - - void setTimerPing() { - auto weak_self = std::weak_ptr(shared_from_this()); - - ping_handle_ = scheduler_->scheduleWithHandle( - [weak_self, id = connection_id_]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Ping-" << id << ": object destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Ping-" << id << ": connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Ping-" << id << ": executed" << std::endl; - - // Рекурсивный вызов только если активно - if (self->started_ && !self->closed_) { - self->setTimerPing(); - } - }, - std::chrono::milliseconds(200) - ); - } - - void cancelAllTimers() { - std::cout << "[Connection-" << connection_id_ << "] === CANCELLING TIMERS ===" << std::endl; - - ping_handle_.reset(); - cleanup_handle_.reset(); - - std::cout << "[Connection-" << connection_id_ << "] === TIMERS CANCELLED ===" << std::endl; - } - -private: - std::shared_ptr scheduler_; - ConnectionClosedCallback closed_callback_; - peer::PeerId remote_peer_; - bool started_ = false; - bool closed_ = false; - bool registered_in_manager_ = false; - int connection_id_; - - basic::Scheduler::Handle ping_handle_; - basic::Scheduler::Handle cleanup_handle_; - - static std::atomic destroyed_count_; -}; - -std::atomic SimpleYamuxedConnection::destroyed_count_{0}; - -} // namespace connection - -namespace network { - -class ConnectionManagerTest { -public: - using ConnectionSPtr = std::shared_ptr; - - void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { - connections_[peer].insert(conn); - std::cout << "[Manager] Added connection " << conn->getConnectionId() << " for " << peer.toBase58() << std::endl; - } - - void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { - std::cout << "[Manager] onConnectionClosed for " << peer.toBase58() - << " (connection " << connection->getConnectionId() << ")" << std::endl; - - auto it = connections_.find(peer); - if (it != connections_.end()) { - it->second.erase(connection); - if (it->second.empty()) { - connections_.erase(it); - std::cout << "[Manager] Removed peer " << peer.toBase58() << std::endl; - } - } - } - - size_t getTotalConnections() const { - size_t total = 0; - for (const auto& [peer, conns] : connections_) { - total += conns.size(); - } - return total; - } - - void printStats() const { - std::cout << "[Manager] Active connections: " << getTotalConnections() << std::endl; - } - -private: - std::unordered_map> connections_; -}; - -} // namespace network -} // namespace libp2p - -class SimpleTest10Connections { -public: - void runTest() { - std::cout << "\n=== SIMPLE YAMUX TEST: 10 CONNECTIONS ===" << std::endl; - - auto scheduler = std::make_shared(); - auto connection_manager = std::make_shared(); - - std::vector> connections; - - // Создаем 10 соединений - std::cout << "\n--- Creating 10 connections ---" << std::endl; - { - for (int i = 0; i < 10; ++i) { - std::ostringstream oss; - oss << "peer_" << std::setfill('0') << std::setw(2) << i; - auto peer_id = oss.str(); - - auto callback = [connection_manager](const libp2p::peer::PeerId& peer, - std::shared_ptr conn) { - connection_manager->onConnectionClosed(peer, conn); - }; - - auto yamux_conn = std::make_shared( - peer_id, scheduler, callback, i); - - yamux_conn->markAsRegistered(); - connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); - - yamux_conn->start(); - connections.push_back(yamux_conn); - } - } - - std::cout << "\n--- Initial state ---" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Работа системы - std::cout << "\n--- Running system (500ms) ---" << std::endl; - for (int i = 0; i < 5; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - scheduler->processCallbacks(); - } - - std::cout << "\n--- After workload ---" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Закрываем все соединения - std::cout << "\n--- Closing all connections ---" << std::endl; - for (auto& conn : connections) { - conn->close(); - } - - std::cout << "\n--- After close() calls ---" << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Очищаем локальные ссылки - connections.clear(); - - std::cout << "\n--- After clearing local references ---" << std::endl; - std::cout << "Destroyed objects: " << libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - // Финальная очистка - std::cout << "\n--- Final cleanup (1 second) ---" << std::endl; - for (int i = 0; i < 10; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - scheduler->processCallbacks(); - } - - std::cout << "\n=== FINAL RESULTS ===" << std::endl; - std::cout << "Destroyed objects: " << libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() << std::endl; - connection_manager->printStats(); - scheduler->printStats(); - - if (scheduler->getActiveCallbacksCount() > 0) { - std::cout << "\n❌ MEMORY LEAK DETECTED!" << std::endl; - std::cout << "Active callbacks: " << scheduler->getActiveCallbacksCount() << std::endl; - } else { - std::cout << "\n✅ NO MEMORY LEAKS!" << std::endl; - std::cout << "All callbacks properly cleaned up!" << std::endl; - } - - if (libp2p::connection::SimpleYamuxedConnection::getDestroyedCount() == 10) { - std::cout << "✅ All 10 connections properly destroyed!" << std::endl; - } else { - std::cout << "❌ Some connections were not destroyed!" << std::endl; - } - } -}; - -int main() { - SimpleTest10Connections test; - test.runTest(); - return 0; -} \ No newline at end of file diff --git a/test_yamux_complete b/test_yamux_complete deleted file mode 100755 index b2f90f9abf262f02df07833934492493342b2642..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 366736 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%0A6M(`E%+Y4l;>4H{7m3> zUga-=>v_VehwL$|w{scEfxagQ{{h0zIfQVP6@bj8gK%#DXRtR9$B*9v-}o~Dv>%4= zBlHJgoz?Li18&!ozYO@~3DO?5E0YDn$F9%$XW(}Is9zNdeIwTE325g-MQG3c0{j&C z!Nr2__n-h!2c5%91mELE!Bwxj1Gw$4dk^^51Eu}?UJA>EkDZ@+5%2}`gnlO4v&(Ry zf2C6JBH%Xwx6jGyO9xo;d$H@Wp91`t-omE}d@4o=y?rj>W58{H@}?t&{w~-Ta6dVP z!1tOa{56hq3-HbM6-zg1@U7Pq{$GH8 zgZ+iS?Oz=a-1f`80DQu=!a&!-ngfK-3-<{=4E$dMZl5O@J5cB!0sSVR|10pX9}z(N zVb4)QZ=cgK2e`dYa53;bu`X*r95`C|Ool%2A?~{hc)@PcKkC=LX^ha@@u`0Sx9f2J zeyq?xJw*7-2LJy9Ztw5gZJf~C>-e?6?fT@qMTFj#W5)rv{q0W>9wwLG0=->Ne*5vl z-_DCW7QkT$9O;RO3OYykn~HYxAz>!@#Bx`MT@5jy`6vi6!3||gum*&ZyhA`cD!J(D#2}k_^H6{^Yy+3{@?+^U;Ae{ z#of96>u({ruH(;76Wm^xe_Sp2OIOJY(Rnl!_@K80*Y~>wxa}vo4ERnb3%%-}Th|DG zd;j|t!0o!$>mMTYi@y>++Hb=M*JqSpQ?#tQF3uE18&!Kzd9y->~lO{1zu(817m81-mc4iD)9EX(r{f*r_>4kZ*P-^ zDE>NdyYAT*^+JEbuZ6xp+8+ac2lQmspWgw#-*ZBEEa>av!e)7aT6A$%UX zK^|1~&m{2opBG%)c|UObe6i<%e-6R$cl6tUIl|x8_s${Q_!G{Meo#GX4e0GU|0CuK zANxGt2Z7u1?ntB1Z}cB&NG00S4&3&8uLf?PN4ZCn@Tt997^t3hEAV5^6y4Mq6Wre4w-C4;C;AGweU88mZNjJiXz2%?kIlfBzaR}MMtfEQf9W#; zz5xD2yYTs7Z{efke7~gN_IZDI0JrN2e*?U=N%-su{*4{N=Z$*=P&xB&;Nua;)b{_p zQ|PDF3%$O(Pk`I!*v_9X^!B;84*|FLo4gNvk!9D{E)YJO9^~)O<-mKtD(z8u^}B^a zZ`Y}Q1^B1~g?^%3oXwBHJY6dMX8}Ksa31IOzTgXi+vjWS^;4m@^Lx((ZrA(W_*kL0 z&u3W*d^!BL>X#dEoY41&U8DYlYT&kitnhfDpZJD6Py)~OBJg+MXVdq)%g=<~KEGxu za6A9-IpCAZgt7AZ2)JEu?I$M)f7@?)K5%;xp{1<(&TSoqAuk3&usKKFG9pzFv7z&kGzT*q?!~-dE^VKmP#u@+m^E?|0A{!pA;$_zB>)AF29Gq5tRZ!bjWrAn>hW z$Eln=bScvZKOF}DvGYWU{HE*a@xW(YBKYz6)6>q9`;L4~fI7Lo^M|tqf8h6mtKQrH z9Kj1l3Sl+)oJaUz{M&n33HnE@b#Sv^3ZHW@z_p(z1OIw}@LvdKd!8%w6PpEq+T=6= zxAQk%1O5&Y_f$R%`xW>=A3GfUYt9qg_AA~5dMrO4t#!mf$*`_FMk$LZRPmE8(x>LaCwpBc^y4oRT=n_+z;9h6 zxXOX+E*JU@5Vz8C{yOmO;s5ysp7;J=3;olO+p1^&6}Y{BbFbeBy=`Bd0(|>=>E{Ue zKYgXpZ-e;D{=ny6CHTl10rb5*4t&%K!F9ZCbhXew2)U&Fxyvo`9;nRvdCH1#QZV>#w@zOuK z&JMg$@K?SPKDr(i0^b$+722K!z#jmA)t_Jat?;qqNB680+&-W8W#CUwmHVD8&2sj? zN$BnTSSJ~8PevEUnmQIl>sp#x8{^6Nu)5Y(XY8=T!m?onPBc1U>LJm{#OU~Gqo+io z6UR++qT>#mI(kaQSSLDR@biz_eMe)w zEfOg#nIDhMb^k_~;#H*myTYQe^yIa%y15n2vs%U#X;aFh(fW8YmS`*-5uMsnACD%I z@wQm9rOmu@>YS3+SfZ_BlJ-PNYdqdoRz?4*sE<(Z7k4zbwAIJ?Dd;T|ePIC}io17e zbx}0K=!g)Pl7?7&Lq+xIDE+%UKCgpbb+Sdi)B7Pf5}90E7>SH6id0RlCXUgG^as&q zYHvmL#Hjg=M*|Pq!e~tgO@U~FCPKyJrh-W2v`KT!pB_Yw5u&nW1C6@+G8$bp5{N6m zmzwGH=lF%Vn4g3T-LgDd(cIZGm!7&hS(@Yr|7)nSvdbP5eZ zGa;*!)Ql!#$|HVwG(yknzWRb_b-a-pR>(uy^9JUm-pw5PgAvif^5~S7`e<9Md3HR? z?<~e5FHnv73*kB%8&KtSN*A~jV6DzEzW$U-sC-3VNF~VGCOm@w)i@1W6+!6WTiJlF_95YNk~e(x9n6I9gH3 zTzJ$_>&ra1Gh%?Jzxl;CpoY_cBI&}PajhhRc+7Zab{Wf%#O!8jQ*FnrSu`YcZe)@Y zkus8ZG%a-Q6_Pk=j?Y(-M8hH*S>&5ffzg(gC~~L&@Tieig@r{%;6&S#ZS+nn>Ubj6 zk#N%2QpbGj=zSE>Bh)9_TU*-WsmCaaPB)`kL`H%rX&}>^1Ijbey`#OVxKh#m3tnw1 zluseuQH6G-i59bXTU&EW)JSn!nnq2STrp;Bv}jn-uu^_gG(5`c8roW#TgvM@NRkmr zMI((2^UsROjfD~Ve?bAi;8G*<&12APZ>DE1YKk|tv@MJpk!D^-)Qd!$TIv(C67e>= zQI@lR#QZjrs51SzY5w^ioc>eI{CB(Sdl5Eciz+Hv%(5UAVVWBF)MkiV5kT2UouCRp zbCH%|l03A=dnM0^XhnUzIhjZ<^vNA2ORWm#Ps-BCp0a3K*<*eRmp#NTt?bb*h?KOG zLXjHeUMaj5bwXL9xjo*Nj2Qhaqa@6?WBiiQ9&;*RE!_i}39agM+e~^$K@NJz2uly) z?=*JlBFpCl{~)IM;aNV%Mk}aA5t>fsI<>kY-O#N_KXlDc;X{|$g$`XFw!C!8vPmn8 z3dm@3VQYLi2~l1_WjKea3c*QRSX$ReVt#ZZiBDD@+I23t3OXzBvAVi=dpoJzq`C90 zNO_*s5{XQ!i9*|T^^7zNu%*ytq1OZ(%Nn9A+O*8O3x?>3tTdGI+p8kgCnegv8qo0Q zG^3svt#3j{tgW6D1AaeYFM;(?)-bT#xXFud)`295l6>hi)`Vx|w;C z6*bXF3HNj4pz3klgqc&>DiO2KsCtvhJYcJ2cw0xau}(T8w5m)?tHS#g_ADk!Bs#W` z1;PlqeRiX%yglArU&RWeX-*;%)s??X-KzUt$U{F?Uk|N|WeeTVwNZ5Zs*v%iR{{OG zOB+unAdNyEfwSXDoiCPR1Kr<6SwWH>Eihw>nrJCsMU5tMjpGq_`})T7iIy{Y>q zf|ytynU>ZhNGICTOSUx9%dhkoQ~%A4FN_*fu$|^wQIv)+8Ga%_%%qNX#u_`w{40mH z&Xe)`QJ;0((rY3M(sdk|-tTgNM4;DICyQx#kab!ZNjochazQJ%7Bv1&3mRQWPE*Iy z@@Z_^C|Q9`q>ok1AR(hOkG&{tO^MKbhzsuYKS%0lXrq_*v?3}W*ijRgd;$kNM;kKG!Xy=26a=f#X4 zdKW%p1gC)BKE8oit{cy56RySSx!& zGWS+MhNnymc5k@uCi+Hm!d{|ZkiSH4?0XS`E}^z}Mk?*zq%jrZ&LxpS{m3Q#h6ap7u4-WzYw==*Q=dAUmDwhJiD1~gTfqagRXp( z^7=jN<~Xteib;}=k!$YLkpCjHwqHuZCO%KJ4c2dpQiH_!VA0)~yi;8dC0?*n`b>tk zDQlUfj$fK;-kE63e{mLgCx5PsZBYsJOB*d|@Gn z>R^WJIU?Sx88f2A!%Bt~6?xXTw6nt_l{2msfr(Btiv<-=_9!)nMt*Qz#sp74xn*vv zuIetWfyL~*P(@``V}Eov*R*geHe3C|Yt9_fNY)JXTFT-jG5sA!&S*iNLWXuC88zVp zb{+G26$qd4fMSv0^_=erJ6A6}B0~sPk@q%y)CTUCPbjLA?DYsmLD+2)obp`<4f9lcX!Q?<`7|mc8uWLv z#!*L#Y$Ww2Tj_@tq%oN$$k52nz(}nzU)=?S0_~(BnU`N2tswKNhN;*WH@N`D&3n9;f1b3tx+a9dNl z7RDFFvb(L9G}02`4}h6P)T{f{kP*qwrPLWpQNRM=q!NJ~u9BrU@KBkoOijYI(lV?8! zz1t|P^0G;9t&cB=G~t!27E_q57L#j8-9*%bY7BKDrb3=`FH+aYGOtA4p|tFh!6rt9WIoopA6WRLnMB7qgEs?KXNczSUleA=fu_oleos=3RRVsdb zjy7esW^#G@AdUGcEb=*(Vg}(3DSrUR zpS4BVCA@HFo3&Nt$=agZrE%EPFFrlDEF^2o%pOh^l-w14geI*%=q^J{p2G^De z#!|{z`fOJ=9UxbJ_<01bCgbxUtUV*Sl#*d7(~ZYHxw=h)tVuXbrOEQNWT`Ip669)z zK@{d22$LkKfn@YHcY+%|4*pS99ju|=ea{<9oF7h}sMkZ2T|Pk?VUSS(^pvd^NO^Kq z-?a8=?(1Y~Xa+1wN+#~MMQM_1#JAydp?lmL!^u7@mjJR%4roOG6B*W=r$I?F>T_`4 zK$3ph{XDKd@RKs-u(+bcLtq_TP}y(p6*g4NHf^R7j&ioDjT?LFSKAokYU z`-yzhHaO3+n6=~uGdX4?J$S!Y8(X5D{7ZQixyBV}SW&iTOI@@fL0fuAwWz8)C}qpI z(y?o&f1XJhqCtha{{1OlJob%qFuM#0?ik(o^?b{<1K zg=a^kU(mWZcnO2zuZdOCei85ccz zIp2h_^xU%$ipIk}u9=!(!gsW#vaMx4Ippe79yCa376d+DU6!k7J^@rSsyPX{f%6fk zQK$r6lxsc<7MSp+1_zfnLxJ+YDMf(+ z^~F(=FuYGvHcobuE|}fqr@aO(v=6AcBhFcyk|l21TuEEWIMIxwK49IFY>2mUFq(&{ zL{qvn`9hlzTy%W~8I2zr!Tz1a_1NLqTv64~#El|dNF(CiOD0MC^rUg8l1jc8W1uuz zA<5{eWj|Dur=O*?HzJQ9x_?(34Rm_pwDU-Jb+<(u6YWXbFiUH>_ISC`0lZFe-x3g< z5B{t|l5C!hw-lboIQ1JOwpEnP<_J!)%F+fRM-CZOk*H)?uvj1^&ZngCS9h;M*6Yd- zal0Mm)lT6Iz4j<2&dsJB+@hpJsz@YJoH8JaxV!Mu(hf(6OzK73U@}9jM5nYU(X_zY z0hJPA_i?5^)ukbJ7(UmNMD<)u^SdfZPd3r$S zh`XDhI~~#EAvUM&EqJyycs9-WMd5!V)=bWVXnPawKq0l^m^hn!@%Dxm&GDznDti1plPYP7 z!q9{Hmp9fnZB>Ajd#!c>2b(b+dG>q#n`=)$b3b;mrQADM(#Eg;`_mTrmF(J-^^LOw zWRtjENQj;{_u?$w5`|P<#r1lbz3L`K${urTo8!`7hogrSP_K7H_HWR5sxP*m51e7ws>1(&hbQDvsfDY)Krq> zx@0EEqNjD%wTLqMD}yRS<+Q3vR0PQ9B6Ou`H)>?%6_ui=py|VulES2?o2?N1cqD{%6Ln4n`!cC{StzEFh`Z-8 zJ13?`ra&%OZzul>ifOH7Q;$nxA%3Ano!3?2M4xt-X6$w^51s`b?SPcJ8yuUAw>6Po zoQ!vdTQIrA^jtS~UT#1Rc974_*m7R?8iljv#aYrsH+4~;ddXG7r(g8l?Urofq}?s; z-%v>lQ7T@M^7y5{N7wd&*>aF>p~*8;tIJIm`{%XiXfAipMednfR3cIKTaw@iRm#^k z1&J2BDbZP!RWEfWnz%MmsOGp9Su0#ZrkyHna)HSDcx0N%T$bpyuY8QA4cq%qXg|H# zvqxbvllA$(ToyG_Jqaz1}S|v23bCjz{?vK{-Hf=yj=6@PnF%waT2OUV_FUQfULm^WPk6 zZfS3f$6Kw6t*K&IRH`{O6nyhO(7t@qFia`EG=;9T$SOq#cw2TVGB6$!CdbfwpuO4p z!Nt7xrM}Xe%rSNl;zFjH;WP((ct>pxJ`Wm}6vC6K!I4;ZT&DC}-wO|fKe`-`T#ixn z!0beP&h8a)+N6YgO?5V5S>FTYH6rp9CEZ&`Rf4doqy5lJw!s-=WOsp^z zggF_RM4!ozl0{01+FM+K*6ZLi-^s=I11d~Q2OpsN5$WP`COeyhh%zxfx3Xn1LT|H{56wc4qIC|iHQawrD%A4O8?U(2u!LG zQlTlwZ(c_nmNTb9Q?8LO=3D}gD=b7`pRH|T(R7>}qe6;SyUEd_0~P`~TAn`3C*3x$ zuz*obAp&TjCU5s_I;MtdCq${52$eFA&Z5&!D2|b!R6_cn*BLpim=4Pkzj_v0O2}mB zT2Jwow+WkSnKHRNWq`c0lQLv!)h1`ARu*v;@!U*Ll^xb{mT?Iy&LOLU3dQ)AF#b-` zgX_nTQDKUgca{IIwP&+B;vrR%k8(`tydfhnp@jCBV?Iqv5)R79&oQ5kiX7A^yB>R~ zv|P0@y5o%Y>9#pf15(!yLJf+rfL!-#qNypDM z2Rt6FbW#`Qi`N!dixdSDPBj$(pcw>KxGofikgi+X^aUBI6$gmPymd;&$|QcL{W@TEAjT@Xg(d{taTSfPyvjQnt+DyBgc=KA4=1UD##>#xgM-LzI;Yu&x9Hdz) zbEPPP!A&M^(EQBw(jz6NsxrS?nr5_5+1;vV@;yRw1Tv3m-%azGLY#|iuWs~|g&``A z6hWtH?kQ5>RmyvIM-gjG61~Z8l!t66OZz?(*85C}IqHopwWxd~ZlE9=*=nRqx#K{+ zL(w`K5x(&-tgu9$##MiEGjwPf&g|<544_m|{zw-k3_0@RRhH7&RO?)Xw81NNt{UIT$!c!YJh0=b zy^Z8HB}-Bg5U*kMPtqW0SHCe(X)~0Z@6(u=8|MSWNW&;9B($le({qAqf=`&0AVXof z{wgJS&Ec~WXec!YFHu!+90)|HdnAxo^sQ~i4h>;%%qXN%Yo_dkG>b(>2VBo>Yr_5r z%9vu+j3b>SCaZHg<4Tt1??GF$cdfD_s;60p@33TZzMYSJPD%Q_yf@v}Gb81i)EsG| zy01`Xa^KLdjv$|C@Se%ovvxxk!_1t6p?R4!c*u>OeO_iFjmE1gx#r+BuUpY8NY|dU&9350w7D?geM5Z79WN#p;vE|j6Jf2q zN463K-R@bqO1wJ>azE^Y=Fk+`uwhCI$qpQ+q4ed=jpfopMvNo%~zG0o6_e3I*((+o~!oeq=)QYi5zF|2B zCt9~4CI!^UL6NL$@RV-H{7aox;yuB{n_rbF+af4zIMAyV`M&FfW;Tz>@9kBU*c)#4 zQS+wukZLK^-C_Hvx#vvpjjbpo5)#BIMrK1cx!BC+MAuzjSitVV=xlQkb9J(`sUt}z z25^*{1e0{{_xJWgUcQk$?j(|R$rKrv0wnp4yO2{n-Tj>OBiU`JEuPn@p1kEb^f*CL z`(=bjj047d{O%;Wv!p(Ucwqt?5;ND-pwb~=KREQ{OrD@Jhh;H2peB~TMV_QGsL!B1Qzx@(@9!isL(_AnGhiTgEUjQZk&N zCy9V&zi)LiKChyVI-{_zA*KfgR@AW&qZ$sTYJa+eCrzy^Q_>qzN8-}8JfyxSBTjX* z?>p_@Q(cq2Q_5%R^iliA_+x_NwXE6i=!`HQwlT9Fvb(bs}9Gs|` z_d4N=(`HU?SWd?dYz{zPM~t+X48&qgD!b)++$ z2Di5PG(8@&j9L2G_@A@&cxM;gGUM5I@H$s?r`PAJ7={c|p7uG%q|&CPWXQ4$2;0=Y zSk_Z%@lMjd7c8JXGi^KycOG-~f5hN(bw^ThRUgl$tSgxd`Ut*INl;}srafw>MW$6z z>?ZA!McdEas`i;oc7Le?H~%-Al`h!It`~n%@N-%Gb6-o%CMLawJ7lxebTjL>AuW?VY-Ot#(y2#5S2rzBe&vkVddvN3DzTfz;}6w`spP>XhglBBZlL{5QV*%7 zI=jGJwt_JW7pt86?Yce8l14*DgEg=aGAX3F4obH`8@-Nz2&%K{Y1XB7Bj(-?jbE`I zX$=M{TVXwJ&Gekzfx-6-XJeNRK`2U;MD8i^N8U+l;{RHSKRP{(27x&HNdQhvmH2b# zx#v9Fy2c8Zd{XXOohkOg<2D*CY){HT_T;bEir-_SPE#x)=fsqd4%QgvC*crvVKK$- z5_QoQa{a|)O;SXhi-&t{E~DUk{I;Bi*GR|K$LTESj#;zf><`ROI0cFdsasL^%ERx-(l|CEB$+%(g5!3J30v76mK&(rgg!?Q;cX^t5TimzZDC|>O31Rt~Y#a#stN=V12BtbJ7P-G-V zNg=bt`G^+gJZ#K5FK;>J(##yO$>cK5B4$G(h#Y5$_SP0UMp$<;1tQ=<)qzAtSSX!i z;BM@c6us&3I;wIfQD;m@@d1l3Hp?UdRb+DwzGPuD>4c?j_eUxDJ4GXT!yU)dJjn*M zP^88JE$gXV{QnPP>pThK^EzU5kc081HOWBF5Lf5*Bd?u^9-AOnQe>79p2;$;O?2I-OP3A={g(g`p~#b+Fqg4{@N1F z$!bcSZ%-{^>jrh2L!4+xh9+70cDbdL(+WNf%BVS1I)*o*A?Sxftav?kw)Idz>T@)fXZB<>~FNlLut95>)Vo7rpAMh6zfTx-Ks zm$G!EVwLJ{%7E)I5QaX@Ezk#fdPpR-xPUAOO4Ke2P1K%AHxBXHh0pnbj+$RO2uHI0 zl|;hz5MSUR5WwkL7jbp_eBW^BB0!zx@zI1H{n68UNY}piP#f2^d^v-hh8kHbV)14S z31;i%3HmgQ6AbD1T$3ZqWhdRy#@Y~1(m<9hb4p6^k34T$f(b*R;)1N%(Rf>1OB-!5 zvi+MhD*W#O0c{LIo?)J>(D1-mV0?2B#kW19t2__N&E_2k-cuf%lf3JhcPhu)+F}cN zV>31<^G;=P_L^`Sd?DTq)Om$o>`f^echL=x7!VoUMy_D=EsXl^Eg#G}!!T{72!4lc z@di4d@5 z#WAmi$qXgWp&XR>MU(KqpuKvOw7^2wg<=Tln_s#MEy=F>O5JWH2~s=wOyGR7>!#5$ zS(F_ot)px{+G#HR3af*(kVZ-dHAiGuOm3vW7bTwSClYBSKaU5dcJk37v`?|6si~z| zvh^xijj8XDQ?`+JM^t3((7wc)B9k~~qKW}3;I?>bzP)|0mOhzNHPay7U>dY$%m8aFgmx$tSQp#dT) znO#7U@@C3Sq&(!p5Z4PC#z?U0DlJe<{%VS6)+H&AJ3^%nxUznPWWBla@8tPvsgFwj zF}s3E6{mHAlPbo=XT>@ilk!_Vna<=V=D*0CoZ-q+x1(~i_VQk_CELjr$G#($LW~OJ zRp;mo%f}f_>Yda}*3=7<3UsRb!dA}vp4CDMKn*9l=Nh-pLzm|oSmC-nul`G`P>-!Ebp9-#iiS5ZQ~>oQcnZons(2c-wL8#ge#_Hy|I?oP`?6AS}Xf3 z((nA1jo&6yC7Zi&v7j{GPJ6AOwq#VtBT*_lL_?HZDOjh!6B~>(`Qy!en1JrIpVijV zL@7v=!!tjTY~W%l^uLhP4cPU=B8Rm2XuN$^Quce0ABv9IvQ8wZsxi-i8JxkSc6Ezf z=iqQEdso-ex-e2zhX^5i_dVr0^Ay4ndJ{%mkXudOMKGl1d!Ipt$s_1!Un>G-AxTrrYt2tnt#y7ffm|05T^#T&;&E(qG$@x*rM%Bsm-GGrXQm*vt_g} zTGh}HVJBad-Y!{t(`f3l!;kwSJE>esHU8UDr@2`9=OhcV<>U2i9nzSH@K|%thAXB$ zQOTAj+8r$QeIs;SB6c#`A)Y+dakY`>kl1j?6@Bv*@tkAUl}KWNb}y|aIU0jOS!jf1 z*X|Tr-~;;_rA)7@F}s-u-U`TMe`C`khpVGpN*I6gJ+Fi`^{c4&An$rgBS@F+8DWD> z$^#igGgvW(XJ?lRwk$UB zm$XwMTD5p`vN?KWA+tjxqfKapWNff04WXyH1nIJo&*^p0EJSl?J90lT+YZv11GJ}- zGO5uxj8<6$D-xW{W7a?0KBv{Mo9}`bJc=<|2Bya^>|Y+?TAo9HK&K&uJBUZ5_Yj+( z!o%alF4TL>+w^p+UW9WoYvZ#M%`$B5?y%MK>~xwRq>nP>C_g$zE@ZQN2@*TBN=RrT zmT?U6-oKhw-HqPTmJ$v5D!Qsu`pvb>F^-$^b0~CyG)=s=Wga2aRQPrlpa zWvhz+aNME8+Tyc@QP$If1<}@cTYC$ia*$jY?JO|wl13l)!nH4KPsW>MFI>Wx-%wb{ zQik0;se+n8-+MQe9T{aL;#*TLjF3#na34mXd-BSf^KR02A2f6|(6Nx~>e+KslJEC1ZFYG=eA-g4 z9)~}zK61>jPNy!!G^0C@ ztyZ?;2sOzuX#WeFU)YT!rR^#tae}HInh_hwi{Ka#x-7@#xm$6&5Wz^AD;+7sZLtkh z9fX!l$Fjx|n#|Tw79ppU%0+v%eJU4!Cl!h=Wc1QMCUj-_kM*B#W%h!GTl^;LJv=9@ z2NL3~BKN7ZtTfTC@Z}?HO(-lw#4{BsOPRc~BCl?ITGGgl{t|vLe+9jPH)7V zxZ*u0z;eXq*-o8_S;U##lSrufxkgM&IM(ACz1|H89+yV$3qxdDjk_O#JcX_^<9|t! zAq66MSeH8_zdJ*MV+N8+JCSl=k(1-!OZ9z(3{7&ONmYqZG%7WW!~CDNYDOAEJ%P{KaD4(k>yh}9-K3(0v+ zc^kYT{&%x2T=xPp`z2xyMk^j5dtkSCqUoqfZj(@Z51vys{) zO7TW&@(F|m0(8$XjY;y9(2-*;^C=g1Hl+fjub-3S5U^)JF1<>k*?q7;f`50?B}Iya z2VOXsCprBIlV%^Tg{2R>WD{E9ygD*fb)!?T5~$NE&OoQe zNg@YlK7W_q6{8eD9EIN}DAvLbeZcM<_mBmakZ!T$l!m!Zji=$5RfQO{q1)rI7VVM_ z|D;hBwxQc7`B=WvN~E%hF*;x%PKT%IMliOwdfq)z*IBFcA~pHxfq2E2gQ-1d+0rr= z&P8LM0b)^29L|zIxw@y zILGQz88rEY^nD9_KGNMzMHrs)d-%^7^Qq{;7y(<*tiq-}PW$2p9 zLG!ja?Iz>0vC+mvZC%u4@zG(!3HQj|;*xOfjsneND2PbJ&9T{Z;6}D`HIU&Kp$^MF zb-OxQ+>~gpXrjOg#UV}VsS(4-VRM7^sNlWJ-L__{HJdGAg~8r{9OGDG@41?XP?oTu~cZJr&AtDLF4yFrwO$zq)@GAF9

?S4`% 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 literal 0 HcmV?d00001 diff --git a/test_yamux_leaks.cpp b/test_yamux_leaks.cpp new file mode 100644 index 00000000..05bf1078 --- /dev/null +++ b/test_yamux_leaks.cpp @@ -0,0 +1,319 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Mock классы для тестирования +namespace libp2p { + +namespace peer { +struct PeerId { + std::string id; + + PeerId(const std::string& id_) : id(id_) {} + + std::string toBase58() const { return id; } + + bool operator==(const PeerId& other) const { + return id == other.id; + } +}; +} +} + +// Хеш для peer::PeerId в unordered_map - должен быть определен до использования +namespace std { +template <> +struct hash { + size_t operator()(const libp2p::peer::PeerId& peer) const { + return hash()(peer.id); + } +}; +} + +namespace libp2p { + +namespace basic { +struct Scheduler { + struct Handle { + bool valid = false; + }; + + Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { + // Простая эмуляция - выполняем через delay + std::thread([cb, delay]() { + std::this_thread::sleep_for(delay); + cb(); + }).detach(); + return Handle{true}; + } + + void cancel(Handle& h) { + h.valid = false; + } +}; +} + +namespace connection { +struct Stream { + virtual ~Stream() = default; +}; + +struct SecureConnection { + peer::PeerId remote_peer; + bool closed = false; + + SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} + + peer::PeerId remotePeer() const { return remote_peer; } + bool isClosed() const { return closed; } + void close() { closed = true; } +}; + +// Упрощенная версия YamuxedConnection для тестирования +class YamuxedConnection : public std::enable_shared_from_this { +public: + using ConnectionClosedCallback = std::function)>; + + explicit YamuxedConnection( + std::shared_ptr connection, + std::shared_ptr scheduler, + ConnectionClosedCallback closed_callback) + : connection_(std::move(connection)) + , scheduler_(std::move(scheduler)) + , closed_callback_(std::move(closed_callback)) + , remote_peer_(connection_->remotePeer()) { + + std::cout << "[YamuxedConnection] Created connection to " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + ~YamuxedConnection() { + std::cout << "[YamuxedConnection] Destroyed connection to " + << remote_peer_.toBase58() + << " at address " << (void*)this << std::endl; + } + + void start() { + started_ = true; + std::cout << "[YamuxedConnection] Started connection to " + << remote_peer_.toBase58() << std::endl; + } + + void close() { + if (closed_) return; + + auto self_ptr = shared_from_this(); + std::cout << "[YamuxedConnection] Closing connection to " + << remote_peer_.toBase58() + << " (use_count: " << self_ptr.use_count() << ")" << std::endl; + + closed_ = true; + connection_->close(); + + // Вызываем callback для ConnectionManager + if (closed_callback_ && registered_in_manager_) { + std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " + << self_ptr.use_count() << std::endl; + + closed_callback_(remote_peer_, self_ptr); + } + } + + bool isClosed() const { return closed_; } + + peer::PeerId remotePeer() const { return remote_peer_; } + + void markAsRegistered() { + registered_in_manager_ = true; + std::cout << "[YamuxedConnection] Marked as registered in manager" << std::endl; + } + + long getSharedPtrUseCount() const { + auto self_ptr = shared_from_this(); + return self_ptr.use_count(); + } + +private: + std::shared_ptr connection_; + std::shared_ptr scheduler_; + ConnectionClosedCallback closed_callback_; + peer::PeerId remote_peer_; + bool started_ = false; + bool closed_ = false; + bool registered_in_manager_ = false; +}; + +} // namespace connection + +namespace network { + +// Упрощенная версия ConnectionManager для тестирования +class ConnectionManagerTest { +public: + using ConnectionSPtr = std::shared_ptr; + + void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { + std::cout << "[ConnectionManager] === addConnectionToPeer CALLED ===" << std::endl; + std::cout << "[ConnectionManager] peer: " << peer.toBase58() << std::endl; + std::cout << "[ConnectionManager] connection address: " << (void*)conn.get() << std::endl; + std::cout << "[ConnectionManager] connection use_count: " << conn.use_count() << std::endl; + + auto it = connections_.find(peer); + if (it == connections_.end()) { + std::cout << "[ConnectionManager] Creating new peer entry" << std::endl; + connections_.insert({peer, {conn}}); + } else { + std::cout << "[ConnectionManager] Adding to existing peer (current size: " + << it->second.size() << ")" << std::endl; + connections_[peer].insert(conn); + } + + std::cout << "[ConnectionManager] Total connections for peer: " + << connections_[peer].size() << std::endl; + std::cout << "[ConnectionManager] === addConnectionToPeer FINISHED ===" << std::endl; + } + + void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { + std::cout << "[ConnectionManager] === onConnectionClosed CALLED ===" << std::endl; + std::cout << "[ConnectionManager] peer: " << peer.toBase58() << std::endl; + std::cout << "[ConnectionManager] connection address: " << (void*)connection.get() << std::endl; + std::cout << "[ConnectionManager] connection use_count: " << connection.use_count() << std::endl; + + auto it = connections_.find(peer); + if (it == connections_.end()) { + std::cout << "[ConnectionManager] WARNING: Peer not found in connections_!" << std::endl; + return; + } + + std::cout << "[ConnectionManager] Found peer, current connections: " << it->second.size() << std::endl; + + // Показываем все соединения для сравнения + for (const auto& conn : it->second) { + std::cout << "[ConnectionManager] Existing connection: " + << (void*)conn.get() + << " (use_count: " << conn.use_count() << ")" << std::endl; + } + + auto erased = it->second.erase(connection); + std::cout << "[ConnectionManager] Erased count: " << erased << std::endl; + + if (erased == 0) { + std::cout << "[ConnectionManager] ERROR: Connection was NOT found in set!" << std::endl; + } else { + std::cout << "[ConnectionManager] SUCCESS: Connection removed" << std::endl; + } + + if (it->second.empty()) { + connections_.erase(peer); + std::cout << "[ConnectionManager] Peer removed from connections_ (no more connections)" << std::endl; + } + + std::cout << "[ConnectionManager] === onConnectionClosed FINISHED ===" << std::endl; + } + + size_t getTotalConnections() const { + size_t total = 0; + for (const auto& [peer, conns] : connections_) { + total += conns.size(); + } + return total; + } + + void printStatus() const { + std::cout << "\n[ConnectionManager] === STATUS ===" << std::endl; + std::cout << "[ConnectionManager] Total peers: " << connections_.size() << std::endl; + std::cout << "[ConnectionManager] Total connections: " << getTotalConnections() << std::endl; + + for (const auto& [peer, conns] : connections_) { + std::cout << "[ConnectionManager] Peer " << peer.toBase58() + << " has " << conns.size() << " connections:" << std::endl; + for (const auto& conn : conns) { + std::cout << "[ConnectionManager] - " << (void*)conn.get() + << " (use_count: " << conn.use_count() << ")" << std::endl; + } + } + std::cout << "[ConnectionManager] ===================" << std::endl; + } + +private: + std::unordered_map> connections_; +}; + +} // namespace network +} // namespace libp2p + +// Тест множественных соединений +class YamuxLeakTest { +public: + void runTest() { + std::cout << "\n=== YAMUX LEAK TEST STARTED ===" << std::endl; + + auto scheduler = std::make_shared(); + auto connection_manager = std::make_shared(); + + // Создаем множественные соединения + const int num_connections = 5; + std::vector> connections; + + for (int i = 0; i < num_connections; ++i) { + auto peer_id = "peer_" + std::to_string(i); + auto secure_conn = std::make_shared(peer_id); + + // Создаем callback для ConnectionManager + auto callback = [connection_manager](const libp2p::peer::PeerId& peer, + std::shared_ptr conn) { + connection_manager->onConnectionClosed(peer, conn); + }; + + auto yamux_conn = std::make_shared( + secure_conn, scheduler, callback); + + yamux_conn->start(); + yamux_conn->markAsRegistered(); + + connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); + connections.push_back(yamux_conn); + + std::cout << "\n--- Created connection " << (i+1) << "/" << num_connections << " ---" << std::endl; + } + + connection_manager->printStatus(); + + // Даем время на обработку + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + std::cout << "\n=== CLOSING ALL CONNECTIONS ===" << std::endl; + + // Закрываем все соединения + for (int i = 0; i < connections.size(); ++i) { + std::cout << "\n--- Closing connection " << (i+1) << "/" << connections.size() << " ---" << std::endl; + connections[i]->close(); + + connection_manager->printStatus(); + } + + // Очищаем наши ссылки + connections.clear(); + + std::cout << "\n=== FINAL STATUS ===" << std::endl; + connection_manager->printStatus(); + + std::cout << "\n=== YAMUX LEAK TEST FINISHED ===" << std::endl; + } +}; + +int main() { + YamuxLeakTest test; + test.runTest(); + + std::cout << "\nWaiting for potential cleanup..." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(1)); + + return 0; +} \ No newline at end of file diff --git a/test_yamux_realistic b/test_yamux_realistic new file mode 100755 index 0000000000000000000000000000000000000000..fdf00c1eae674b26187e9a0dfe786c2b7c314524 GIT binary patch literal 275096 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 diff --git a/test_yamux_complete.cpp b/test_yamux_complete.cpp deleted file mode 100644 index cc207567..00000000 --- a/test_yamux_complete.cpp +++ /dev/null @@ -1,637 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Полный тест утечек памяти в YamuxedConnection с максимальной точностью - -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id; - PeerId(const std::string& id_) : id(id_) {} - std::string toBase58() const { return id; } - bool operator==(const PeerId& other) const { return id == other.id; } -}; -} -} - -namespace std { -template <> -struct hash { - size_t operator()(const libp2p::peer::PeerId& peer) const { - return hash()(peer.id); - } -}; -} - -namespace libp2p { - -namespace basic { - -// Полная эмуляция Scheduler -class CompleteScheduler : public std::enable_shared_from_this { -public: - struct Handle { - int id = -1; - std::weak_ptr scheduler; - - void reset() { - if (auto sched = scheduler.lock()) { - sched->cancelHandle(id); - } - id = -1; - } - - bool has_value() const { return id >= 0; } - - Handle() = default; - Handle(int id_, std::weak_ptr sched) - : id(id_), scheduler(sched) {} - }; - - Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { - std::lock_guard lock(mutex_); - - int handle_id = next_id_++; - - scheduled_callbacks_[handle_id] = { - .callback = std::move(cb), - .execute_time = std::chrono::steady_clock::now() + delay, - .cancelled = false - }; - - total_scheduled_++; - std::cout << "[Scheduler] Scheduled callback " << handle_id - << ", total active: " << scheduled_callbacks_.size() << std::endl; - - return Handle(handle_id, weak_from_this()); - } - - void cancelHandle(int handle_id) { - std::lock_guard lock(mutex_); - - auto it = scheduled_callbacks_.find(handle_id); - if (it != scheduled_callbacks_.end()) { - it->second.cancelled = true; - total_cancelled_++; - std::cout << "[Scheduler] Cancelled callback " << handle_id - << ", total active: " << scheduled_callbacks_.size() << std::endl; - } - } - - void processCallbacks() { - std::lock_guard lock(mutex_); - - auto now = std::chrono::steady_clock::now(); - std::vector to_execute; - - for (auto& [id, info] : scheduled_callbacks_) { - if (!info.cancelled && info.execute_time <= now) { - to_execute.push_back(id); - } - } - - for (int id : to_execute) { - auto it = scheduled_callbacks_.find(id); - if (it != scheduled_callbacks_.end() && !it->second.cancelled) { - auto callback = std::move(it->second.callback); - scheduled_callbacks_.erase(it); - - mutex_.unlock(); - std::cout << "[Scheduler] Executing callback " << id << std::endl; - callback(); - mutex_.lock(); - - total_executed_++; - } - } - } - - void printStats() const { - std::lock_guard lock(mutex_); - std::cout << "[Scheduler] Stats:" << std::endl; - std::cout << " Total scheduled: " << total_scheduled_ << std::endl; - std::cout << " Total executed: " << total_executed_ << std::endl; - std::cout << " Total cancelled: " << total_cancelled_ << std::endl; - std::cout << " Currently active: " << scheduled_callbacks_.size() << std::endl; - - if (!scheduled_callbacks_.empty()) { - std::cout << " WARNING: Non-zero active callbacks - potential memory leak!" << std::endl; - } - } - - size_t getActiveCallbacksCount() const { - std::lock_guard lock(mutex_); - return scheduled_callbacks_.size(); - } - -private: - mutable std::mutex mutex_; - - struct CallbackInfo { - std::function callback; - std::chrono::steady_clock::time_point execute_time; - bool cancelled; - }; - - std::unordered_map scheduled_callbacks_; - int next_id_ = 1; - int total_scheduled_ = 0; - int total_executed_ = 0; - int total_cancelled_ = 0; -}; - -using Scheduler = CompleteScheduler; - -} // namespace basic - -namespace connection { - -// Эмуляция Stream -class MockYamuxStream : public std::enable_shared_from_this { -public: - MockYamuxStream(std::shared_ptr connection, uint32_t stream_id) - : connection_(connection), stream_id_(stream_id) { - std::cout << "[MockYamuxStream] Created stream " << stream_id_ << std::endl; - } - - ~MockYamuxStream() { - std::cout << "[MockYamuxStream] Destroyed stream " << stream_id_ << std::endl; - } - - void simulateAsyncRead() { - // Симулируем асинхронное чтение, которое держит ссылку на соединение - auto conn = connection_.lock(); - if (conn) { - std::cout << "[MockYamuxStream] Stream " << stream_id_ << " performing async read" << std::endl; - // В реальном коде здесь были бы колбэки с shared_ptr - } - } - - void close() { - std::cout << "[MockYamuxStream] Closing stream " << stream_id_ << std::endl; - connection_.reset(); - } - - uint32_t getId() const { return stream_id_; } - -private: - std::weak_ptr connection_; // Важно: weak_ptr! - uint32_t stream_id_; -}; - -struct SecureConnection { - peer::PeerId remote_peer; - bool closed = false; - std::atomic async_operations_count{0}; - - SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} - - peer::PeerId remotePeer() const { return remote_peer; } - bool isClosed() const { return closed; } - void close() { - closed = true; - std::cout << "[SecureConnection] Closed, pending operations: " - << async_operations_count.load() << std::endl; - } - - // Симуляция асинхронного чтения (как continueReading) - void readSome(std::vector& buffer, size_t size, - std::function callback) { - async_operations_count++; - std::cout << "[SecureConnection] Starting async read operation (total: " - << async_operations_count.load() << ")" << std::endl; - - // Симулируем асинхронную операцию - std::thread([this, callback]() { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - if (!closed) { - // Симулируем успешное чтение - callback(42); // 42 байта прочитано - } else { - // Симулируем ошибку при закрытии - callback(-1); - } - - async_operations_count--; - std::cout << "[SecureConnection] Async read completed (remaining: " - << async_operations_count.load() << ")" << std::endl; - }).detach(); - } - - void writeSome(const std::vector& data, - std::function callback) { - async_operations_count++; - std::cout << "[SecureConnection] Starting async write operation" << std::endl; - - std::thread([this, callback]() { - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - callback(closed ? -1 : 100); // 100 байт записано - async_operations_count--; - }).detach(); - } -}; - -// Полная версия YamuxedConnection -class YamuxedConnection : public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function)>; - - explicit YamuxedConnection( - std::shared_ptr connection, - std::shared_ptr scheduler, - ConnectionClosedCallback closed_callback) - : connection_(std::move(connection)) - , scheduler_(std::move(scheduler)) - , closed_callback_(std::move(closed_callback)) - , remote_peer_(connection_->remotePeer()) - , raw_read_buffer_(1024) { - - std::cout << "[YamuxedConnection] Created connection to " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - ~YamuxedConnection() { - std::cout << "[YamuxedConnection] *** DESTRUCTOR *** for " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - void start() { - started_ = true; - std::cout << "[YamuxedConnection] Started connection to " - << remote_peer_.toBase58() << std::endl; - - // Запускаем таймеры (как в реальном коде) - setTimerCleanup(); - setTimerPing(); - - // ВАЖНО: запускаем чтение (как в реальном коде!) - continueReading(); - - // Симулируем создание потоков - createMockStreams(); - } - - void stop() { - if (!started_) return; - - started_ = false; - std::cout << "[YamuxedConnection] Stopping connection to " - << remote_peer_.toBase58() << std::endl; - - // ИСПРАВЛЕНИЕ: отменяем все таймеры - cancelAllTimers(); - - // Закрываем потоки - closeAllStreams(); - } - - void close() { - if (closed_) return; - - auto self_ptr = shared_from_this(); - std::cout << "[YamuxedConnection] Closing connection to " - << remote_peer_.toBase58() - << " (use_count: " << self_ptr.use_count() << ")" << std::endl; - - closed_ = true; - connection_->close(); - - // ИСПРАВЛЕНИЕ: отменяем все таймеры - cancelAllTimers(); - - // Закрываем потоки - closeAllStreams(); - - // Вызываем callback для ConnectionManager - if (closed_callback_ && registered_in_manager_) { - std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " - << self_ptr.use_count() << std::endl; - - closed_callback_(remote_peer_, self_ptr); - } - } - - bool isClosed() const { return closed_; } - peer::PeerId remotePeer() const { return remote_peer_; } - - void markAsRegistered() { - registered_in_manager_ = true; - } - - long getSharedPtrUseCount() const { - auto self_ptr = shared_from_this(); - return self_ptr.use_count(); - } - -private: - // Эмуляция continueReading (КЛЮЧЕВОЕ отличие от простого теста!) - void continueReading() { - if (!started_ || closed_) return; - - std::cout << "[YamuxedConnection] continueReading() called" << std::endl; - - // В реальном коде здесь weak_from_this() захватывается в колбэк - auto weak_self = std::weak_ptr(shared_from_this()); - - connection_->readSome(raw_read_buffer_, raw_read_buffer_.size(), - [weak_self](int bytes_read) { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[ReadCallback] Connection already destroyed" << std::endl; - return; - } - self->onRead(bytes_read); - }); - } - - void onRead(int bytes_read) { - if (!started_) return; - - std::cout << "[YamuxedConnection] onRead: " << bytes_read << " bytes" << std::endl; - - if (bytes_read < 0) { - // Ошибка чтения - закрываем соединение - close(); - return; - } - - // Симулируем обработку данных - processReceivedData(); - - // ВАЖНО: продолжаем чтение (создает новую асинхронную операцию!) - continueReading(); - } - - void processReceivedData() { - // Симулируем создание новых потоков при получении данных - std::cout << "[YamuxedConnection] Processing received data" << std::endl; - } - - void createMockStreams() { - // Симулируем создание потоков - for (uint32_t i = 1; i <= 3; ++i) { - auto stream = std::make_shared(shared_from_this(), i); - streams_[i] = stream; - - // Симулируем асинхронные операции потоков - stream->simulateAsyncRead(); - } - - std::cout << "[YamuxedConnection] Created " << streams_.size() << " streams" << std::endl; - } - - void closeAllStreams() { - std::cout << "[YamuxedConnection] Closing " << streams_.size() << " streams" << std::endl; - - for (auto& [id, stream] : streams_) { - if (stream) { - stream->close(); - } - } - streams_.clear(); - } - - void setTimerCleanup() { - auto weak_self = std::weak_ptr(shared_from_this()); - - cleanup_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Cleanup: object already destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Cleanup: connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Cleanup executed for " << self->remote_peer_.toBase58() << std::endl; - - // Очистка потоков - self->cleanupAbandonedStreams(); - - // ПРОБЛЕМА: рекурсивный вызов! - self->setTimerCleanup(); - }, - std::chrono::milliseconds(150) - ); - - std::cout << "[YamuxedConnection] Set cleanup timer for " << remote_peer_.toBase58() << std::endl; - } - - void setTimerPing() { - auto weak_self = std::weak_ptr(shared_from_this()); - - ping_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Ping: object already destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Ping: connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Ping executed for " << self->remote_peer_.toBase58() << std::endl; - - // Симулируем отправку ping - self->sendPing(); - - // ПРОБЛЕМА: рекурсивный вызов! - self->setTimerPing(); - }, - std::chrono::milliseconds(100) - ); - - std::cout << "[YamuxedConnection] Set ping timer for " << remote_peer_.toBase58() << std::endl; - } - - void cleanupAbandonedStreams() { - std::cout << "[YamuxedConnection] Cleanup: checking " << streams_.size() << " streams" << std::endl; - // В реальном коде здесь проверяется use_count потоков - } - - void sendPing() { - // Симулируем асинхронную отправку ping - std::vector ping_data = {0x01, 0x02, 0x03}; - auto weak_self = std::weak_ptr(shared_from_this()); - - connection_->writeSome(ping_data, [weak_self](int result) { - auto self = weak_self.lock(); - if (self) { - std::cout << "[YamuxedConnection] Ping sent, result: " << result << std::endl; - } - }); - } - - void cancelAllTimers() { - std::cout << "[YamuxedConnection] === CANCELLING ALL TIMERS === for " << remote_peer_.toBase58() << std::endl; - - ping_handle_.reset(); - cleanup_handle_.reset(); - - std::cout << "[YamuxedConnection] === ALL TIMERS CANCELLED ===" << std::endl; - } - -private: - std::shared_ptr connection_; - std::shared_ptr scheduler_; - ConnectionClosedCallback closed_callback_; - peer::PeerId remote_peer_; - bool started_ = false; - bool closed_ = false; - bool registered_in_manager_ = false; - - // Буфер для чтения (как в реальном коде) - std::vector raw_read_buffer_; - - // Потоки (как streams_ в реальном коде) - std::unordered_map> streams_; - - // Таймеры - basic::Scheduler::Handle ping_handle_; - basic::Scheduler::Handle cleanup_handle_; -}; - -} // namespace connection - -namespace network { - -class ConnectionManagerTest { -public: - using ConnectionSPtr = std::shared_ptr; - - void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { - connections_[peer].insert(conn); - std::cout << "[ConnectionManager] Added connection for " << peer.toBase58() - << " (total: " << connections_[peer].size() << ")" << std::endl; - } - - void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { - std::cout << "[ConnectionManager] onConnectionClosed for " << peer.toBase58() - << " (use_count: " << connection.use_count() << ")" << std::endl; - - auto it = connections_.find(peer); - if (it != connections_.end()) { - it->second.erase(connection); - if (it->second.empty()) { - connections_.erase(it); - std::cout << "[ConnectionManager] Removed peer " << peer.toBase58() << std::endl; - } - } - - std::cout << "[ConnectionManager] Final use_count: " << connection.use_count() << std::endl; - } - - size_t getTotalConnections() const { - size_t total = 0; - for (const auto& [peer, conns] : connections_) { - total += conns.size(); - } - return total; - } - -private: - std::unordered_map> connections_; -}; - -} // namespace network -} // namespace libp2p - -class CompleteYamuxLeakTest { -public: - void runTest() { - std::cout << "\n=== COMPLETE YAMUX MEMORY LEAK TEST ===" << std::endl; - - auto scheduler = std::make_shared(); - auto connection_manager = std::make_shared(); - - auto peer_id = "complete_test_peer"; - auto secure_conn = std::make_shared(peer_id); - - auto callback = [connection_manager](const libp2p::peer::PeerId& peer, - std::shared_ptr conn) { - connection_manager->onConnectionClosed(peer, conn); - }; - - { - auto yamux_conn = std::make_shared( - secure_conn, scheduler, callback); - - yamux_conn->markAsRegistered(); - connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); - - std::cout << "\n--- Starting connection (full simulation) ---" << std::endl; - yamux_conn->start(); - - std::cout << "\n--- Initial state ---" << std::endl; - std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; - std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; - scheduler->printStats(); - - // Даем время на выполнение асинхронных операций - std::cout << "\n--- Running async operations (500ms) ---" << std::endl; - for (int i = 0; i < 10; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - std::cout << "\n--- After async operations ---" << std::endl; - std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; - scheduler->printStats(); - - std::cout << "\n--- Closing connection ---" << std::endl; - yamux_conn->close(); - - std::cout << "\n--- After close() call ---" << std::endl; - std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; - scheduler->printStats(); - } - - std::cout << "\n--- After yamux_conn goes out of scope ---" << std::endl; - std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; - scheduler->printStats(); - - // Финальная очистка - std::cout << "\n--- Final cleanup (1000ms) ---" << std::endl; - for (int i = 0; i < 20; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - std::cout << "\n=== FINAL RESULTS ===" << std::endl; - std::cout << "Active connections: " << connection_manager->getTotalConnections() << std::endl; - scheduler->printStats(); - - if (scheduler->getActiveCallbacksCount() > 0) { - std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; - std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; - std::cout << "This indicates that timers were not properly cancelled!" << std::endl; - } else { - std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; - std::cout << "All async operations completed and timers cancelled properly." << std::endl; - } - } -}; - -int main() { - CompleteYamuxLeakTest test; - test.runTest(); - return 0; -} \ No newline at end of file diff --git a/test_yamux_leaks b/test_yamux_leaks deleted file mode 100755 index 42c93cb373d87421d5b57b61c88a760ee165f7a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239088 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Реалистичный тест утечек памяти в YamuxedConnection - -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id; - PeerId(const std::string& id_) : id(id_) {} - std::string toBase58() const { return id; } - bool operator==(const PeerId& other) const { return id == other.id; } -}; -} -} - -namespace std { -template <> -struct hash { - size_t operator()(const libp2p::peer::PeerId& peer) const { - return hash()(peer.id); - } -}; -} - -namespace libp2p { - -namespace basic { - -// Реалистичная эмуляция Scheduler с накоплением колбэков -class RealisticScheduler : public std::enable_shared_from_this { -public: - struct Handle { - int id = -1; - std::weak_ptr scheduler; - - void reset() { - if (auto sched = scheduler.lock()) { - sched->cancelHandle(id); - } - id = -1; - } - - bool has_value() const { return id >= 0; } - - Handle() = default; - Handle(int id_, std::weak_ptr sched) - : id(id_), scheduler(sched) {} - }; - - Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { - std::lock_guard lock(mutex_); - - int handle_id = next_id_++; - - // Эмулируем хранение колбэков в Scheduler (это источник утечки!) - scheduled_callbacks_[handle_id] = { - .callback = std::move(cb), - .execute_time = std::chrono::steady_clock::now() + delay, - .cancelled = false - }; - - total_scheduled_++; - std::cout << "[Scheduler] Scheduled callback " << handle_id - << ", total active: " << scheduled_callbacks_.size() << std::endl; - - return Handle(handle_id, weak_from_this()); - } - - void cancelHandle(int handle_id) { - std::lock_guard lock(mutex_); - - auto it = scheduled_callbacks_.find(handle_id); - if (it != scheduled_callbacks_.end()) { - it->second.cancelled = true; - // В реальном Scheduler отмененные колбэки могут не удаляться сразу! - // scheduled_callbacks_.erase(it); // Закомментировано для эмуляции проблемы - total_cancelled_++; - std::cout << "[Scheduler] Cancelled callback " << handle_id - << ", total active: " << scheduled_callbacks_.size() << std::endl; - } - } - - // Эмулируем выполнение колбэков - void processCallbacks() { - std::lock_guard lock(mutex_); - - auto now = std::chrono::steady_clock::now(); - std::vector to_execute; - - for (auto& [id, info] : scheduled_callbacks_) { - if (!info.cancelled && info.execute_time <= now) { - to_execute.push_back(id); - } - } - - for (int id : to_execute) { - auto it = scheduled_callbacks_.find(id); - if (it != scheduled_callbacks_.end() && !it->second.cancelled) { - auto callback = std::move(it->second.callback); - scheduled_callbacks_.erase(it); - - // Выполняем callback без блокировки - mutex_.unlock(); - std::cout << "[Scheduler] Executing callback " << id << std::endl; - callback(); - mutex_.lock(); - - total_executed_++; - } - } - } - - void printStats() const { - std::lock_guard lock(mutex_); - std::cout << "[Scheduler] Stats:" << std::endl; - std::cout << " Total scheduled: " << total_scheduled_ << std::endl; - std::cout << " Total executed: " << total_executed_ << std::endl; - std::cout << " Total cancelled: " << total_cancelled_ << std::endl; - std::cout << " Currently active: " << scheduled_callbacks_.size() << std::endl; - - // Проблема: активные колбэки могут держать weak_ptr, которые при выполнении - // становятся shared_ptr и продлевают жизнь объектов! - if (!scheduled_callbacks_.empty()) { - std::cout << " WARNING: Non-zero active callbacks - potential memory leak!" << std::endl; - } - } - - size_t getActiveCallbacksCount() const { - std::lock_guard lock(mutex_); - return scheduled_callbacks_.size(); - } - -private: - mutable std::mutex mutex_; - - struct CallbackInfo { - std::function callback; - std::chrono::steady_clock::time_point execute_time; - bool cancelled; - }; - - std::unordered_map scheduled_callbacks_; - int next_id_ = 1; - int total_scheduled_ = 0; - int total_executed_ = 0; - int total_cancelled_ = 0; -}; - -using Scheduler = RealisticScheduler; - -} // namespace basic - -namespace connection { - -struct SecureConnection { - peer::PeerId remote_peer; - bool closed = false; - - SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} - - peer::PeerId remotePeer() const { return remote_peer; } - bool isClosed() const { return closed; } - void close() { closed = true; } -}; - -// Реалистичная версия YamuxedConnection с таймерами -class YamuxedConnection : public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function)>; - - explicit YamuxedConnection( - std::shared_ptr connection, - std::shared_ptr scheduler, - ConnectionClosedCallback closed_callback) - : connection_(std::move(connection)) - , scheduler_(std::move(scheduler)) - , closed_callback_(std::move(closed_callback)) - , remote_peer_(connection_->remotePeer()) { - - std::cout << "[YamuxedConnection] Created connection to " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - ~YamuxedConnection() { - std::cout << "[YamuxedConnection] *** DESTRUCTOR *** for " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - void start() { - started_ = true; - std::cout << "[YamuxedConnection] Started connection to " - << remote_peer_.toBase58() << std::endl; - - // Запускаем таймеры (источник проблемы!) - setTimerCleanup(); - setTimerPing(); - setTimerInactivity(); - } - - void stop() { - if (!started_) return; - - started_ = false; - std::cout << "[YamuxedConnection] Stopping connection to " - << remote_peer_.toBase58() << std::endl; - - // ДО ИСПРАВЛЕНИЯ: таймеры не отменялись! - // ПОСЛЕ ИСПРАВЛЕНИЯ: отменяем все таймеры - cancelAllTimers(); - } - - void close() { - if (closed_) return; - - auto self_ptr = shared_from_this(); - std::cout << "[YamuxedConnection] Closing connection to " - << remote_peer_.toBase58() - << " (use_count: " << self_ptr.use_count() << ")" << std::endl; - - closed_ = true; - connection_->close(); - - // ДО ИСПРАВЛЕНИЯ: таймеры не отменялись! - // ПОСЛЕ ИСПРАВЛЕНИЯ: отменяем все таймеры - cancelAllTimers(); - - // Вызываем callback для ConnectionManager - if (closed_callback_ && registered_in_manager_) { - std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " - << self_ptr.use_count() << std::endl; - - closed_callback_(remote_peer_, self_ptr); - } - } - - bool isClosed() const { return closed_; } - peer::PeerId remotePeer() const { return remote_peer_; } - - void markAsRegistered() { - registered_in_manager_ = true; - } - - long getSharedPtrUseCount() const { - auto self_ptr = shared_from_this(); - return self_ptr.use_count(); - } - -private: - void setTimerCleanup() { - auto weak_self = std::weak_ptr(shared_from_this()); - - cleanup_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Cleanup: object already destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Cleanup: connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Cleanup executed for " << self->remote_peer_.toBase58() << std::endl; - - // ПРОБЛЕМА: рекурсивный вызов создает новый таймер! - self->setTimerCleanup(); - }, - std::chrono::milliseconds(150) - ); - - std::cout << "[YamuxedConnection] Set cleanup timer for " << remote_peer_.toBase58() << std::endl; - } - - void setTimerPing() { - auto weak_self = std::weak_ptr(shared_from_this()); - - ping_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Ping: object already destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Ping: connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Ping executed for " << self->remote_peer_.toBase58() << std::endl; - - // ПРОБЛЕМА: рекурсивный вызов создает новый таймер! - self->setTimerPing(); - }, - std::chrono::milliseconds(100) - ); - - std::cout << "[YamuxedConnection] Set ping timer for " << remote_peer_.toBase58() << std::endl; - } - - void setTimerInactivity() { - auto weak_self = std::weak_ptr(shared_from_this()); - - inactivity_handle_ = scheduler_->scheduleWithHandle( - [weak_self]() { - auto self = weak_self.lock(); - if (!self) { - std::cout << "[Timer] Inactivity: object already destroyed" << std::endl; - return; - } - if (!self->started_) { - std::cout << "[Timer] Inactivity: connection stopped" << std::endl; - return; - } - - std::cout << "[Timer] Inactivity executed for " << self->remote_peer_.toBase58() << std::endl; - - // Этот таймер может закрыть соединение - self->close(); - }, - std::chrono::milliseconds(500) - ); - - std::cout << "[YamuxedConnection] Set inactivity timer for " << remote_peer_.toBase58() << std::endl; - } - - void cancelAllTimers() { - std::cout << "[YamuxedConnection] === CANCELLING ALL TIMERS === for " << remote_peer_.toBase58() << std::endl; - - ping_handle_.reset(); - cleanup_handle_.reset(); - inactivity_handle_.reset(); - - std::cout << "[YamuxedConnection] === ALL TIMERS CANCELLED ===" << std::endl; - } - -private: - std::shared_ptr connection_; - std::shared_ptr scheduler_; - ConnectionClosedCallback closed_callback_; - peer::PeerId remote_peer_; - bool started_ = false; - bool closed_ = false; - bool registered_in_manager_ = false; - - // Таймеры - basic::Scheduler::Handle ping_handle_; - basic::Scheduler::Handle cleanup_handle_; - basic::Scheduler::Handle inactivity_handle_; -}; - -} // namespace connection - -namespace network { - -class ConnectionManagerTest { -public: - using ConnectionSPtr = std::shared_ptr; - - void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { - connections_[peer].insert(conn); - std::cout << "[ConnectionManager] Added connection for " << peer.toBase58() - << " (total: " << connections_[peer].size() << ")" << std::endl; - } - - void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { - std::cout << "[ConnectionManager] onConnectionClosed for " << peer.toBase58() - << " (use_count: " << connection.use_count() << ")" << std::endl; - - auto it = connections_.find(peer); - if (it != connections_.end()) { - it->second.erase(connection); - if (it->second.empty()) { - connections_.erase(it); - std::cout << "[ConnectionManager] Removed peer " << peer.toBase58() << std::endl; - } - } - - // ВАЖНО: в этом месте connection должен быть единственной ссылкой! - // Если use_count > 1, значит есть утечка - std::cout << "[ConnectionManager] Final use_count: " << connection.use_count() << std::endl; - } - - size_t getTotalPeers() const { return connections_.size(); } - - size_t getTotalConnections() const { - size_t total = 0; - for (const auto& [peer, conns] : connections_) { - total += conns.size(); - } - return total; - } - -private: - std::unordered_map> connections_; -}; - -} // namespace network -} // namespace libp2p - -class YamuxMemoryLeakTest { -public: - void runTest() { - std::cout << "\n=== YAMUX MEMORY LEAK TEST (REALISTIC) ===" << std::endl; - - auto scheduler = std::make_shared(); - auto connection_manager = std::make_shared(); - - // Создаем соединение - auto peer_id = "leak_test_peer"; - auto secure_conn = std::make_shared(peer_id); - - auto callback = [connection_manager](const libp2p::peer::PeerId& peer, - std::shared_ptr conn) { - connection_manager->onConnectionClosed(peer, conn); - }; - - { - // Область видимости для соединения - auto yamux_conn = std::make_shared( - secure_conn, scheduler, callback); - - yamux_conn->markAsRegistered(); - connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); - - std::cout << "\n--- Starting connection (timers will be created) ---" << std::endl; - yamux_conn->start(); - - std::cout << "\n--- Initial state ---" << std::endl; - std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; - std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; - scheduler->printStats(); - - // Даем время таймерам сработать - std::cout << "\n--- Waiting for timers (250ms) ---" << std::endl; - for (int i = 0; i < 5; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - std::cout << "\n--- After timer execution ---" << std::endl; - scheduler->printStats(); - - std::cout << "\n--- Closing connection ---" << std::endl; - yamux_conn->close(); - - std::cout << "\n--- After close() call ---" << std::endl; - std::cout << "YamuxedConnection use_count: " << yamux_conn.use_count() << std::endl; - scheduler->printStats(); - } - - std::cout << "\n--- After yamux_conn goes out of scope ---" << std::endl; - std::cout << "Connections count: " << connection_manager->getTotalConnections() << std::endl; - scheduler->printStats(); - - // Даем время на финальную очистку - std::cout << "\n--- Final cleanup (500ms) ---" << std::endl; - for (int i = 0; i < 10; ++i) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - scheduler->processCallbacks(); - } - - std::cout << "\n=== FINAL RESULTS ===" << std::endl; - std::cout << "Active connections: " << connection_manager->getTotalConnections() << std::endl; - scheduler->printStats(); - - if (scheduler->getActiveCallbacksCount() > 0) { - std::cout << "\n*** MEMORY LEAK DETECTED ***" << std::endl; - std::cout << "Active callbacks in scheduler: " << scheduler->getActiveCallbacksCount() << std::endl; - std::cout << "This indicates that timers were not properly cancelled!" << std::endl; - } else { - std::cout << "\n*** NO MEMORY LEAKS DETECTED ***" << std::endl; - std::cout << "All timers were properly cancelled." << std::endl; - } - } -}; - -int main() { - YamuxMemoryLeakTest test; - test.runTest(); - return 0; -} \ No newline at end of file From 8599f21fd10cde2b4b881437bc1f53910b43ecb1 Mon Sep 17 00:00:00 2001 From: iceseer Date: Mon, 9 Jun 2025 20:31:11 +0300 Subject: [PATCH 10/21] 1 --- .../libp2p/muxer/yamux/hardware_tracker.hpp | 89 +++++++ src/muxer/yamux/hardware_tracker.cpp | 229 ++++++++++++++++++ src/muxer/yamux/yamux.cpp | 15 +- 3 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 include/libp2p/muxer/yamux/hardware_tracker.hpp create mode 100644 src/muxer/yamux/hardware_tracker.cpp diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp new file mode 100644 index 00000000..93e34410 --- /dev/null +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -0,0 +1,89 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace libp2p::connection { + +class YamuxedConnection; + +class HardwareSharedPtrTracker { +public: + static HardwareSharedPtrTracker& getInstance() { + static HardwareSharedPtrTracker instance; + return instance; + } + + // Начать отслеживание счетчика ссылок для shared_ptr + void startTracking(std::shared_ptr ptr); + + // Остановить текущее отслеживание + void stopTracking(); + + // Проверить активно ли отслеживание + bool isTracking() const { return is_tracking_; } + + // Включить/выключить отслеживание + void enable() { enabled_ = true; } + void disable() { enabled_ = false; } + +private: + HardwareSharedPtrTracker(); + ~HardwareSharedPtrTracker(); + + // Получить адрес счетчика ссылок в shared_ptr + void* getRefCountAddress(const std::shared_ptr& ptr); + + // Установить hardware watchpoint + bool setHardwareWatchpoint(void* address); + + // Удалить hardware watchpoint + bool removeHardwareWatchpoint(); + + // Обработчик сигнала при изменении памяти + static void signalHandler(int sig, siginfo_t* info, void* context); + + // Вывести стек вызовов + void printStackTrace(); + + // Проверить счетчик и переключиться на следующий объект если нужно + void checkAndSwitchIfNeeded(); + +private: + std::atomic enabled_{false}; + std::atomic is_tracking_{false}; + + void* watched_address_{nullptr}; + std::weak_ptr current_tracked_ptr_; + + // Для debug registers + static constexpr int DR7_L0 = 1; // Local enable for DR0 + static constexpr int DR7_RW0_WRITE = (1 << 16); // Watch writes to DR0 + static constexpr int DR7_LEN0_4BYTES = (3 << 18); // 4-byte length for DR0 + + static HardwareSharedPtrTracker* instance_; + struct sigaction old_sigtrap_action_; +}; + +// Глобальная функция для установки в yamux.cpp +void trackNextYamuxedConnection(std::shared_ptr ptr); + +// Макросы для удобства +#define YAMUX_HARDWARE_TRACK_ENABLE() \ + libp2p::connection::HardwareSharedPtrTracker::getInstance().enable() + +#define YAMUX_HARDWARE_TRACK_DISABLE() \ + libp2p::connection::HardwareSharedPtrTracker::getInstance().disable() + +#define YAMUX_HARDWARE_TRACK_SHARED_PTR(ptr) \ + libp2p::connection::trackNextYamuxedConnection(ptr) + +} // namespace libp2p::connection \ No newline at end of file diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp new file mode 100644 index 00000000..461bad24 --- /dev/null +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -0,0 +1,229 @@ +#include +#include + +#include +#include +#include +#include +#include + +namespace libp2p::connection { + +HardwareSharedPtrTracker* HardwareSharedPtrTracker::instance_ = nullptr; + +HardwareSharedPtrTracker::HardwareSharedPtrTracker() { + instance_ = this; + + // Установка обработчика сигнала SIGTRAP для hardware breakpoints + struct sigaction sa; + sa.sa_sigaction = signalHandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + if (sigaction(SIGTRAP, &sa, &old_sigtrap_action_) == -1) { + std::cerr << "❌ Не удалось установить обработчик SIGTRAP\n"; + } + + std::cout << "🔧 HardwareSharedPtrTracker инициализирован\n"; +} + +HardwareSharedPtrTracker::~HardwareSharedPtrTracker() { + stopTracking(); + + // Восстановить старый обработчик сигнала + sigaction(SIGTRAP, &old_sigtrap_action_, nullptr); + + instance_ = nullptr; +} + +void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr& ptr) { + // shared_ptr состоит из двух указателей: + // - указатель на объект + // - указатель на control block (содержит счетчики ссылок) + + // Получаем указатель на control block из shared_ptr + // Это внутренняя структура, но мы можем получить к ней доступ + struct shared_ptr_internal { + void* ptr; + void* control_block; + }; + + auto* internal = reinterpret_cast(&ptr); + void* control_block = internal->control_block; + + if (!control_block) { + return nullptr; + } + + // В control block счетчик shared_ptr обычно находится по смещению 0 + // (зависит от реализации стандартной библиотеки) + void* ref_count_addr = control_block; + + std::cout << "📍 Адрес control block: " << control_block << "\n"; + std::cout << "📍 Адрес счетчика ссылок: " << ref_count_addr << "\n"; + std::cout << "📍 Текущий use_count: " << ptr.use_count() << "\n"; + + return ref_count_addr; +} + +bool HardwareSharedPtrTracker::setHardwareWatchpoint(void* address) { + // Используем perf_event для hardware watchpoint + struct perf_event_attr pe; + memset(&pe, 0, sizeof(pe)); + + pe.type = PERF_TYPE_BREAKPOINT; + pe.size = sizeof(pe); + pe.config = 0; + pe.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; // Watch reads and writes + pe.bp_addr = reinterpret_cast(address); + pe.bp_len = sizeof(long); // Размер счетчика ссылок + pe.disabled = 0; + pe.exclude_kernel = 1; + pe.exclude_hv = 1; + + // Создаем hardware breakpoint через perf_event_open + int fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); + if (fd == -1) { + perror("❌ perf_event_open для hardware watchpoint"); + return false; + } + + std::cout << "✅ Hardware watchpoint установлен на адрес " << address + << " (fd=" << fd << ")\n"; + + return true; +} + +bool HardwareSharedPtrTracker::removeHardwareWatchpoint() { + // В реальной реализации здесь должно быть удаление watchpoint + // Но для простоты пока оставляем пустым + std::cout << "🗑️ Hardware watchpoint удален\n"; + return true; +} + +void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* context) { + if (!instance_ || sig != SIGTRAP) { + return; + } + + std::cout << "\n🎯 === HARDWARE BREAKPOINT TRIGGERED ===\n"; + std::cout << "Сигнал: " << sig << "\n"; + std::cout << "Адрес: " << info->si_addr << "\n"; + + // Выводим стек вызовов + instance_->printStackTrace(); + + // Проверяем нужно ли переключиться на следующий объект + instance_->checkAndSwitchIfNeeded(); + + std::cout << "==========================================\n\n"; +} + +void HardwareSharedPtrTracker::printStackTrace() { + const int max_frames = 20; + void* buffer[max_frames]; + + int nframes = backtrace(buffer, max_frames); + char** symbols = backtrace_symbols(buffer, nframes); + + std::cout << "📚 Стек вызовов (изменение счетчика ссылок):\n"; + + for (int i = 0; i < nframes; ++i) { + std::cout << " [" << i << "] " << (symbols ? symbols[i] : "???") << "\n"; + } + + if (symbols) { + free(symbols); + } +} + +void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() { + // Проверяем жив ли текущий отслеживаемый объект + if (auto ptr = current_tracked_ptr_.lock()) { + long count = ptr.use_count(); + std::cout << "📊 Текущий use_count: " << count << "\n"; + + if (count <= 1) { + std::cout << "💀 Объект скоро будет удален (use_count=" << count << ")\n"; + std::cout << "🔄 Ожидаем следующий YamuxedConnection для отслеживания...\n"; + + // Останавливаем текущее отслеживание + stopTracking(); + } + } else { + std::cout << "💀 Отслеживаемый объект уже удален\n"; + std::cout << "🔄 Ожидаем следующий YamuxedConnection для отслеживания...\n"; + + // Останавливаем текущее отслеживание + stopTracking(); + } +} + +void HardwareSharedPtrTracker::startTracking(std::shared_ptr ptr) { + if (!enabled_) { + return; + } + + // Если уже что-то отслеживаем - останавливаем + if (is_tracking_) { + stopTracking(); + } + + std::cout << "\n🎯 === НАЧАЛО HARDWARE ОТСЛЕЖИВАНИЯ ===\n"; + std::cout << "YamuxedConnection адрес: " << ptr.get() << "\n"; + std::cout << "shared_ptr use_count: " << ptr.use_count() << "\n"; + + // Получаем адрес счетчика ссылок + void* ref_count_addr = getRefCountAddress(ptr); + if (!ref_count_addr) { + std::cerr << "❌ Не удалось получить адрес счетчика ссылок\n"; + return; + } + + // Устанавливаем hardware watchpoint + if (!setHardwareWatchpoint(ref_count_addr)) { + std::cerr << "❌ Не удалось установить hardware watchpoint\n"; + return; + } + + // Сохраняем состояние + watched_address_ = ref_count_addr; + current_tracked_ptr_ = ptr; + is_tracking_ = true; + + std::cout << "✅ Hardware отслеживание активировано\n"; + std::cout << "==========================================\n\n"; +} + +void HardwareSharedPtrTracker::stopTracking() { + if (!is_tracking_) { + return; + } + + std::cout << "\n🛑 === ОСТАНОВКА HARDWARE ОТСЛЕЖИВАНИЯ ===\n"; + + // Удаляем hardware watchpoint + removeHardwareWatchpoint(); + + // Сбрасываем состояние + watched_address_ = nullptr; + current_tracked_ptr_.reset(); + is_tracking_ = false; + + std::cout << "✅ Hardware отслеживание остановлено\n"; + std::cout << "==========================================\n\n"; +} + +// Глобальная функция для использования в yamux.cpp +void trackNextYamuxedConnection(std::shared_ptr ptr) { + auto& tracker = HardwareSharedPtrTracker::getInstance(); + + // Если сейчас ничего не отслеживается - начинаем отслеживание + if (!tracker.isTracking()) { + tracker.startTracking(std::move(ptr)); + } else { + std::cout << "⏳ Уже отслеживается другой YamuxedConnection, ждем его завершения...\n"; + } +} + +} // namespace libp2p::connection \ No newline at end of file diff --git a/src/muxer/yamux/yamux.cpp b/src/muxer/yamux/yamux.cpp index 96ee3d85..44e82ec5 100644 --- a/src/muxer/yamux/yamux.cpp +++ b/src/muxer/yamux/yamux.cpp @@ -9,6 +9,10 @@ #include #include +#ifdef YAMUX_HARDWARE_TRACKING +#include +#endif + namespace libp2p::muxer { Yamux::Yamux(MuxedConnectionConfig config, std::shared_ptr scheduler, @@ -43,7 +47,14 @@ namespace libp2p::muxer { "inactive connection passed to muxer: {}", res.error()); return cb(res.error()); } - cb(std::make_shared( - std::move(conn), scheduler_, close_cb_, config_)); + + auto yamux_connection = std::make_shared( + std::move(conn), scheduler_, close_cb_, config_); + +#ifdef YAMUX_HARDWARE_TRACKING + connection::trackNextYamuxedConnection(yamux_connection); +#endif + + cb(yamux_connection); } } // namespace libp2p::muxer From 6112c4b1f867bc0c4723f4c20b2b1bac04417fb3 Mon Sep 17 00:00:00 2001 From: iceseer Date: Mon, 9 Jun 2025 20:37:20 +0300 Subject: [PATCH 11/21] 2 --- .../libp2p/muxer/yamux/hardware_tracker.hpp | 26 +++--- src/muxer/yamux/hardware_tracker.cpp | 92 ++++++------------- 2 files changed, 43 insertions(+), 75 deletions(-) diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp index 93e34410..b084b89d 100644 --- a/include/libp2p/muxer/yamux/hardware_tracker.hpp +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -22,16 +22,16 @@ class HardwareSharedPtrTracker { return instance; } - // Начать отслеживание счетчика ссылок для shared_ptr + // Start tracking the reference count of a shared_ptr void startTracking(std::shared_ptr ptr); - // Остановить текущее отслеживание + // Stop current tracking void stopTracking(); - // Проверить активно ли отслеживание + // Check if tracking is active bool isTracking() const { return is_tracking_; } - // Включить/выключить отслеживание + // Enable/disable tracking void enable() { enabled_ = true; } void disable() { enabled_ = false; } @@ -39,22 +39,22 @@ class HardwareSharedPtrTracker { HardwareSharedPtrTracker(); ~HardwareSharedPtrTracker(); - // Получить адрес счетчика ссылок в shared_ptr + // Get the address of the reference count in a shared_ptr void* getRefCountAddress(const std::shared_ptr& ptr); - // Установить hardware watchpoint + // Set hardware watchpoint bool setHardwareWatchpoint(void* address); - // Удалить hardware watchpoint + // Remove hardware watchpoint bool removeHardwareWatchpoint(); - // Обработчик сигнала при изменении памяти + // Signal handler for memory changes static void signalHandler(int sig, siginfo_t* info, void* context); - // Вывести стек вызовов + // Print stack trace void printStackTrace(); - // Проверить счетчик и переключиться на следующий объект если нужно + // Check counter and switch to the next object if needed void checkAndSwitchIfNeeded(); private: @@ -64,7 +64,7 @@ class HardwareSharedPtrTracker { void* watched_address_{nullptr}; std::weak_ptr current_tracked_ptr_; - // Для debug registers + // For debug registers static constexpr int DR7_L0 = 1; // Local enable for DR0 static constexpr int DR7_RW0_WRITE = (1 << 16); // Watch writes to DR0 static constexpr int DR7_LEN0_4BYTES = (3 << 18); // 4-byte length for DR0 @@ -73,10 +73,10 @@ class HardwareSharedPtrTracker { struct sigaction old_sigtrap_action_; }; -// Глобальная функция для установки в yamux.cpp +// Global function for setting in yamux.cpp void trackNextYamuxedConnection(std::shared_ptr ptr); -// Макросы для удобства +// Macros for convenience #define YAMUX_HARDWARE_TRACK_ENABLE() \ libp2p::connection::HardwareSharedPtrTracker::getInstance().enable() diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index 461bad24..65bb7721 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -14,35 +14,25 @@ HardwareSharedPtrTracker* HardwareSharedPtrTracker::instance_ = nullptr; HardwareSharedPtrTracker::HardwareSharedPtrTracker() { instance_ = this; - // Установка обработчика сигнала SIGTRAP для hardware breakpoints struct sigaction sa; sa.sa_sigaction = signalHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_RESTART; if (sigaction(SIGTRAP, &sa, &old_sigtrap_action_) == -1) { - std::cerr << "❌ Не удалось установить обработчик SIGTRAP\n"; + std::cerr << "Failed to install SIGTRAP handler\n"; } - std::cout << "🔧 HardwareSharedPtrTracker инициализирован\n"; + std::cout << "HardwareSharedPtrTracker initialized\n"; } HardwareSharedPtrTracker::~HardwareSharedPtrTracker() { stopTracking(); - - // Восстановить старый обработчик сигнала sigaction(SIGTRAP, &old_sigtrap_action_, nullptr); - instance_ = nullptr; } void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr& ptr) { - // shared_ptr состоит из двух указателей: - // - указатель на объект - // - указатель на control block (содержит счетчики ссылок) - - // Получаем указатель на control block из shared_ptr - // Это внутренняя структура, но мы можем получить к ней доступ struct shared_ptr_internal { void* ptr; void* control_block; @@ -55,49 +45,43 @@ void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr(address); - pe.bp_len = sizeof(long); // Размер счетчика ссылок + pe.bp_len = sizeof(long); pe.disabled = 0; pe.exclude_kernel = 1; pe.exclude_hv = 1; - // Создаем hardware breakpoint через perf_event_open int fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); if (fd == -1) { - perror("❌ perf_event_open для hardware watchpoint"); + perror("perf_event_open for hardware watchpoint failed"); return false; } - std::cout << "✅ Hardware watchpoint установлен на адрес " << address + std::cout << "Hardware watchpoint set on address " << address << " (fd=" << fd << ")\n"; return true; } bool HardwareSharedPtrTracker::removeHardwareWatchpoint() { - // В реальной реализации здесь должно быть удаление watchpoint - // Но для простоты пока оставляем пустым - std::cout << "🗑️ Hardware watchpoint удален\n"; + std::cout << "Hardware watchpoint removed\n"; return true; } @@ -106,17 +90,14 @@ void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* con return; } - std::cout << "\n🎯 === HARDWARE BREAKPOINT TRIGGERED ===\n"; - std::cout << "Сигнал: " << sig << "\n"; - std::cout << "Адрес: " << info->si_addr << "\n"; + std::cout << "\n=== HARDWARE BREAKPOINT TRIGGERED ===\n"; + std::cout << "Signal: " << sig << "\n"; + std::cout << "Address: " << info->si_addr << "\n"; - // Выводим стек вызовов instance_->printStackTrace(); - - // Проверяем нужно ли переключиться на следующий объект instance_->checkAndSwitchIfNeeded(); - std::cout << "==========================================\n\n"; + std::cout << "====================================\n\n"; } void HardwareSharedPtrTracker::printStackTrace() { @@ -126,7 +107,7 @@ void HardwareSharedPtrTracker::printStackTrace() { int nframes = backtrace(buffer, max_frames); char** symbols = backtrace_symbols(buffer, nframes); - std::cout << "📚 Стек вызовов (изменение счетчика ссылок):\n"; + std::cout << "Stack trace (reference count change):\n"; for (int i = 0; i < nframes; ++i) { std::cout << " [" << i << "] " << (symbols ? symbols[i] : "???") << "\n"; @@ -138,23 +119,18 @@ void HardwareSharedPtrTracker::printStackTrace() { } void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() { - // Проверяем жив ли текущий отслеживаемый объект if (auto ptr = current_tracked_ptr_.lock()) { long count = ptr.use_count(); - std::cout << "📊 Текущий use_count: " << count << "\n"; + std::cout << "Current use_count: " << count << "\n"; if (count <= 1) { - std::cout << "💀 Объект скоро будет удален (use_count=" << count << ")\n"; - std::cout << "🔄 Ожидаем следующий YamuxedConnection для отслеживания...\n"; - - // Останавливаем текущее отслеживание + std::cout << "Object will be deleted soon (use_count=" << count << ")\n"; + std::cout << "Waiting for next YamuxedConnection to track...\n"; stopTracking(); } } else { - std::cout << "💀 Отслеживаемый объект уже удален\n"; - std::cout << "🔄 Ожидаем следующий YamuxedConnection для отслеживания...\n"; - - // Останавливаем текущее отслеживание + std::cout << "Tracked object already deleted\n"; + std::cout << "Waiting for next YamuxedConnection to track...\n"; stopTracking(); } } @@ -164,35 +140,31 @@ void HardwareSharedPtrTracker::startTracking(std::shared_ptr return; } - // Если уже что-то отслеживаем - останавливаем if (is_tracking_) { stopTracking(); } - std::cout << "\n🎯 === НАЧАЛО HARDWARE ОТСЛЕЖИВАНИЯ ===\n"; - std::cout << "YamuxedConnection адрес: " << ptr.get() << "\n"; + std::cout << "\n=== HARDWARE TRACKING STARTED ===\n"; + std::cout << "YamuxedConnection address: " << ptr.get() << "\n"; std::cout << "shared_ptr use_count: " << ptr.use_count() << "\n"; - // Получаем адрес счетчика ссылок void* ref_count_addr = getRefCountAddress(ptr); if (!ref_count_addr) { - std::cerr << "❌ Не удалось получить адрес счетчика ссылок\n"; + std::cerr << "Failed to get reference count address\n"; return; } - // Устанавливаем hardware watchpoint if (!setHardwareWatchpoint(ref_count_addr)) { - std::cerr << "❌ Не удалось установить hardware watchpoint\n"; + std::cerr << "Failed to set hardware watchpoint\n"; return; } - // Сохраняем состояние watched_address_ = ref_count_addr; current_tracked_ptr_ = ptr; is_tracking_ = true; - std::cout << "✅ Hardware отслеживание активировано\n"; - std::cout << "==========================================\n\n"; + std::cout << "Hardware tracking activated\n"; + std::cout << "=================================\n\n"; } void HardwareSharedPtrTracker::stopTracking() { @@ -200,29 +172,25 @@ void HardwareSharedPtrTracker::stopTracking() { return; } - std::cout << "\n🛑 === ОСТАНОВКА HARDWARE ОТСЛЕЖИВАНИЯ ===\n"; + std::cout << "\n=== HARDWARE TRACKING STOPPED ===\n"; - // Удаляем hardware watchpoint removeHardwareWatchpoint(); - // Сбрасываем состояние watched_address_ = nullptr; current_tracked_ptr_.reset(); is_tracking_ = false; - std::cout << "✅ Hardware отслеживание остановлено\n"; - std::cout << "==========================================\n\n"; + std::cout << "Hardware tracking stopped\n"; + std::cout << "=================================\n\n"; } -// Глобальная функция для использования в yamux.cpp void trackNextYamuxedConnection(std::shared_ptr ptr) { auto& tracker = HardwareSharedPtrTracker::getInstance(); - // Если сейчас ничего не отслеживается - начинаем отслеживание if (!tracker.isTracking()) { tracker.startTracking(std::move(ptr)); } else { - std::cout << "⏳ Уже отслеживается другой YamuxedConnection, ждем его завершения...\n"; + std::cout << "Already tracking another YamuxedConnection, waiting for completion...\n"; } } From a436c9c07c8d06d315757896cbe5573c1299f369 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 00:16:04 +0300 Subject: [PATCH 12/21] 3 --- src/muxer/yamux/hardware_tracker.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index 65bb7721..44ac4c01 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -141,7 +141,10 @@ void HardwareSharedPtrTracker::startTracking(std::shared_ptr } if (is_tracking_) { - stopTracking(); + std::cout << "Already tracking another YamuxedConnection (address: " + << (current_tracked_ptr_.expired() ? "expired" : "active") + << "), ignoring new request\n"; + return; } std::cout << "\n=== HARDWARE TRACKING STARTED ===\n"; From ce20de1cc6f1a97be130ced1ba167e893daf88af Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 00:24:00 +0300 Subject: [PATCH 13/21] fix --- .../libp2p/muxer/yamux/hardware_tracker.hpp | 2 + src/muxer/yamux/hardware_tracker.cpp | 51 +++++++++++-------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp index b084b89d..a7f22f4e 100644 --- a/include/libp2p/muxer/yamux/hardware_tracker.hpp +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -60,8 +60,10 @@ class HardwareSharedPtrTracker { private: std::atomic enabled_{false}; std::atomic is_tracking_{false}; + std::atomic should_stop_{false}; // Flag for signal handler void* watched_address_{nullptr}; + int watchpoint_fd_{-1}; // Store perf_event fd std::weak_ptr current_tracked_ptr_; // For debug registers diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index 44ac4c01..e915d0c9 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -74,6 +74,8 @@ bool HardwareSharedPtrTracker::setHardwareWatchpoint(void* address) { return false; } + watchpoint_fd_ = fd; + std::cout << "Hardware watchpoint set on address " << address << " (fd=" << fd << ")\n"; @@ -81,8 +83,13 @@ bool HardwareSharedPtrTracker::setHardwareWatchpoint(void* address) { } bool HardwareSharedPtrTracker::removeHardwareWatchpoint() { - std::cout << "Hardware watchpoint removed\n"; - return true; + if (watchpoint_fd_ != -1) { + close(watchpoint_fd_); + watchpoint_fd_ = -1; + std::cout << "Hardware watchpoint removed\n"; + return true; + } + return false; } void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* context) { @@ -90,14 +97,7 @@ void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* con return; } - std::cout << "\n=== HARDWARE BREAKPOINT TRIGGERED ===\n"; - std::cout << "Signal: " << sig << "\n"; - std::cout << "Address: " << info->si_addr << "\n"; - - instance_->printStackTrace(); - instance_->checkAndSwitchIfNeeded(); - - std::cout << "====================================\n\n"; + instance_->should_stop_ = true; } void HardwareSharedPtrTracker::printStackTrace() { @@ -119,19 +119,26 @@ void HardwareSharedPtrTracker::printStackTrace() { } void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() { - if (auto ptr = current_tracked_ptr_.lock()) { - long count = ptr.use_count(); - std::cout << "Current use_count: " << count << "\n"; + if (should_stop_.exchange(false)) { + std::cout << "\n=== HARDWARE BREAKPOINT TRIGGERED ===\n"; + printStackTrace(); - if (count <= 1) { - std::cout << "Object will be deleted soon (use_count=" << count << ")\n"; - std::cout << "Waiting for next YamuxedConnection to track...\n"; + if (auto ptr = current_tracked_ptr_.lock()) { + long count = ptr.use_count(); + std::cout << "Current use_count: " << count << "\n"; + + if (count <= 1) { + std::cout << "Object will be deleted soon (use_count=" << count << ")\n"; + std::cout << "Stopping hardware tracking\n"; + stopTracking(); + } + } else { + std::cout << "Tracked object already deleted\n"; + std::cout << "Stopping hardware tracking\n"; stopTracking(); } - } else { - std::cout << "Tracked object already deleted\n"; - std::cout << "Waiting for next YamuxedConnection to track...\n"; - stopTracking(); + + std::cout << "====================================\n\n"; } } @@ -165,6 +172,7 @@ void HardwareSharedPtrTracker::startTracking(std::shared_ptr watched_address_ = ref_count_addr; current_tracked_ptr_ = ptr; is_tracking_ = true; + should_stop_ = false; std::cout << "Hardware tracking activated\n"; std::cout << "=================================\n\n"; @@ -182,6 +190,7 @@ void HardwareSharedPtrTracker::stopTracking() { watched_address_ = nullptr; current_tracked_ptr_.reset(); is_tracking_ = false; + should_stop_ = false; std::cout << "Hardware tracking stopped\n"; std::cout << "=================================\n\n"; @@ -190,6 +199,8 @@ void HardwareSharedPtrTracker::stopTracking() { void trackNextYamuxedConnection(std::shared_ptr ptr) { auto& tracker = HardwareSharedPtrTracker::getInstance(); + tracker.checkAndSwitchIfNeeded(); + if (!tracker.isTracking()) { tracker.startTracking(std::move(ptr)); } else { From 2e69564eb469c026b58140b68f245491b93594f4 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 09:13:36 +0300 Subject: [PATCH 14/21] test --- src/muxer/yamux/hardware_tracker.cpp | 44 ++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index e915d0c9..c8be45a3 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -96,12 +96,37 @@ void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* con if (!instance_ || sig != SIGTRAP) { return; } + + // printStackTrace(); + + static int call_number = 0; + call_number++; + + const char msg[] = "\n=== HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED ===\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); + + char call_msg[100]; + int len = snprintf(call_msg, sizeof(call_msg), "Call #%d - Address: %p\n", call_number, info->si_addr); + write(STDOUT_FILENO, call_msg, len); - instance_->should_stop_ = true; + const int max_frames = 15; + void* buffer[max_frames]; + + const char stack_msg[] = "Stack trace (exact location of reference count change):\n"; + write(STDOUT_FILENO, stack_msg, sizeof(stack_msg) - 1); + + int nframes = backtrace(buffer, max_frames); + + backtrace_symbols_fd(buffer, nframes, STDOUT_FILENO); + + const char end_msg[] = "================================================\n\n"; + write(STDOUT_FILENO, end_msg, sizeof(end_msg) - 1); + + //instance_->signal_count_.fetch_add(1, std::memory_order_relaxed); } void HardwareSharedPtrTracker::printStackTrace() { - const int max_frames = 20; + const int max_frames = 7; void* buffer[max_frames]; int nframes = backtrace(buffer, max_frames); @@ -147,13 +172,13 @@ void HardwareSharedPtrTracker::startTracking(std::shared_ptr return; } - if (is_tracking_) { - std::cout << "Already tracking another YamuxedConnection (address: " - << (current_tracked_ptr_.expired() ? "expired" : "active") + if (!current_tracked_ptr_.expired()) { + std::cout << "Already tracking another YamuxedConnection (address: active" << "), ignoring new request\n"; return; } + stopTracking(); std::cout << "\n=== HARDWARE TRACKING STARTED ===\n"; std::cout << "YamuxedConnection address: " << ptr.get() << "\n"; std::cout << "shared_ptr use_count: " << ptr.use_count() << "\n"; @@ -198,14 +223,7 @@ void HardwareSharedPtrTracker::stopTracking() { void trackNextYamuxedConnection(std::shared_ptr ptr) { auto& tracker = HardwareSharedPtrTracker::getInstance(); - - tracker.checkAndSwitchIfNeeded(); - - if (!tracker.isTracking()) { - tracker.startTracking(std::move(ptr)); - } else { - std::cout << "Already tracking another YamuxedConnection, waiting for completion...\n"; - } + tracker.startTracking(std::move(ptr)); } } // namespace libp2p::connection \ No newline at end of file From 7c5b20de0d024222358c217f77d247c85f298976 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 09:30:18 +0300 Subject: [PATCH 15/21] tracker test --- test_your_hardware_tracker.cpp | 339 +++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 test_your_hardware_tracker.cpp diff --git a/test_your_hardware_tracker.cpp b/test_your_hardware_tracker.cpp new file mode 100644 index 00000000..493dc335 --- /dev/null +++ b/test_your_hardware_tracker.cpp @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Простая заглушка для YamuxedConnection для тестирования hardware tracker'а +class YamuxedConnection { +public: + YamuxedConnection(int id) : id_(id) { + std::cout << "YamuxedConnection(" << id_ << ") создан по адресу " << this << std::endl; + } + + ~YamuxedConnection() { + std::cout << "YamuxedConnection(" << id_ << ") удален с адреса " << this << std::endl; + } + + int getId() const { return id_; } + +private: + int id_; +}; + +class HardwareSharedPtrTracker { +public: + static HardwareSharedPtrTracker& getInstance() { + static HardwareSharedPtrTracker instance; + return instance; + } + + // Start tracking the reference count of a shared_ptr + void startTracking(std::shared_ptr ptr); + + // Stop current tracking + void stopTracking(); + + // Check if tracking is active + bool isTracking() const { return is_tracking_; } + + // Enable/disable tracking + void enable() { enabled_ = true; } + void disable() { enabled_ = false; } + +private: + HardwareSharedPtrTracker(); + ~HardwareSharedPtrTracker(); + + // Get the address of the reference count in a shared_ptr + void* getRefCountAddress(const std::shared_ptr& ptr); + + // Set hardware watchpoint + bool setHardwareWatchpoint(void* address); + + // Remove hardware watchpoint + bool removeHardwareWatchpoint(); + + // Signal handler for memory changes + static void signalHandler(int sig, siginfo_t* info, void* context); + + // Print stack trace + void printStackTrace(); + + // Check counter and switch to the next object if needed + void checkAndSwitchIfNeeded(); + +private: + std::atomic enabled_{false}; + std::atomic is_tracking_{false}; + std::atomic should_stop_{false}; // Flag for signal handler + + void* watched_address_{nullptr}; + int watchpoint_fd_{-1}; // Store perf_event fd + std::weak_ptr current_tracked_ptr_; + + // For debug registers + static constexpr int DR7_L0 = 1; // Local enable for DR0 + static constexpr int DR7_RW0_WRITE = (1 << 16); // Watch writes to DR0 + static constexpr int DR7_LEN0_4BYTES = (3 << 18); // 4-byte length for DR0 + + static HardwareSharedPtrTracker* instance_; + struct sigaction old_sigtrap_action_; +}; + +// Global function for setting in yamux.cpp +void trackNextYamuxedConnection(std::shared_ptr ptr); + +// Macros for convenience +#define YAMUX_HARDWARE_TRACK_ENABLE() \ + libp2p::connection::HardwareSharedPtrTracker::getInstance().enable() + +#define YAMUX_HARDWARE_TRACK_DISABLE() \ + libp2p::connection::HardwareSharedPtrTracker::getInstance().disable() + +#define YAMUX_HARDWARE_TRACK_SHARED_PTR(ptr) \ + libp2p::connection::trackNextYamuxedConnection(ptr) + + +HardwareSharedPtrTracker* HardwareSharedPtrTracker::instance_ = nullptr; + +HardwareSharedPtrTracker::HardwareSharedPtrTracker() { + instance_ = this; + + struct sigaction sa; + sa.sa_sigaction = signalHandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + if (sigaction(SIGTRAP, &sa, &old_sigtrap_action_) == -1) { + std::cerr << "Failed to install SIGTRAP handler\n"; + } + + std::cout << "HardwareSharedPtrTracker initialized\n"; +} + +HardwareSharedPtrTracker::~HardwareSharedPtrTracker() { + stopTracking(); + sigaction(SIGTRAP, &old_sigtrap_action_, nullptr); + instance_ = nullptr; +} + +void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr& ptr) { + struct shared_ptr_internal { + void* ptr; + void* control_block; + }; + + auto* internal = reinterpret_cast(&ptr); + void* control_block = internal->control_block; + + if (!control_block) { + return nullptr; + } + + void* ref_count_addr = control_block; + + std::cout << "Control block address: " << control_block << "\n"; + std::cout << "Reference count address: " << ref_count_addr << "\n"; + std::cout << "Current use_count: " << ptr.use_count() << "\n"; + + return ref_count_addr; +} + +bool HardwareSharedPtrTracker::setHardwareWatchpoint(void* address) { + struct perf_event_attr pe; + memset(&pe, 0, sizeof(pe)); + + pe.type = PERF_TYPE_BREAKPOINT; + pe.size = sizeof(pe); + pe.config = 0; + pe.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; + pe.bp_addr = reinterpret_cast(address); + pe.bp_len = sizeof(long); + pe.disabled = 0; + pe.exclude_kernel = 1; + pe.exclude_hv = 1; + + int fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); + if (fd == -1) { + perror("perf_event_open for hardware watchpoint failed"); + return false; + } + + watchpoint_fd_ = fd; + + std::cout << "Hardware watchpoint set on address " << address + << " (fd=" << fd << ")\n"; + + return true; +} + +bool HardwareSharedPtrTracker::removeHardwareWatchpoint() { + if (watchpoint_fd_ != -1) { + close(watchpoint_fd_); + watchpoint_fd_ = -1; + std::cout << "Hardware watchpoint removed\n"; + return true; + } + return false; +} + +void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* context) { + if (!instance_ || sig != SIGTRAP) { + return; + } + + // printStackTrace(); + + static int call_number = 0; + call_number++; + + const char msg[] = "\n=== HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED ===\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); + + char call_msg[100]; + int len = snprintf(call_msg, sizeof(call_msg), "Call #%d - Address: %p\n", call_number, info->si_addr); + write(STDOUT_FILENO, call_msg, len); + + const int max_frames = 15; + void* buffer[max_frames]; + + const char stack_msg[] = "Stack trace (exact location of reference count change):\n"; + write(STDOUT_FILENO, stack_msg, sizeof(stack_msg) - 1); + + int nframes = backtrace(buffer, max_frames); + + backtrace_symbols_fd(buffer, nframes, STDOUT_FILENO); + + const char end_msg[] = "================================================\n\n"; + write(STDOUT_FILENO, end_msg, sizeof(end_msg) - 1); + + //instance_->signal_count_.fetch_add(1, std::memory_order_relaxed); +} + +void HardwareSharedPtrTracker::printStackTrace() { + const int max_frames = 7; + void* buffer[max_frames]; + + int nframes = backtrace(buffer, max_frames); + char** symbols = backtrace_symbols(buffer, nframes); + + std::cout << "Stack trace (reference count change):\n"; + + for (int i = 0; i < nframes; ++i) { + std::cout << " [" << i << "] " << (symbols ? symbols[i] : "???") << "\n"; + } + + if (symbols) { + free(symbols); + } +} + +void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() { + if (should_stop_.exchange(false)) { + std::cout << "\n=== HARDWARE BREAKPOINT TRIGGERED ===\n"; + printStackTrace(); + + if (auto ptr = current_tracked_ptr_.lock()) { + long count = ptr.use_count(); + std::cout << "Current use_count: " << count << "\n"; + + if (count <= 1) { + std::cout << "Object will be deleted soon (use_count=" << count << ")\n"; + std::cout << "Stopping hardware tracking\n"; + stopTracking(); + } + } else { + std::cout << "Tracked object already deleted\n"; + std::cout << "Stopping hardware tracking\n"; + stopTracking(); + } + + std::cout << "====================================\n\n"; + } +} + +void HardwareSharedPtrTracker::startTracking(std::shared_ptr ptr) { + if (!enabled_) { + return; + } + + if (!current_tracked_ptr_.expired()) { + std::cout << "Already tracking another YamuxedConnection (address: active" + << "), ignoring new request\n"; + return; + } + + stopTracking(); + std::cout << "\n=== HARDWARE TRACKING STARTED ===\n"; + std::cout << "YamuxedConnection address: " << ptr.get() << "\n"; + std::cout << "shared_ptr use_count: " << ptr.use_count() << "\n"; + + void* ref_count_addr = getRefCountAddress(ptr); + if (!ref_count_addr) { + std::cerr << "Failed to get reference count address\n"; + return; + } + + if (!setHardwareWatchpoint(ref_count_addr)) { + std::cerr << "Failed to set hardware watchpoint\n"; + return; + } + + watched_address_ = ref_count_addr; + current_tracked_ptr_ = ptr; + is_tracking_ = true; + should_stop_ = false; + + std::cout << "Hardware tracking activated\n"; + std::cout << "=================================\n\n"; +} + +void HardwareSharedPtrTracker::stopTracking() { + if (!is_tracking_) { + return; + } + + std::cout << "\n=== HARDWARE TRACKING STOPPED ===\n"; + + removeHardwareWatchpoint(); + + watched_address_ = nullptr; + current_tracked_ptr_.reset(); + is_tracking_ = false; + should_stop_ = false; + + std::cout << "Hardware tracking stopped\n"; + std::cout << "=================================\n\n"; +} + +void trackNextYamuxedConnection(std::shared_ptr ptr) { + auto& tracker = HardwareSharedPtrTracker::getInstance(); + tracker.startTracking(std::move(ptr)); +} + + +int main() { + auto& tracker = HardwareSharedPtrTracker::getInstance(); + tracker.enable(); + + std::shared_ptr ptr1 = std::make_shared(1); + trackNextYamuxedConnection(ptr1); + + std::shared_ptr ptr2 = ptr1; + ptr2.reset(); + ptr1.reset(); + + std::shared_ptr ptr = std::make_shared(10); + trackNextYamuxedConnection(ptr); + ptr.reset(); + return 0; +} \ No newline at end of file From e2e32c56e22028fa3111a3b412c6ba61f0904fa7 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 11:27:19 +0300 Subject: [PATCH 16/21] hw tracker --- CMakeLists.txt | 2 + .../libp2p/muxer/yamux/hardware_tracker.hpp | 4 +- src/muxer/yamux/hardware_tracker.cpp | 86 ++++++++++++++----- src/muxer/yamux/yamux.cpp | 6 -- 4 files changed, 67 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3500ff4c..5f7129d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(AppleClang|Clang|GNU)$") add_flag(-Werror-non-virtual-dtor) # warn the user if a class with virtual functions has a non-virtual destructor. This helps catch hard to track down memory errors add_flag(-Werror-sign-compare) # warn the user if they compare a signed and unsigned numbers add_flag(-Werror-reorder) # field '$1' will be initialized after field '$2' + + add_link_options(-rdynamic) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # using Visual Studio C++ # TODO(warchant): add flags https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#msvc diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp index a7f22f4e..5653c93d 100644 --- a/include/libp2p/muxer/yamux/hardware_tracker.hpp +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -23,7 +23,7 @@ class HardwareSharedPtrTracker { } // Start tracking the reference count of a shared_ptr - void startTracking(std::shared_ptr ptr); + void startTracking(const std::shared_ptr& ptr); // Stop current tracking void stopTracking(); @@ -76,7 +76,7 @@ class HardwareSharedPtrTracker { }; // Global function for setting in yamux.cpp -void trackNextYamuxedConnection(std::shared_ptr ptr); +void trackNextYamuxedConnection(const std::shared_ptr& ptr); // Macros for convenience #define YAMUX_HARDWARE_TRACK_ENABLE() \ diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index c8be45a3..c64e90de 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace libp2p::connection { @@ -45,11 +46,12 @@ void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr(address); - pe.bp_len = sizeof(long); - pe.disabled = 0; + pe.bp_len = HW_BREAKPOINT_LEN_4; // 4 байта для int + pe.disabled = 0; // Включен сразу pe.exclude_kernel = 1; pe.exclude_hv = 1; + pe.exclude_user = 0; // Отслеживаем user space + pe.sample_period = 1; // Генерировать событие на каждое изменение + pe.wakeup_events = 1; // Пробуждать на каждое событие + + std::cout << "🔧 Настройка hardware watchpoint:\n"; + std::cout << " Адрес: " << address << "\n"; + std::cout << " bp_addr: 0x" << std::hex << pe.bp_addr << std::dec << "\n"; + std::cout << " bp_len: " << pe.bp_len << "\n"; + std::cout << " bp_type: " << pe.bp_type << " (только запись)\n"; int fd = syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); if (fd == -1) { - perror("perf_event_open for hardware watchpoint failed"); + perror("❌ perf_event_open неудачен"); + std::cout << " Ошибка: " << strerror(errno) << "\n"; + std::cout << " Код ошибки: " << errno << "\n"; return false; } + // Настраиваем доставку сигнала + struct f_owner_ex owner; + owner.type = F_OWNER_TID; + owner.pid = syscall(SYS_gettid); + + if (fcntl(fd, F_SETOWN_EX, &owner) == -1) { + perror("⚠️ fcntl F_SETOWN_EX failed"); + } + + if (fcntl(fd, F_SETFL, O_ASYNC) == -1) { + perror("⚠️ fcntl F_SETFL failed"); + } + + if (fcntl(fd, F_SETSIG, SIGTRAP) == -1) { + perror("⚠️ fcntl F_SETSIG failed"); + } + watchpoint_fd_ = fd; - std::cout << "Hardware watchpoint set on address " << address + std::cout << "✅ Hardware watchpoint установлен на адрес " << address << " (fd=" << fd << ")\n"; return true; @@ -96,33 +126,43 @@ void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* con if (!instance_ || sig != SIGTRAP) { return; } - - // printStackTrace(); static int call_number = 0; call_number++; - const char msg[] = "\n=== HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED ===\n"; + const char msg[] = "\n🚨 === HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED === 🚨\n"; write(STDOUT_FILENO, msg, sizeof(msg) - 1); - char call_msg[100]; - int len = snprintf(call_msg, sizeof(call_msg), "Call #%d - Address: %p\n", call_number, info->si_addr); + char call_msg[200]; + int len = snprintf(call_msg, sizeof(call_msg), "📍 Изменение #%d - Адрес: %p\n", call_number, info->si_addr); write(STDOUT_FILENO, call_msg, len); - const int max_frames = 15; - void* buffer[max_frames]; - - const char stack_msg[] = "Stack trace (exact location of reference count change):\n"; + const char stack_msg[] = "📚 Стек трассировки (точное место изменения счетчика ссылок):\n"; write(STDOUT_FILENO, stack_msg, sizeof(stack_msg) - 1); + // Получаем стек трассировки + const int max_frames = 7; + void* buffer[max_frames]; int nframes = backtrace(buffer, max_frames); - backtrace_symbols_fd(buffer, nframes, STDOUT_FILENO); + // Используем backtrace_symbols для получения символов + char** symbols = backtrace_symbols(buffer, nframes); - const char end_msg[] = "================================================\n\n"; - write(STDOUT_FILENO, end_msg, sizeof(end_msg) - 1); + if (symbols) { + for (int i = 0; i < nframes; ++i) { + char frame_msg[500]; + int frame_len = snprintf(frame_msg, sizeof(frame_msg), + " [%2d] %s\n", i, symbols[i]); + write(STDOUT_FILENO, frame_msg, frame_len); + } + free(symbols); + } else { + // Fallback - используем backtrace_symbols_fd если symbols == NULL + backtrace_symbols_fd(buffer, nframes, STDOUT_FILENO); + } - //instance_->signal_count_.fetch_add(1, std::memory_order_relaxed); + const char end_msg[] = "🔚 ============================================== 🔚\n\n"; + write(STDOUT_FILENO, end_msg, sizeof(end_msg) - 1); } void HardwareSharedPtrTracker::printStackTrace() { @@ -167,7 +207,7 @@ void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() { } } -void HardwareSharedPtrTracker::startTracking(std::shared_ptr ptr) { +void HardwareSharedPtrTracker::startTracking(const std::shared_ptr& ptr) { if (!enabled_) { return; } @@ -221,9 +261,9 @@ void HardwareSharedPtrTracker::stopTracking() { std::cout << "=================================\n\n"; } -void trackNextYamuxedConnection(std::shared_ptr ptr) { +void trackNextYamuxedConnection(const std::shared_ptr& ptr) { auto& tracker = HardwareSharedPtrTracker::getInstance(); - tracker.startTracking(std::move(ptr)); -} + tracker.startTracking(ptr); +} } // namespace libp2p::connection \ No newline at end of file diff --git a/src/muxer/yamux/yamux.cpp b/src/muxer/yamux/yamux.cpp index 44e82ec5..1892b11a 100644 --- a/src/muxer/yamux/yamux.cpp +++ b/src/muxer/yamux/yamux.cpp @@ -8,10 +8,7 @@ #include #include - -#ifdef YAMUX_HARDWARE_TRACKING #include -#endif namespace libp2p::muxer { Yamux::Yamux(MuxedConnectionConfig config, @@ -50,10 +47,7 @@ namespace libp2p::muxer { auto yamux_connection = std::make_shared( std::move(conn), scheduler_, close_cb_, config_); - -#ifdef YAMUX_HARDWARE_TRACKING connection::trackNextYamuxedConnection(yamux_connection); -#endif cb(yamux_connection); } From 1679f63e0e1d116ebe52b433ac33b9c992dbca37 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 12:07:33 +0300 Subject: [PATCH 17/21] hw tracker fix --- include/libp2p/muxer/yamux/hardware_tracker.hpp | 5 ++++- src/muxer/yamux/hardware_tracker.cpp | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp index 5653c93d..8e90588a 100644 --- a/include/libp2p/muxer/yamux/hardware_tracker.hpp +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -76,7 +76,10 @@ class HardwareSharedPtrTracker { }; // Global function for setting in yamux.cpp -void trackNextYamuxedConnection(const std::shared_ptr& ptr); +inline void trackNextYamuxedConnection(const std::shared_ptr& ptr) { + auto& tracker = HardwareSharedPtrTracker::getInstance(); + tracker.startTracking(ptr); +} // Macros for convenience #define YAMUX_HARDWARE_TRACK_ENABLE() \ diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index c64e90de..21109889 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -261,9 +261,4 @@ void HardwareSharedPtrTracker::stopTracking() { std::cout << "=================================\n\n"; } -void trackNextYamuxedConnection(const std::shared_ptr& ptr) { - auto& tracker = HardwareSharedPtrTracker::getInstance(); - tracker.startTracking(ptr); -} - } // namespace libp2p::connection \ No newline at end of file From cbf8697eb2a606128ce9c63c286230acf7115c4a Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 12:24:52 +0300 Subject: [PATCH 18/21] Revert "hw tracker fix" This reverts commit 1679f63e0e1d116ebe52b433ac33b9c992dbca37. --- include/libp2p/muxer/yamux/hardware_tracker.hpp | 5 +---- src/muxer/yamux/hardware_tracker.cpp | 5 +++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/libp2p/muxer/yamux/hardware_tracker.hpp b/include/libp2p/muxer/yamux/hardware_tracker.hpp index 8e90588a..5653c93d 100644 --- a/include/libp2p/muxer/yamux/hardware_tracker.hpp +++ b/include/libp2p/muxer/yamux/hardware_tracker.hpp @@ -76,10 +76,7 @@ class HardwareSharedPtrTracker { }; // Global function for setting in yamux.cpp -inline void trackNextYamuxedConnection(const std::shared_ptr& ptr) { - auto& tracker = HardwareSharedPtrTracker::getInstance(); - tracker.startTracking(ptr); -} +void trackNextYamuxedConnection(const std::shared_ptr& ptr); // Macros for convenience #define YAMUX_HARDWARE_TRACK_ENABLE() \ diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index 21109889..c64e90de 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -261,4 +261,9 @@ void HardwareSharedPtrTracker::stopTracking() { std::cout << "=================================\n\n"; } +void trackNextYamuxedConnection(const std::shared_ptr& ptr) { + auto& tracker = HardwareSharedPtrTracker::getInstance(); + tracker.startTracking(ptr); +} + } // namespace libp2p::connection \ No newline at end of file From 7b1e8a5541e00b21c374cf1af17b8f3458803a7b Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 12:25:15 +0300 Subject: [PATCH 19/21] fix --- src/muxer/yamux/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/muxer/yamux/CMakeLists.txt b/src/muxer/yamux/CMakeLists.txt index 0b3ec6fd..9ea71d1b 100644 --- a/src/muxer/yamux/CMakeLists.txt +++ b/src/muxer/yamux/CMakeLists.txt @@ -16,6 +16,7 @@ libp2p_add_library(p2p_yamuxed_connection yamux_frame.cpp yamux_stream.cpp yamux_reading_state.cpp + hardware_tracker.cpp ) target_link_libraries(p2p_yamuxed_connection Boost::boost From 4b267bcdf0f3bd41af95a8761353874f39a9731e Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 12:40:46 +0300 Subject: [PATCH 20/21] fix --- src/muxer/yamux/hardware_tracker.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/muxer/yamux/hardware_tracker.cpp b/src/muxer/yamux/hardware_tracker.cpp index c64e90de..a512e29b 100644 --- a/src/muxer/yamux/hardware_tracker.cpp +++ b/src/muxer/yamux/hardware_tracker.cpp @@ -7,6 +7,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include namespace libp2p::connection { From a9ba1cb1e6465c3c1a0850ca7ad120f7bb54f813 Mon Sep 17 00:00:00 2001 From: iceseer Date: Tue, 10 Jun 2025 13:07:39 +0300 Subject: [PATCH 21/21] enable --- src/muxer/yamux/yamux.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/muxer/yamux/yamux.cpp b/src/muxer/yamux/yamux.cpp index 1892b11a..169f0bd5 100644 --- a/src/muxer/yamux/yamux.cpp +++ b/src/muxer/yamux/yamux.cpp @@ -15,6 +15,7 @@ namespace libp2p::muxer { std::shared_ptr scheduler, std::shared_ptr cmgr) : config_{config}, scheduler_{std::move(scheduler)} { + connection::HardwareSharedPtrTracker::getInstance().enable(); assert(scheduler_); if (cmgr) { std::weak_ptr w(cmgr);

?S4`% zj?Q_+&)C1G`EJWwx$aMw{-Hugfn!O@ShiOhAAJckJI3j zrNfAd;{df!)- zFVXm1qCZ(<+ZpZPuIgZmuLI3o73z7mej_sf(Y z@s{v<8>i;)V*hL)J)cxQI9|KzeVMlp?&BH_Z=UPb;S&Dm1)P1#KlqRk=PCc!{}ub- zJkO0sh2N?XoT&DF{vrG!%8~hW7jSM;KG>iCrSd6X6hoWNZ9b52?E6YfHJrK12j|tR z|0(txR*0c3hYOAg-$Co6&97t1cc&bgk1fv|{!i@Z?04z-zQhs7HGEAUTfe5(3tyrB z{6}(`^Mvwqz9qyoebO!}w)S%_PdPfHR01@&Y3%8yol%Nikam48I}V841hyzvkA zJ)(|k|4+3K_Uj&NEB8G@|HypoxcQv}~o z{=%4ix8Z!Ioy2pnuG96#jqP8a(r z-wDFQd-j6c*SgP-{S%3Htys;0C*Y+size;X6UGLld(_+8kHX&@i z{!itD>AdYivHx13*xT~?vhu-ouEiILeQ^Kk8_EawliZRa&y}wJ)0V3j;LUSwS|Ine zX?wvX!oRQe#rn_p;mv;U;C|P(pAq|#yEY z{)4{>Z~c4@6W}I2gYQ+%h3|+TTe(^Tmdl(w)PC0nA#6JL?jhl{j|iWUCb&uYE7cF% z`0Tn=?5nhYrPa@=xJ>xn+8>_VR>E0pc^w~R3+?p#yx4Cj7UCl1mn&a8T!^8{?}oQ! zMkyEmsP@72h1E>>oAf#U4Y4-Aace$b=p}rxz59Xk!Tlk(UM}{*dD>qnADn;wYo^#= z@_o6Vjq~U%;s1KQ@Na8;<|rSWPy0l+*pJ*S_O=`rEC14Wgtz;&-|Q{+!S|Tn%n|;M z17d%PfHS3!@WJ=0<|)6wTntC6eVe{wzh50~RQX}bKd1dPJ6?FCpV+U~ahY~sIAB%y z;C|hC${)N%0=DhWPnF-T?fBJt-*W~^I8VPX#QDmXD&Ixh_k86qyF%=P@6D}J-kvXT zsoI}4NbH0CoD$`O`|DOKe?a?_T6~=Y$}iq70guw~M}JYmpRehu)xfz=`QUpo9j;7X z{yz(E%K2M;B;YGF{Hv7@z6WvbRbroWSPX5xJfwVZAM6h0A63U=(|Pz{3Fl=UM_51b z?IFSk-v{}P^1*#XV}^?T{evVvww#wLAKbURLiynPO=k>~aDw~rW6B5D3x275a9*PA za0w?kKai<>us>g`{LvhV|5gF#QRSy-{#yU`Kk&vs+kU2+JAYLB;JU;65s6PXb%eIR zJ#d8Z`RdQF(ttj3b@FmD0N#|7;C|yDDTr%j@{^aJ zp717proArq+6{FcSAN$^!rS?}v#u5U;QL&Q;oW|3U1B*|r}jZV@C)UG?;)N)Ny1M* zm>8c2;7$0uzAfR~{%6{CV!u-Bsco0ffH&g{doD_;1n10E``~zCzw%2p;cYpYH(A2p ztnKXS8qRU$x2pfN;KY=GNuXtf#$nSpAzK{R*IqZw+}17O$)5$_rNEM z&%0_L9ADg8B=^1duM)m}-s_5mf89yUm)|NMT(^CtMC_+6lyGePbEgX*Tt8X>Z{A}{ z*NKOYnhrmJPZs~@HJl%4`rGGCn<3!`_sRTH`QUqtrp%A?e{hKK+H5;l zm5F_DAM*bx-%k7Cw*S`iX0h*FE8#pV;PfpQJ~(bFRz5}hrSbBq{K20{0GDYvJt`!e zoH`+FzjuZ5_PnUcYM)Ul_NTofM3M4$D}UD?h0yM%^Ec%OtHbD~_Oq%aobEdRVEy5r zm48(0`*O7}zD4YV?RZwT@Ke;UPE`9kse6i)TLiyc+@z?(;|MFA` zXM~17nuQhP5A8Wqn%vG$;f>!IukDU~uC}v<555obyz-l)5^#o852yXDVjuLA_bMMe zr=sf|vG1hyWvs??k@8(Ng4TcjL;2u5z=*lY>&p%BZo993&!*dh%3r1qa!IP(_`-Q& zA3TTQ%gPV>x!4tGJU85y{Jz`a&3&KN_E)>_&c*YE@2q~$mh<(>FT70xwsn8=?P4Fh zQ+S(?Pv0T@#;wBJe#?7z3LhMIkE<0vcrL`V%D?pc#QPS1S?qWJRCqfN^WXyEgMRoo z$}ip~_L%}s-@C+q%0MALt$aCrhW_n`#cJQ~Tf&Z3@r{Ma)4BauH2gq4nx*_YP5-ks zoL%sy|FAO9f4E|igcIB+eG@x$m*?dpZ4=KM< z8&X@I&3n1V{>{KR-#skh2hVehen;b}>D)`h`4xPI{_Tf9s(rA2UA;=enf#Pk&(({%KO+364+(L% z@{cGVoG0wKTI@ghycnu`a_W>1o*VG0^1*X0uJ{iLC)kf&v_|;g`E?V&D}41Hxv#B{ zo8e9SRZISukL?$|s`i_;f2-BNIjVec9w6&`5`M)R34e@$^A+WHED*xB`%Bk~{bx1c zA!`4G^1<@&JSO(@el3Q1YCq+1;e-2IV#=@8biP#WA65R6twMZV`NiLta0dUk5VpKs zwNCiVuL%FW6v6e%2m7mkQNBZ^*zFT=M*l#<3GRnk{)F(s{U|ZO-;1B}W8s72=qon~A6!>*VkI@P=-k4Yv*tw0 zOA2qU=~Yx!LWEqW&jE)#TWK1MFa`<>BI{dn^L&oF|bD~%0jT<^7FFJ0-hzXH` zXu*)7d6B3Soji6zEGsiQvaqH!RyeJ^B-ebcDJ`rnDUMdfs&mKoEiao^m0gvUSyWk3 zQBo8utE|ZCcb&O$N%62a6^Ts9iB2fY<=+S)_K!x3OJap(cET@#a>Lq=nS^cA9DvP7lg%vYOqDCpJm_b;5quH6!;U&`xXO+i9EOu2Z zaT4p3~T9*5NBoY~x9T_)aWON+y zHuuqFh*neM{flQ&<}t}FpAhTg z{+XLsj{hjn%FHy*p^sZ5M%zu9UpL zKyXR>3#P9ieFkD_oT7Ca(b(Lo661(XZ^62o0ns59bECzDvBCi;g+)arH8r{UB>Vtl zjnAH58HtQ9h&E_r`}+DSZtI^*iZp1^POungKPHl8e7x;jNH1p;1+cHlfcy#lqQk4k z*-VsuEZo>f>~Y~n?iELl359@Y2>S+*+^aMRi4rob1Gk5c*LH>oIr zH&2_B*wtvzYiMp?RQhKz?QUoARQdV#If2Wm#gEfO_V#q?3iV$tcQ{iXjvNgGN@n?0V|5U(au;3mX+&!CT( zH!~{|+7WB2KiLvb)IZ>f%y%3RK<%U;(tC}~swyvu;(ul`ddZzsV6G6)SdbYl$igzm zRB7YDM+J*BnI9icNqzfJYBR$n23ZO9*{#Nb%0*6?*f4gW6R&;u6KhT;^odeQ6Gn78 zg6m^kcbG#C^T)1R!eOX0G|tsNj0` zuR^tfj+bd3tEH_`b`H5*jrTLnM|ojQEINxniYm*C?Spu=Br`h1OjnpWf)B&ZnI45H znMr)A@z)J(5$s@ssV1_nB5QqpU&-WU_kGVE(}rCDXdw@o94>7J`M0&aXQo z=FSDi=fzIGvr12{;Vf1koraWx{-HQ1JR(i)?8qq7Uyku~bY0z+*!sd);f!2*KxTX( zuCh7JavyirX267^(vsp?N7OfqxdN`_GVY>VXi*@k1If14RtZCtCoX6|FUpg`I2jj*T9D!REORuj>=E-xz^ z^vM6MJC-Nhp>(I;Z3lm}x@iAwQ~y|{8KCy*KeUfokMIVvO$_#udHbYGQg#8MkzNw< z8^^4YdIsN(XBJk)XV3kS#zi*Oi)+q0LA(doFVKTC-|4{tX7VCo*2^6b`R3<_V-vAc ziR0+hnx~*+p`)@BbW9OuXz8ZNyrkdjHS|CyHja$X&Qw*oPM!qKk}>MExh!kukDfhq z=HOwICJhmLZIaMGOu+@ z(MNxB)ega%u3oKN{dNAKrM*Jy*qWHR|2Ju*6PE%=V}D^aUy}@bn=JkK2;-9QuKwOp z!UWO3+mgTAK-bi;MrtM`M>3)1uKNduu%UYa@VAlK%o&W2cZ5H#3CT!gLQ!QEE6rvB z#8-JgrUlEJhW}TrG%(9HCd#}LgQfBkMh&JB^DQz-Z>FUljVyKRLA11tjT`v4{GxI3 z)~&^XnTf*c5_gY^%p9@$n?Jf}ruK&W&Sq)P-BxgdzDH-dh_t&ZB_mdE1*Yj0e5!KJ zyprllJJ9s{=Sk+8T7NYzJKG)Wx&v*N*4%33?!Yihab%!75|75%hj1&i&&APO*|=hK zJ6+z=IX$m{hKz6%hqyXMF_qh${EjfpPBv1ti+SY3L^nrIa*aW=wOOsJ?PMi1R1Kzm z=pvKSzP&9ite{Eyea)E4=o8JISyfJ=YYhs{_kE1o-0UpUp9$oeXbl^9SXPsPaU`D- zM@!qFq#5tkXs@cd`EHiy3yX{6o0^)=_@-w1PaxwNj-A|2xz<|QG}C-6QAKoH+<3mw zYS{g13H=zGz^6tp^lY28HKY%lBiVK~K0a*5AKK|tTu*!^p~0+Z<7-E_!Erh|olsfM zRFdpfn=~ofyH}31@*y{B!Y4LA?x!Z6` z=ESETKb*b=zC54ooyi7`!Wb*-6s;HLvja%TB|o zqmxXg)+;|cd2PD8vZn6tmN5OET*ilP`LgQVs8S}Zrru5{bagQ#+$kx z)r>)X8-cuM4Gw?Yk#9v|MP*HSNl8_bcN4OEmsFTHwQP*1S69wto}jEI-pNdeaFU7{ zai@>m357zL3w77f%}YqeNub)W-Pap(8*lHmE75|+(Ts}i@>0UMgL{8mCZhWkvAaq} zrUet4v!5a%QyWflG{f0SMtLQ#neFz8Wr(i%BD9hx9>%b*VXv(l|wL5#FC$!N8im1ozQfA#!`=bQST01I$0teJ24L>>6rL zt!*&gZ$>@kO*U^|H@(q*ANRMV+zCW^V=6kUqU@GgGFu**Ia6j36J{ptd%GX=H_Y6b zqmjChz-VL!uW_@zB9UMBbPv8&P@Ny}YC%V%8yT8TVe*IpGbw^kpf*{QJ?_2H{R&xHH!3LW83a zGZ_}P3qq2v>BW==b-fvF-|$S+UCbTFi^Iib6=v0_xVg7$$~86P?(|R_>^~09{`^0E ztIi+4gcs@PpCmt|f|nq*sQ2?;g)c3vC}vA`D|a3nKV!kv65iN|M$8tRvWnT2H?v&A zsK9#}5Q}m8c7*9~M&nD~@zx_@43uPG+xS4$9a-y~*T=MT%fbbYu(E0{{}hw{ZY7s- zplm>xU06QLclZezWE-TWCM%mgB(U348`+d=SJQMCswv!2-&P2B&%|thr-dSJmK*Fj zEOv0&zytXXTIv5`4WZngm+UB}cza!yhHD@vI+E zMnK+v6q|g}BC;bPGkRsYOOvNY{3rW{6HUz+8p6tI^X{EgR~Dm_RM)F@oyr~am~?O1 z3?4zsZZdhxk28ki1?yw#C*2OZjyPqvN>tu9Yiz`+?QF7PQ$t7OdI{M&?)MU*@0Ok9 z2&VO>>~+0VosXHjZ1L-*CZYTfOZ7Qf*K<#H%S>yH*CLT|W8HbPXp~b(+#^5C zi*WMl|F{Wx?!txtNs^z7VS3w~8WxND>;85#U$c8Q@zn~Fo1G=@_05@_w|yRtFLIAG z$PHhzW*{zaX1I$o@%j0d?lWxAhbG1}g7JNhGt3zxCB7nDKMa_tfZ*q)-w0iZq}-+XBEZ7hl#WC zuPD-@xbM8$Q{YZ`upEE+C&H`vS=9A@4PM3P*snryxAZMyMWw!Xff{kKP2`JNi12nZ z|LYzw$@2xApA5Zy$4rnl$=Z;F2TU^fi7-{o4wkUjFW8_I-%)i!=XHdh44!MN$Q|Fj!8UV(a>Pz!=3`s=07N^1M>+QSwvWpDlnKjh_88NT z!bS?S<;*)3Qk#t?CdD+X8Z8|h+}D~*jP3z|?p%;MbN;T1mQ1T;zg&40lTvwQnR-@$ zIlhzbhr4e=jums8hUsM$oN_s@B)B)iG-)QRnT0pUH%D-EK_5bhmDv%EHy&^1^7lzP zrPk_-s(X#_hz*W?s&TihIke!+ZYN2VkLe)J>-#2cPn)P3X6r%=SEiCpK{eTG`;Pui zzGXZigoYi?Cgwc7_nRlgN^S{1J=HxxBkX7t_cRUn)HCl@`Npd)X-~_~X(2O9W){tC zu#L%daX!8)FV!XN_7sO?Mj|a4&xK9ZBs*Tg-392K#@LL~m84hMMDb$rHaqIBJi1xx zP1zSj^O(=)P-*eb?Q42dwLxXnI78 z*2N^d77{{lX^JN7aBfiSiUPZRisJiLS{@I(`J!NAb7oc&9x6$aHDkTh4#yL=ztd^^ zH{AZ7>27V6&Rjv19qKiWd6?#@mL%W ztUrw%-RL`u#yvKbqe(JB-Xw{?#Q1UkwFbB1w$9NFk+FT{t#R?C?x-R@L0K}VsHDmq z`rcsPsga||B9Rj~hm2N+SA^t+Y4bW!$S}*kkwbe*acy+0*2+UQnJ*lm`}6;uc0zdl z1Evs@o-0g+Yhp)4(>qw28X`2qMap!z|5pi`@)IXH;B2jxp2WB2X&b$f^Z&nQEKO1J zPgc%s=4@qBf1YHa&p+?n!i8C>fAJ$0{$DOxn5eKhM-Qh+=(p+Kv47J8rju`Iw>v~m zy?)T#*AE)qgw3{ugdtPHh6KOsXl5V(Bz<5jkGOn`uW=_Bf5oo#7sk9ja1BNa&FR-S za6!#zrR>OodfoIov2kd2fY{P;y=-aW;38%!XT(bF*_bUK*_-2q+*NQrrrOT$O36v^ zPpzLrdWv|%rAyO4j~5Xhs#(7S@NZVw8yO*==pe@1>_P!%W2fvQlOkY#jH$Ak9ofP0 zlk zef-BY1NOF8K$p6!~LK^H;Xv__Sts9PIaQ1+lgxIxJJhL4c-(qW!R+pM{uu~uR-2h5=x&th8a)ic@0 z#LFGNMx`ZZsCXv>o+|Pu{h|#HIN^sqi)Op$J~o&+F!Ng4G?AB-{D0+YjMo=S@NmZA zoyf`}%SmR-d(KDbwPm;G>01IM4`h3*8I?6?MCm#BCSw}-t-!)N`&jJK`$y1|StpXP zPSec!rxPna+9i%KNh3dkYhUrGY{7ZEO^pDWF?GoHxc*vKsEwa91$+`P$5A zgE`Vj6C0|{nowpmu@j-c&cZ9r?EdbZaAaV-kNsf{i1hWVf7L*ocZ1yXIebq^lDG0( zr{CRoLr{a(~Zvzc?dBkl z$7I_UdjZ+~+{ZmOBQjgx49-tDg{g^o8g;PTucfnA{dlp(oaMpqwAiUC)BW>~JwCxA z8UFz|`5_Y93O3PK>%$w))xKTrA5$mde|@ZJkDZXF4LhvO@ZSstc^}BPzsxx7s2;Er ztrYAjNgxz$QY;4;^mEzSMcNhDq7Omj{A{^=^jy&N# z+~A>!Y-MiQZ{VKf!a?h9*x^-NcXS%~QC)kIk=LaC|7#;7EeU;8UWib0&I2hxjL1 zCt7_m&7QR0=z9vyZ0!T@C6J5_JEzTA#7ZcOC)5DS*0tf+_Np$K-ivciIpdTaI5m~# z9pTvA=xjaBw6&J-n2+%P-duKrC2*aaZKZd|TCWhW?ZvKW$G?*+|^tk~wx; zWo!IYKwn*3i2uxhE%7ZbL-7VE`8wiT3Ae#{P*pM&Xn%-+_xN+odspUnS+e5A zhT)ibs><@RqPeW8 zvJSzofJLX>983J6v|d^L18q0YH@<|CeCY&pESKxh>2R2)JW0sjPle!l{KMK)o~l$6 zzeRfsyu!+`?m;mPWmr72_E8z$r7P^=cre%x2os+aCCk(lg&EwHw_fE=dX+K9MA-pxK zkjeIVU$Dv8czvT2uGk6pII%&d&)YRot0{KV1HFw#-W5B^HmVukF@ES@<3FQncQwhc zvEho6P8~IJ~ZDw1hes`(o}47a(?_UKQr6X(zSS9SYw1i`Snimb|=&5Hs7i* zDojt&Pc=OA{`J)pgNt9E);p78`X8vfj**{t{lMyUGjLsfXa;2oEw6Z+@D_>?r z*5Z?b8$Yng+d)Tzk?o#|(r_G4fr}s96sRT5S}SVC?29+1GTok2gQ}$C&Sn-P(~p$X z$=xone@45RYxXDE3bpb`Dd|u1vZxWuZt5h~@f^!TgY+d%V#RR>e#y7xb2g?2sXsxH zbb`Am(%()$ncox&rarxX_snGZAzZ`$Ij&oi zIj>~xdV}WL?K_gvExngE(Wl(VNwr2fX6q9}Ch5Cp^}eof=Bzn+C51N^l+?ufRnMw0 zD7kscXP@jF2c{jiTl_S|X$PCJ<*7lXi8S8e$A4ar-}-5J#lnY%Psht_ysV3w62b7E zGt$fksZ!Y-Rm3>G$jo51phBDDvvmWKd&Y!m&Fs(mt+cM%%3T(_ZSe#e%J}@*iM)ZP$yilhSj0|M^Sg#RV{VVC zE6FYANEi1&irl<%emIK%TY6NTn>YS0`iWLUGm!m=zj36$ia5j^AZj{yX2mi5ml91M z)O|&1yji=9A3CU;YfrVJC)Eviu*QoL2uuJ{%WXS4cb1v%cudm51kL1iNsjjpIspY*6vr&e_bm@6a zm#y<|k;EOe*7mT3*4*p63`qR-Be*$g+MqJ%eFW=)^Y zZ*16|3kf~QB&9g<5Kt3gZ~gs*e*)?w*bQK2!gO+3w~v*%zdcgTYA5xFM{!>e8fs=z z2bh24U_46HhceBoZp4rM_*G=P|{cnky@d>r8_!Gg0}^a3j8A)cJ6Lln3TMWLt|vL8+l&Ph+ha8=fjAfMB`@=xK^5Ts zVoj_3a#;)JYs?IfIq#pJ>nN-${Qug!me|O$v+VF3o*5vEK}66Wp~0(pQ!+HZ#e?+4EmsiM8o`JHB~oV0Ja6zdQ~`)wBo+9;%zR` z?Y-SAH0leuO5A96#8W^=Cu|1}0G%K(Kc7CA*$!#hhH+DCx9u*^;7d`Cx_@$iG0O8< zh9YU-Q6o3vf~U!o_o{VTv zv#{Bzn!RMK(g0*{3+&WvcyA&Q*rr}(gus`9d}-7k0Bce(T3dJRWgN}R&W0!XToybD zW@-LdbX2A0)Oe@ag5g%2MgO!L>Pf+eTIBO(_ka@XSW!orZljH14NHWWl#B@o-Nf%D z;0UTLY_T(G6vvVdG@_j=RbHhIWuA3PFpjdK@B~Y@tvH99-pAZww+I#@tJ&f^Ho*yM zkWq*pycqF5>G*AJXI=lScz*bqRS>^iKG1BJb8rSKkXaNfDjfnOiaKpWs#}J!Rz*`Q zV~FKuA*Nwy)$(772kZ>S0j?q40g&2s>YQFEOYR*!-xG8mm`#V1Wj-gn!6I_kX@R=h zgRobl;dqFOBc8$lK8{B9A^h1!Mrb3al_}Ax?c_?KL8hBcWL977+@pGi`2}*3dOVF1 zrKKdEN8`vLZ!YGWL!FnHyYYq<1yyDPF|ekM({iG@puil8e9-uTow;eY+B@?29H_xpD8*?)A({cK zEr^3)BNwwi@uf%$Y&aHy#3_h`b!vR_@z{=ADSLsIfeVU?aF!TOcXm{Z;cl#SuVJ8L zKOfH!h!&+$7n}x-QlyFDL_I~kluKsJ6`Pvru_$V7*;0RX__|kbN`&f9^7S&)*#CfC z6iNu03Wc-58$f7e)Fx?)?0bLmBxjuHaPoxy4( z>U@c(FQM4L3Uom`@Ds9`@my_TPfkV$7h{WQVOv#T)dh(bYGj4zZE79_X4%R|VW!uc zby_F)3b`e9>LM?>FNiR_6=YZ3f?#C^!_kX@X!}Z=RoxvK4Bb&)Bta8C949?2+VCcc zXSJodlN8w&QI0ZyOE*O|mzTV|aaVAR8Gb^GW6U@-=$kL3rI?HJoo_EKvHy+@B42h61Cn$4~H#-E%y({#&_*#JR z67gHMJfDs7?t{mR8C4u0oO_6m(W^arrNc$`cNzC*Rg2vI*xCylL`R5I6|g0Gjr2JV z9T@k_{E6JCI^ys44ukFmuTGBQMD5VUBYsVSHX4o%q^I%}k^r>cjmn7G+G|=Hn34u6 zx~X7}KZJoXov-PmDbRvZMAp|VMS1S(9?b~p=vYMg10aY4thjSHIFyeVGeS5|u8lb% z?5NmGH&hK)r7R_kV(Gc-A~p8Wix~xmhdra*6EFt8)wa?#>|8x&@TRU%n9O0KQzLfj z5<9AB7=R{X1{Ze!oh;c4Y^XC~`77NB65cn|2a$lmfz%FW? zUgvy~E6B6hDrRM(;=eyrs=LC(6sO`!`$~}!_M0j=YlSd6=xX1E9n=9>kdO6)w<@d~ zqEoF5@YzWbp5Ng!o=`Dc+cki=-46jmjx^UWHRF_NYb#;CKR}7QzG@N&iU1JVRf#rX zD8pPkz?m>eqSX4JpiH)uc*v#?J!2qNT7-D-lP1rl`pBTxCU@sexl#W~(pN}k!)jTJa@p%F9R{9}LVSY+j5dp8yon+Tx z!t1>}>OkP0-*iFkTq?{-H=^uQptO=p6Hz~#n3iW{=rv408{wjnL5!_h#?0$|QIqIp z&je;-H{rB#E#jH%=+WEI`tM|V^{kn!XsdutwBHTJE>K#4nW4~Ti?cO@qK<2Qx^Svv zhQAu83n!ToOSOj#gMx3WN6f2LeRx~#8>Bk$CZg+uU&{~UL9Rpp31)yWT!GPu?aS41 z1GCseMwb_a*xi}u4um>MZ||C9s$HyBtSFs^&t0l8i~GvXeFN(x;l|W+ z_$4UXuv#7m+;IyuBO0NUICvpm9l2PJJJ;BaV?PYbAJ~3^Zxcqy_+*d~FUp;;qSijU zg~=XNOiApik=Bc?-@*Y}MXTK*tUCBc%!YkQ)GUOX6wGZjZJ!!ivZj?z_99+u;|e&W zpjquQw9i>)hzFUg*=dD}l_|nvV}pA(IAl-{-EKi8Ky8`1#06_Nff5)IiB9jap#--0 z!MqYMFoy-x({O^d1I%!f7Y5w$>4q@`wKI%Faez{8t`3yN*;>4-f{3~tsDekO>#@1B zJRa$MiS#v55=4qelrL4&0%>IVumRFa8P!dVToKFdocnBb#xNG{QQ_T_Icidw61zWH zc8}S!TyO=ltV7o%=4JHRxKsAHbT_VqVUD0UKa==#)wUrWiRpF3%eq6)@+vDru!H}kr zy4$+t%P}V~!PS9+3bd^P&Zj6}wr$qyl6{xZFTR|$(yq(X3m>|H4wO)3FS3}K1nU4y zEX$k-Dc*vGa{*Vm*f0pzW6;C$7N9aEZ<_&7W1dmUa`)|+l>B=OcUHlS;bLY)tW`XD zHN*fEAS1Fa&Zn?B8ICPE-`2NZRtq+E@JwxP<3QeC#?)&VBh!WkLP@QjxCQ13$$Y|!pm)k6u+nrQY~j2cZ=uXHuitq@V&Hd1Y!`X~8`NtWK;!ycpV&IeLO2$;6dfUT*-p)W!t z*saM;aXRvE7@_6}Oy4J@Hin&Js4I82$w8nT6?aB=2Cp8sx^kd__NraU3i$pC7WK`( zH~T(-p}uVRm8qCW+rQBz7*7?dB?!_d$(5#&!KCj3dW1kua6j1klc=nafxZ)H{&~2% z;U?|=JEeA@RHH&@DEz-ut2K@a=_8D26gvip`@&fr;etXuHY40poY8)rV`@(fi&llx z$hXiWja>6oJGv_2uKUX=wREB?eQH<^@q;fR)>Pd%iSuWHZ4lkP{I&PPWXw|BRl1!%JX6c#Jt5!gMD(~v0X*r5Q~-hJKdsh5XH zjQ|1T{-pneNYw181C-G_6n6m2gL*qdzDBk9&|kw&ft8e*WW=0h5>SOqeysttY7LX-v7<&+emO=biu2Bt?ZA0nUN5ymS`UZ@mpwU1cVwJf~F(wu?ieA(2q+?tP3|QGa(dWym>K)jGSsJl%vj2Czq$?d|$I#w4C^s2dnv z!di$M+5-SV{e(oE6R0?yqT!bQs-q{w+uxY<-mM;2;Y%*eH3F-QnY zo9aYkXF9_iSh}n8?V`HUB;M}baew~w&BbB<1Wg3hjRzI%sM4C1SPg^rQ)F!KIhPos~HYR!vGkbb|0_cA4cj~0WGZPFhZtv?futHlU4yF*sfS)Ic{1Sja8P; zW8|M6fZ!i2vlMqE4P?U@AQj1kF6clLfwfyju)B18K6r{D7!n<>Ms4F6BZ>1i zcZ$RUQnF<+m64#jircxWCG{&&EMOJRziup^<%HyM>xv289ker6C39*;qo5j%EP+IfF|qEcTFyazz8jA^SH zG!oaz;;+3 zmx%%Jv^H#X3%=)>@L}bQ0hwj_@zhA;;f@YiB4MU`(x^ttl>5Fy0p&Qp&g5?lz%#T5 z9SsN1Q~f(^NsE=B$i2B*l@u}P^n$~SrGPld9W96A&Q1#|10o;#pMr>n)j(?t+p(7~ zqu+|$w@^b@@)ZIOTS+*UJgro9C|aVBwG;uu6p6#+35TW~pcy%Hb%J=EgO`g3TPhXdFYqF#_Hoh|1YwW5BVb`J&v4i&pZrKpq7 zju#6D;bD8IO~;y4<@M7}u=;_D!9VxupEb)lxs96enW@;iqt(1j!pjCjMV>Q&LWPwL zun3zz8S3e>>8WlncRF5T8Gd3H*lq9aXqza!5u7+uAUwNzUpR&|)M}AqJj&k10^F1I zcU(X^58`d;l(c8LnFVc}4Z1D>!EdJMk#r||+!sJUv=VnB21Z0zcU)ew2K7OW)}-Eh zS7_-Xh>V3F$QdE9MZ&dAIwJV|u%(7eMV_7etVJL&CfK&J2@rE1q9X6X%u9?4b6m5Qco}X^@ah&isTNoKbR_y z)sFs3%s-mfjy)znNok>K8Y|ZQ4EL|1S3v&R1T^qFEvhiPLN&QU1&mUG*cG^?Lwz67 zQ8u|gvWX;9AyWcua>2FS%!wH^9>nXHe_$|;TYCTlg{&2taqfT4WEx)HfcVUGb1bk& zm<;0;C%O0W=*#CaiM7r2te2H=67>8CNfbectUnm!i-jp`aip6cAYGX}P&FGMkeDsy zkuS$&!fFO?#U((kJ2-?*)2*SkD_{2t$d31nBKHfR)~o|*tu>W0 z_pk~`YfdhvPc>xjBF-iiF#jkp?L@GsRZ^^cvXc=u59vU58I}ai(oZs7p5=4me4_oP zKus&-XOb!K1f`oAfYp%X)k7#C{WWy_`S^+Dvlz#O`dTpaEeB^lk_kq~`dkPW@pm`mRRAUeB*~5sY6W-J)Tg)OYRY&72~01$I|Wx3fUXY=YUonL0E3eakmedX zkejG!RmshPqE`06xsq+Vp+V+-Rei{=8wt!by&=o&ik&t?Sxa*LhEAB9T|=g61!cH; zD;VwWJtR+EsYqk6B80-xBp3q@1Fh=2RrW~ImI`rp5%VF89Cf$2;~LX!330%9a!XkT zMeRt2Y)jK`NKTiwqx|X-Tok5@xzY6aqkOPLtxDsYnOG6`NjRV~EmNmrrV?V%Fl*RV z26#>i!nK&s;Sih%gp@Qw3)5T5>}Xdq)C+{e+b+#QdSei{AQC_Y9{_Qm5yXhQP`#yB zvqZYA`VTMS^|B#l;p_yEvXH6qt?9)B680j2AxQvO?5QrMZAN4K|}jjD<4s$Dj2 z34|@*L5Tu{`uj?09rdDo@LCs^7O*>{Dd^7*ixrqvb$v=i9T9a!9i#$RN|d-*!@>FY zRl&>U{aI19x&y-bZYi7c9pDsU7hC)Zvd`Kd#Z>HMZ;mikWMWa+$)5yw-PE(Q)K;Kt z24YYXv$HYGsZob#KzUVaLk8&?)Lxm67M-CD52BeOA3IQ@&@kTHDST*LxabH;Njsge zJZMMT?Zp=&bxR>?ch1|>_q2^ddRb&s&H9W9XX1=O9 zToJ`A$_hoo#&*nViEfn#M_jN}JH?1(fJGcPj9%+7iq18n0R##qE0j4$rQna(P4U3A zZ-b9rWb+M`S!7Z(@5)ejR~=l$@jl{~#B=|q2*3pmgbev+YNAuhEE#(>{%nX6AYoio zCv=a<_ML0C-lIpb)h787(YA%wh-}LW!)Fuh@L1Fk@_v+^g0YEBCsbx4V=V&DK~|H2 zZJSTq3SFJz>op2&`8*jUjaoF;_6w^Z4L0q_`ih+OYI(1ngOKSJa}CI8f;^^b$`2+V z(|jG~i}NusTW`Oe-QL#4^=bRdtNyXY>}CtC$3vsCMpd+;iSfetJSrJ}=aYOs6~P}1 zhdD zRwC(V?^AktLtMD9&ku7w;Pl%aotq93wy+kpH0wp2MGb!og<86X5f(Vs8B;}8GgMKV zfZf|mrinzNWSmcyU1EytEu}#a_#$bMND>XH7BP)31IKg!e365L@_b^@(!0A9{v#fk zynk|kG0O8MFLRT7Jj+2t-vA0_Iwhwi}(+-XyKk@N$b;Hmgl0 zgB~UMnN(9uf-=2WATW|EAIPf~!0qDN8V|p3?->e4j%;gM@7Va2pg7b|`I1$`A6qvo zzb#pvR%K&U;rLcDG3*&(+C&>u`O)AkA3Qa651OEqR$M)!fQXP6ANOaddQc>(Wu3aQ zeQVpkex%}9?9n*lA+|OXWZFABaytrNG|G`TaZk%haV$ooMMBBJ_A`-afPnthNOQ`U zF6`90$`gW{lcw3(5TO=q`Gdjx>}gs?Z=t6>wGK%H7)mLY6xIdKg!{sxhAb*Z+k*r( zG>nZgP6ME_R?N3eW84K`K|$@b4#iq?$>p5|(3+u$mc}kd`<@BTT~cI1t)s> znf#jC6VJ*C0qktMw>aEX!>(8+CB3Ul6&0g6w#b#Jgc5);6xP0y=LqiI?8z80eeR;0 zX_zC~&Gv}e{Vn&hcc(CYG%+#;y5Cc?;8{Lq9xSi&g>&h#rx*5K6&Qgay#xs}0MG|A zC|8&e6K*vuZvi#cTp+$GOEF!P`{%Xau8^^g?hLps*D*QI1tkb5fOU8{d4fh53fVzI zk>NqJ^Ld_K4Cl-9{>ZIbI~g5Z^kl8raj}gJU)P3rfB{X-ikJnEupjK6-jInOa!`4_ z@(A2jRbU1vGFkOfda)|Gh<%t~#Rhg_#EjjuTxz5CQ=NvF3`0r~E(@Eel897F2m_4d zSO%0Gx~rZKmSK>QFE}4G?2CGFaKr`pQkxo=;4LiK0>H6OZU6xt_)wA_pjVV7=!{gX z3BMKT0W>Ao83aBflqg71AO5gYoThO4FmY{TT?$k8#-=fxeiaxGc$rn0BlT7QWekB9 zsxGUlDqB-rB;X7U;%F5Jl%bpI8<*;%tR7mn-HR2EYV{|R`~)V!=_wj&r7Y`!EH3kH ze@IgOxPM}nw;hGmm99b-fnS3#5nr<{m$|T3%F){!G#eIn1w&hQyYCF9 zv*&J`DbHQBH=E~Vs+c{SKel6PTui#By$?1vcU_ws@>+A9QFArr^(;C;;FV4mb1y({ zONbuH#+Y(|ZX~PV!$Qp{ngwi-!oKv11R8G_pOo$rx(8OG`Xvx+#>(aeGvngL^jF*D zw|6leRZ!TEhs!f6N5ucRytUjm_B{+Y1)0wJi!5K9E|trI$Ob5xG^OK(4sgImRcfRy zX~0L^fB4Co1DxD5eZeH09vgAxsC>uK-L&e6c~xIcJG>r}435hZJN z1`zqsbU&L6`(ZCby<8P16TR0GB@?QDXnCfk^Eaxd+Hy;3gI;7UQo572pxGL4QLXu6uOp=ph2vHKVn$i)@PJ7RHtwkrI_qU-BqUDxz{Tc+Cbh}n6$ z`@ykTObYqaa-a)oysw^521}|HA-XzLtG|UqHttXQ$e98Gw|o1y`s4Fw@8Z65Kt2eUejMk(Yv!d2kX7sEz4V2Xz#Y=b zV8g&5RKQi=Y5B~MeCmW>d2@w;`Mw^ex+u<~G>wp_7+hQ1i|1pEH;&7>I-bdI*w^{? zlgat^Y(52{#J|h@8UDp`9pb&|Nq^bj+Ro3i(|LcKXJ;okS6<B(%khh)&(mk^pDtef_YZzBmGl2epD)L6>JxrcpHzPS9{&DQ_)pG1 z&>xiJcl8NBhR@KY%9E1&ijKz{QOV57r5oV-1^(n`LBLaoiE4#`FZz*^8Nq5eEx6f^Y!ry@44s8 z{K;Scp>+P2en*`z$Nw~6Or24_|G(hRw*2_QH`V!ayroVv|CZ1Hcf3PeO)s;pgFjd2 zAN;;LmY-K%%kjT(?&q!ZAM5iUC!YVmIG64u_y4*+|LgkvUn_n8TllQ~^OHDP_9p%P zTYssZ`&)mYj<4$TWq-(X%R2rAe2hLR_y6?U>by_?NF86dZ-(FHd^x^WI{*9n{O{}Y zZ>h_etH^nB{MFL=ul$ud;gvs8N0Ae90Xa`ze;FU6zsd8zq0hgi&ws2gBOl*-!~CXx z`E|TcAJN<1yesFI<%e9(K9;74uknVy|EGuQk|dUC4&?ded;J9dCeN-uss8=fe^Yn( e-go6r>hJEWt*xJ{IR86;p{}}LI-&G(>;D1uB9x^7 diff --git a/test_yamux_leaks.cpp b/test_yamux_leaks.cpp deleted file mode 100644 index 05bf1078..00000000 --- a/test_yamux_leaks.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -// Mock классы для тестирования -namespace libp2p { - -namespace peer { -struct PeerId { - std::string id; - - PeerId(const std::string& id_) : id(id_) {} - - std::string toBase58() const { return id; } - - bool operator==(const PeerId& other) const { - return id == other.id; - } -}; -} -} - -// Хеш для peer::PeerId в unordered_map - должен быть определен до использования -namespace std { -template <> -struct hash { - size_t operator()(const libp2p::peer::PeerId& peer) const { - return hash()(peer.id); - } -}; -} - -namespace libp2p { - -namespace basic { -struct Scheduler { - struct Handle { - bool valid = false; - }; - - Handle scheduleWithHandle(std::function cb, std::chrono::milliseconds delay) { - // Простая эмуляция - выполняем через delay - std::thread([cb, delay]() { - std::this_thread::sleep_for(delay); - cb(); - }).detach(); - return Handle{true}; - } - - void cancel(Handle& h) { - h.valid = false; - } -}; -} - -namespace connection { -struct Stream { - virtual ~Stream() = default; -}; - -struct SecureConnection { - peer::PeerId remote_peer; - bool closed = false; - - SecureConnection(const std::string& peer_id) : remote_peer(peer_id) {} - - peer::PeerId remotePeer() const { return remote_peer; } - bool isClosed() const { return closed; } - void close() { closed = true; } -}; - -// Упрощенная версия YamuxedConnection для тестирования -class YamuxedConnection : public std::enable_shared_from_this { -public: - using ConnectionClosedCallback = std::function)>; - - explicit YamuxedConnection( - std::shared_ptr connection, - std::shared_ptr scheduler, - ConnectionClosedCallback closed_callback) - : connection_(std::move(connection)) - , scheduler_(std::move(scheduler)) - , closed_callback_(std::move(closed_callback)) - , remote_peer_(connection_->remotePeer()) { - - std::cout << "[YamuxedConnection] Created connection to " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - ~YamuxedConnection() { - std::cout << "[YamuxedConnection] Destroyed connection to " - << remote_peer_.toBase58() - << " at address " << (void*)this << std::endl; - } - - void start() { - started_ = true; - std::cout << "[YamuxedConnection] Started connection to " - << remote_peer_.toBase58() << std::endl; - } - - void close() { - if (closed_) return; - - auto self_ptr = shared_from_this(); - std::cout << "[YamuxedConnection] Closing connection to " - << remote_peer_.toBase58() - << " (use_count: " << self_ptr.use_count() << ")" << std::endl; - - closed_ = true; - connection_->close(); - - // Вызываем callback для ConnectionManager - if (closed_callback_ && registered_in_manager_) { - std::cout << "[YamuxedConnection] Calling closed_callback_ with use_count: " - << self_ptr.use_count() << std::endl; - - closed_callback_(remote_peer_, self_ptr); - } - } - - bool isClosed() const { return closed_; } - - peer::PeerId remotePeer() const { return remote_peer_; } - - void markAsRegistered() { - registered_in_manager_ = true; - std::cout << "[YamuxedConnection] Marked as registered in manager" << std::endl; - } - - long getSharedPtrUseCount() const { - auto self_ptr = shared_from_this(); - return self_ptr.use_count(); - } - -private: - std::shared_ptr connection_; - std::shared_ptr scheduler_; - ConnectionClosedCallback closed_callback_; - peer::PeerId remote_peer_; - bool started_ = false; - bool closed_ = false; - bool registered_in_manager_ = false; -}; - -} // namespace connection - -namespace network { - -// Упрощенная версия ConnectionManager для тестирования -class ConnectionManagerTest { -public: - using ConnectionSPtr = std::shared_ptr; - - void addConnectionToPeer(const peer::PeerId& peer, ConnectionSPtr conn) { - std::cout << "[ConnectionManager] === addConnectionToPeer CALLED ===" << std::endl; - std::cout << "[ConnectionManager] peer: " << peer.toBase58() << std::endl; - std::cout << "[ConnectionManager] connection address: " << (void*)conn.get() << std::endl; - std::cout << "[ConnectionManager] connection use_count: " << conn.use_count() << std::endl; - - auto it = connections_.find(peer); - if (it == connections_.end()) { - std::cout << "[ConnectionManager] Creating new peer entry" << std::endl; - connections_.insert({peer, {conn}}); - } else { - std::cout << "[ConnectionManager] Adding to existing peer (current size: " - << it->second.size() << ")" << std::endl; - connections_[peer].insert(conn); - } - - std::cout << "[ConnectionManager] Total connections for peer: " - << connections_[peer].size() << std::endl; - std::cout << "[ConnectionManager] === addConnectionToPeer FINISHED ===" << std::endl; - } - - void onConnectionClosed(const peer::PeerId& peer, ConnectionSPtr connection) { - std::cout << "[ConnectionManager] === onConnectionClosed CALLED ===" << std::endl; - std::cout << "[ConnectionManager] peer: " << peer.toBase58() << std::endl; - std::cout << "[ConnectionManager] connection address: " << (void*)connection.get() << std::endl; - std::cout << "[ConnectionManager] connection use_count: " << connection.use_count() << std::endl; - - auto it = connections_.find(peer); - if (it == connections_.end()) { - std::cout << "[ConnectionManager] WARNING: Peer not found in connections_!" << std::endl; - return; - } - - std::cout << "[ConnectionManager] Found peer, current connections: " << it->second.size() << std::endl; - - // Показываем все соединения для сравнения - for (const auto& conn : it->second) { - std::cout << "[ConnectionManager] Existing connection: " - << (void*)conn.get() - << " (use_count: " << conn.use_count() << ")" << std::endl; - } - - auto erased = it->second.erase(connection); - std::cout << "[ConnectionManager] Erased count: " << erased << std::endl; - - if (erased == 0) { - std::cout << "[ConnectionManager] ERROR: Connection was NOT found in set!" << std::endl; - } else { - std::cout << "[ConnectionManager] SUCCESS: Connection removed" << std::endl; - } - - if (it->second.empty()) { - connections_.erase(peer); - std::cout << "[ConnectionManager] Peer removed from connections_ (no more connections)" << std::endl; - } - - std::cout << "[ConnectionManager] === onConnectionClosed FINISHED ===" << std::endl; - } - - size_t getTotalConnections() const { - size_t total = 0; - for (const auto& [peer, conns] : connections_) { - total += conns.size(); - } - return total; - } - - void printStatus() const { - std::cout << "\n[ConnectionManager] === STATUS ===" << std::endl; - std::cout << "[ConnectionManager] Total peers: " << connections_.size() << std::endl; - std::cout << "[ConnectionManager] Total connections: " << getTotalConnections() << std::endl; - - for (const auto& [peer, conns] : connections_) { - std::cout << "[ConnectionManager] Peer " << peer.toBase58() - << " has " << conns.size() << " connections:" << std::endl; - for (const auto& conn : conns) { - std::cout << "[ConnectionManager] - " << (void*)conn.get() - << " (use_count: " << conn.use_count() << ")" << std::endl; - } - } - std::cout << "[ConnectionManager] ===================" << std::endl; - } - -private: - std::unordered_map> connections_; -}; - -} // namespace network -} // namespace libp2p - -// Тест множественных соединений -class YamuxLeakTest { -public: - void runTest() { - std::cout << "\n=== YAMUX LEAK TEST STARTED ===" << std::endl; - - auto scheduler = std::make_shared(); - auto connection_manager = std::make_shared(); - - // Создаем множественные соединения - const int num_connections = 5; - std::vector> connections; - - for (int i = 0; i < num_connections; ++i) { - auto peer_id = "peer_" + std::to_string(i); - auto secure_conn = std::make_shared(peer_id); - - // Создаем callback для ConnectionManager - auto callback = [connection_manager](const libp2p::peer::PeerId& peer, - std::shared_ptr conn) { - connection_manager->onConnectionClosed(peer, conn); - }; - - auto yamux_conn = std::make_shared( - secure_conn, scheduler, callback); - - yamux_conn->start(); - yamux_conn->markAsRegistered(); - - connection_manager->addConnectionToPeer(libp2p::peer::PeerId(peer_id), yamux_conn); - connections.push_back(yamux_conn); - - std::cout << "\n--- Created connection " << (i+1) << "/" << num_connections << " ---" << std::endl; - } - - connection_manager->printStatus(); - - // Даем время на обработку - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - std::cout << "\n=== CLOSING ALL CONNECTIONS ===" << std::endl; - - // Закрываем все соединения - for (int i = 0; i < connections.size(); ++i) { - std::cout << "\n--- Closing connection " << (i+1) << "/" << connections.size() << " ---" << std::endl; - connections[i]->close(); - - connection_manager->printStatus(); - } - - // Очищаем наши ссылки - connections.clear(); - - std::cout << "\n=== FINAL STATUS ===" << std::endl; - connection_manager->printStatus(); - - std::cout << "\n=== YAMUX LEAK TEST FINISHED ===" << std::endl; - } -}; - -int main() { - YamuxLeakTest test; - test.runTest(); - - std::cout << "\nWaiting for potential cleanup..." << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(1)); - - return 0; -} \ No newline at end of file diff --git a/test_yamux_realistic b/test_yamux_realistic deleted file mode 100755 index fdf00c1eae674b26187e9a0dfe786c2b7c314524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 275096 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