Skip to content

test #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
91 changes: 91 additions & 0 deletions include/libp2p/muxer/yamux/hardware_tracker.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once

#include <memory>
#include <atomic>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>
#include <execinfo.h>
#include <iostream>
#include <cstring>

namespace libp2p::connection {

class YamuxedConnection;

class HardwareSharedPtrTracker {
public:
static HardwareSharedPtrTracker& getInstance() {
static HardwareSharedPtrTracker instance;
return instance;
}

// Start tracking the reference count of a shared_ptr
void startTracking(const std::shared_ptr<YamuxedConnection>& 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<YamuxedConnection>& 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<bool> enabled_{false};
std::atomic<bool> is_tracking_{false};
std::atomic<bool> should_stop_{false}; // Flag for signal handler

void* watched_address_{nullptr};
int watchpoint_fd_{-1}; // Store perf_event fd
std::weak_ptr<YamuxedConnection> 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(const std::shared_ptr<YamuxedConnection>& 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)

} // namespace libp2p::connection
2 changes: 1 addition & 1 deletion include/libp2p/muxer/yamux/yamux_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace libp2p::connection {
closeCompleted();

/// Underlying connection (secured)
std::shared_ptr<connection::SecureConnection> connection_;
std::weak_ptr<connection::SecureConnection> connection_;

/// Yamux-specific interface of connection
YamuxStreamFeedback &feedback_;
Expand Down
12 changes: 12 additions & 0 deletions include/libp2p/muxer/yamux/yamuxed_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ namespace libp2p::connection {
ReadCallbackFunc cb) override;
void deferWriteCallback(std::error_code ec, WriteCallbackFunc cb) override;

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<StreamId, std::shared_ptr<YamuxStream>>;

Expand Down Expand Up @@ -241,6 +251,8 @@ namespace libp2p::connection {

bool close_after_write_ = false;

bool registered_in_manager_ = false;

public:
LIBP2P_METRICS_INSTANCE_COUNT_IF_ENABLED(
libp2p::connection::YamuxedConnection);
Expand Down
7 changes: 7 additions & 0 deletions include/libp2p/network/impl/connection_manager_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include <unordered_set>
#include <mutex>

#include <libp2p/event/bus.hpp>
#include <libp2p/network/connection_manager.hpp>
Expand Down Expand Up @@ -46,6 +47,12 @@ namespace libp2p::network {
/// Reentrancy resolver between closeConnectionsToPeer and
/// onConnectionClosed
boost::optional<peer::PeerId> 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<ConnectionSPtr> connection_is_closing_;
};

} // namespace libp2p::network
1 change: 1 addition & 0 deletions src/muxer/yamux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading