Skip to content

Commit 35e3ff6

Browse files
committed
tests
1 parent e07b03d commit 35e3ff6

16 files changed

+2792
-0
lines changed

debug_yamux_leaks

111 KB
Binary file not shown.

debug_yamux_leaks.cpp

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
#include <iostream>
2+
#include <memory>
3+
#include <thread>
4+
#include <chrono>
5+
#include <mutex>
6+
#include <unordered_map>
7+
#include <unordered_set>
8+
9+
// Простая диагностика утечек для shared_ptr
10+
class LeakDetector {
11+
public:
12+
static LeakDetector& instance() {
13+
static LeakDetector detector;
14+
return detector;
15+
}
16+
17+
void registerPointer(void* ptr, const char* type) {
18+
std::lock_guard<std::mutex> lock(mutex_);
19+
active_pointers_[ptr] = type;
20+
std::cout << "[LEAK_DEBUG] Created " << type << " at " << ptr << std::endl;
21+
}
22+
23+
void unregisterPointer(void* ptr) {
24+
std::lock_guard<std::mutex> lock(mutex_);
25+
auto it = active_pointers_.find(ptr);
26+
if (it != active_pointers_.end()) {
27+
std::cout << "[LEAK_DEBUG] Destroyed " << it->second << " at " << ptr << std::endl;
28+
active_pointers_.erase(it);
29+
}
30+
}
31+
32+
void printActivePointers() {
33+
std::lock_guard<std::mutex> lock(mutex_);
34+
if (active_pointers_.empty()) {
35+
std::cout << "[LEAK_DEBUG] No active pointers detected!" << std::endl;
36+
} else {
37+
std::cout << "[LEAK_DEBUG] Active pointers (" << active_pointers_.size() << "):" << std::endl;
38+
for (const auto& [ptr, type] : active_pointers_) {
39+
std::cout << " " << type << " at " << ptr << std::endl;
40+
}
41+
}
42+
}
43+
44+
private:
45+
std::mutex mutex_;
46+
std::unordered_map<void*, std::string> active_pointers_;
47+
};
48+
49+
// Макросы для отладки утечек
50+
#define REGISTER_LEAK_DEBUG(ptr, type) LeakDetector::instance().registerPointer(ptr, type)
51+
#define UNREGISTER_LEAK_DEBUG(ptr) LeakDetector::instance().unregisterPointer(ptr)
52+
#define PRINT_ACTIVE_LEAKS() LeakDetector::instance().printActivePointers()
53+
54+
// Пример использования для диагностики YamuxedConnection
55+
class YamuxedConnectionDebug : public std::enable_shared_from_this<YamuxedConnectionDebug> {
56+
public:
57+
YamuxedConnectionDebug() {
58+
REGISTER_LEAK_DEBUG(this, "YamuxedConnection");
59+
}
60+
61+
~YamuxedConnectionDebug() {
62+
UNREGISTER_LEAK_DEBUG(this);
63+
}
64+
65+
void debugSharedPtrReferences() {
66+
auto self = shared_from_this();
67+
std::cout << "[DEBUG] shared_ptr use_count: " << self.use_count() << std::endl;
68+
69+
// Симулируем различные места, где могут держаться ссылки:
70+
71+
// 1. В streams_ (как было ранее)
72+
streams_["test"] = std::make_shared<int>(42);
73+
std::cout << "[DEBUG] After adding to streams_, use_count: " << self.use_count() << std::endl;
74+
75+
// 2. В callback'ах
76+
auto callback = [self](){ /* do something */ };
77+
std::cout << "[DEBUG] After capturing in callback, use_count: " << self.use_count() << std::endl;
78+
79+
// 3. В timer'ах
80+
auto timer_callback = [weak_self = std::weak_ptr<YamuxedConnectionDebug>(self)](){
81+
if (auto strong = weak_self.lock()) {
82+
/* do something */
83+
}
84+
};
85+
std::cout << "[DEBUG] After weak capture in timer, use_count: " << self.use_count() << std::endl;
86+
87+
// Очистка
88+
streams_.clear();
89+
std::cout << "[DEBUG] After clearing streams_, use_count: " << self.use_count() << std::endl;
90+
}
91+
92+
private:
93+
std::unordered_map<std::string, std::shared_ptr<int>> streams_;
94+
};
95+
96+
// Mock classes for simple testing
97+
namespace libp2p {
98+
namespace peer {
99+
struct PeerId {
100+
std::string id;
101+
std::string toBase58() const { return id; }
102+
};
103+
}
104+
105+
namespace connection {
106+
struct CapableConnection {
107+
virtual ~CapableConnection() = default;
108+
virtual bool isClosed() const = 0;
109+
};
110+
}
111+
112+
namespace muxer::yamux {
113+
// Simple test for shared_ptr behavior in unordered_set
114+
class YamuxedConnection {
115+
public:
116+
void debugPrintMemoryLeakSources() {
117+
std::cout << "=== MEMORY LEAK DEBUG INFO ===" << std::endl;
118+
std::cout << "This is a test method" << std::endl;
119+
}
120+
};
121+
}
122+
}
123+
124+
// Test shared_ptr behavior in unordered_set
125+
void testSharedPtrInSet() {
126+
std::cout << "\n=== Testing shared_ptr behavior in unordered_set ===" << std::endl;
127+
128+
auto obj = std::make_shared<int>(42);
129+
auto obj2 = obj; // same object, different shared_ptr instance
130+
131+
std::unordered_set<std::shared_ptr<int>> set;
132+
133+
// Add first shared_ptr
134+
set.insert(obj);
135+
std::cout << "Added obj to set, size: " << set.size() << std::endl;
136+
137+
// Try to find with different shared_ptr to same object
138+
auto found = set.find(obj2);
139+
if (found != set.end()) {
140+
std::cout << "SUCCESS: obj2 found in set (pointing to same object)" << std::endl;
141+
} else {
142+
std::cout << "FAIL: obj2 NOT found in set" << std::endl;
143+
}
144+
145+
// Try to erase with different shared_ptr to same object
146+
auto erased = set.erase(obj2);
147+
std::cout << "Erased count using obj2: " << erased << std::endl;
148+
std::cout << "Set size after erase: " << set.size() << std::endl;
149+
150+
// Test with shared_from_this equivalent
151+
struct TestClass : std::enable_shared_from_this<TestClass> {
152+
int value = 123;
153+
};
154+
155+
auto test_obj = std::make_shared<TestClass>();
156+
auto self_ptr = test_obj->shared_from_this();
157+
158+
std::unordered_set<std::shared_ptr<TestClass>> test_set;
159+
test_set.insert(test_obj);
160+
161+
auto found2 = test_set.find(self_ptr);
162+
if (found2 != test_set.end()) {
163+
std::cout << "SUCCESS: shared_from_this() found in set" << std::endl;
164+
} else {
165+
std::cout << "FAIL: shared_from_this() NOT found in set" << std::endl;
166+
}
167+
168+
auto erased2 = test_set.erase(self_ptr);
169+
std::cout << "Erased count using shared_from_this(): " << erased2 << std::endl;
170+
std::cout << "Test set size after erase: " << test_set.size() << std::endl;
171+
}
172+
173+
int main() {
174+
std::cout << "=== Yamux Memory Leak Debug Tool ===" << std::endl;
175+
176+
// Test shared_ptr behavior
177+
testSharedPtrInSet();
178+
179+
// Test our debug method
180+
auto yamux_conn = std::make_shared<libp2p::muxer::yamux::YamuxedConnection>();
181+
yamux_conn->debugPrintMemoryLeakSources();
182+
183+
std::cout << "\n=== Debug tool completed ===" << std::endl;
184+
return 0;
185+
}

test_compilation_check

60.8 KB
Binary file not shown.

test_final_verification

74.1 KB
Binary file not shown.

test_final_verification.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include <iostream>
2+
#include <memory>
3+
#include <functional>
4+
#include <string>
5+
6+
// Финальная проверка исправлений компиляции
7+
8+
namespace libp2p {
9+
10+
namespace peer {
11+
struct PeerId {
12+
std::string id = "test_peer";
13+
std::string toBase58() const { return id; }
14+
bool operator==(const PeerId& other) const { return id == other.id; }
15+
};
16+
}
17+
18+
namespace connection {
19+
class CapableConnection {
20+
public:
21+
virtual ~CapableConnection() = default;
22+
virtual bool isClosed() const = 0;
23+
};
24+
25+
class YamuxedConnection : public CapableConnection, public std::enable_shared_from_this<YamuxedConnection> {
26+
public:
27+
using ConnectionClosedCallback = std::function<void(const peer::PeerId&, const std::shared_ptr<CapableConnection>&)>;
28+
29+
YamuxedConnection(ConnectionClosedCallback callback) : closed_callback_(callback) {}
30+
31+
bool isClosed() const override { return false; }
32+
33+
void simulateCloseCallback() {
34+
peer::PeerId remote_peer;
35+
auto self_ptr = shared_from_this();
36+
37+
// ИСПРАВЛЕНИЕ 1: Приведение типа в yamuxed_connection.cpp (строка 574)
38+
closed_callback_(remote_peer, std::static_pointer_cast<CapableConnection>(self_ptr));
39+
}
40+
41+
private:
42+
ConnectionClosedCallback closed_callback_;
43+
};
44+
}
45+
46+
namespace network {
47+
class ConnectionManagerImpl {
48+
public:
49+
// ИСПРАВЛЕНИЕ 2: Правильная сигнатура в connection_manager_impl.cpp (строка 158)
50+
void onConnectionClosed(const peer::PeerId& peer,
51+
const std::shared_ptr<connection::CapableConnection>& connection) {
52+
std::cout << "ConnectionManagerImpl::onConnectionClosed called for peer: "
53+
<< peer.toBase58() << std::endl;
54+
std::cout << "Connection address: " << (void*)connection.get() << std::endl;
55+
}
56+
};
57+
}
58+
59+
}
60+
61+
int main() {
62+
std::cout << "=== ПРОВЕРКА ВСЕХ ИСПРАВЛЕНИЙ КОМПИЛЯЦИИ ===" << std::endl;
63+
64+
auto manager = std::make_shared<libp2p::network::ConnectionManagerImpl>();
65+
66+
auto callback = [manager](const libp2p::peer::PeerId& peer,
67+
const std::shared_ptr<libp2p::connection::CapableConnection>& conn) {
68+
manager->onConnectionClosed(peer, conn);
69+
};
70+
71+
auto connection = std::make_shared<libp2p::connection::YamuxedConnection>(callback);
72+
73+
std::cout << "1. Тестирование yamuxed_connection.cpp - приведение типа..." << std::endl;
74+
connection->simulateCloseCallback();
75+
76+
std::cout << "2. Тестирование connection_manager_impl.cpp - сигнатура метода..." << std::endl;
77+
libp2p::peer::PeerId peer;
78+
manager->onConnectionClosed(peer, connection);
79+
80+
std::cout << "=== ВСЕ ИСПРАВЛЕНИЯ РАБОТАЮТ КОРРЕКТНО ===" << std::endl;
81+
return 0;
82+
}

test_fix_verification

74.6 KB
Binary file not shown.

test_yamux_100_connections

77.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)