66#include < linux/perf_event.h>
77#include < asm/unistd.h>
88#include < cstdio>
9+ #include < fcntl.h>
910
1011namespace libp2p ::connection {
1112
@@ -45,11 +46,12 @@ void* HardwareSharedPtrTracker::getRefCountAddress(const std::shared_ptr<Yamuxed
4546 return nullptr ;
4647 }
4748
48- void * ref_count_addr = control_block;
49+ uint32_t * ref_count_addr = ( uint32_t *)(( uint8_t *) control_block + sizeof ( void *)) ;
4950
5051 std::cout << " Control block address: " << control_block << " \n " ;
5152 std::cout << " Reference count address: " << ref_count_addr << " \n " ;
5253 std::cout << " Current use_count: " << ptr.use_count () << " \n " ;
54+ assert (*ref_count_addr == ptr.use_count ());
5355
5456 return ref_count_addr;
5557}
@@ -61,22 +63,50 @@ bool HardwareSharedPtrTracker::setHardwareWatchpoint(void* address) {
6163 pe.type = PERF_TYPE_BREAKPOINT;
6264 pe.size = sizeof (pe);
6365 pe.config = 0 ;
64- pe.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
66+ pe.bp_type = HW_BREAKPOINT_W; // Только запись, чтение может генерировать много событий
6567 pe.bp_addr = reinterpret_cast <uint64_t >(address);
66- pe.bp_len = sizeof ( long );
67- pe.disabled = 0 ;
68+ pe.bp_len = HW_BREAKPOINT_LEN_4; // 4 байта для int
69+ pe.disabled = 0 ; // Включен сразу
6870 pe.exclude_kernel = 1 ;
6971 pe.exclude_hv = 1 ;
72+ pe.exclude_user = 0 ; // Отслеживаем user space
73+ pe.sample_period = 1 ; // Генерировать событие на каждое изменение
74+ pe.wakeup_events = 1 ; // Пробуждать на каждое событие
75+
76+ std::cout << " 🔧 Настройка hardware watchpoint:\n " ;
77+ std::cout << " Адрес: " << address << " \n " ;
78+ std::cout << " bp_addr: 0x" << std::hex << pe.bp_addr << std::dec << " \n " ;
79+ std::cout << " bp_len: " << pe.bp_len << " \n " ;
80+ std::cout << " bp_type: " << pe.bp_type << " (только запись)\n " ;
7081
7182 int fd = syscall (__NR_perf_event_open, &pe, 0 , -1 , -1 , 0 );
7283 if (fd == -1 ) {
73- perror (" perf_event_open for hardware watchpoint failed" );
84+ perror (" ❌ perf_event_open неудачен" );
85+ std::cout << " Ошибка: " << strerror (errno) << " \n " ;
86+ std::cout << " Код ошибки: " << errno << " \n " ;
7487 return false ;
7588 }
7689
90+ // Настраиваем доставку сигнала
91+ struct f_owner_ex owner;
92+ owner.type = F_OWNER_TID;
93+ owner.pid = syscall (SYS_gettid);
94+
95+ if (fcntl (fd, F_SETOWN_EX, &owner) == -1 ) {
96+ perror (" ⚠️ fcntl F_SETOWN_EX failed" );
97+ }
98+
99+ if (fcntl (fd, F_SETFL, O_ASYNC) == -1 ) {
100+ perror (" ⚠️ fcntl F_SETFL failed" );
101+ }
102+
103+ if (fcntl (fd, F_SETSIG, SIGTRAP) == -1 ) {
104+ perror (" ⚠️ fcntl F_SETSIG failed" );
105+ }
106+
77107 watchpoint_fd_ = fd;
78108
79- std::cout << " Hardware watchpoint set on address " << address
109+ std::cout << " ✅ Hardware watchpoint установлен на адрес " << address
80110 << " (fd=" << fd << " )\n " ;
81111
82112 return true ;
@@ -96,33 +126,43 @@ void HardwareSharedPtrTracker::signalHandler(int sig, siginfo_t* info, void* con
96126 if (!instance_ || sig != SIGTRAP) {
97127 return ;
98128 }
99-
100- // printStackTrace();
101129
102130 static int call_number = 0 ;
103131 call_number++;
104132
105- const char msg[] = " \n === HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED ===\n " ;
133+ const char msg[] = " \n 🚨 === HARDWARE BREAKPOINT: REFERENCE COUNT CHANGED === 🚨 \n " ;
106134 write (STDOUT_FILENO, msg, sizeof (msg) - 1 );
107135
108- char call_msg[100 ];
109- int len = snprintf (call_msg, sizeof (call_msg), " Call #%d - Address : %p\n " , call_number, info->si_addr );
136+ char call_msg[200 ];
137+ int len = snprintf (call_msg, sizeof (call_msg), " 📍 Изменение #%d - Адрес : %p\n " , call_number, info->si_addr );
110138 write (STDOUT_FILENO, call_msg, len);
111139
112- const int max_frames = 15 ;
113- void * buffer[max_frames];
114-
115- const char stack_msg[] = " Stack trace (exact location of reference count change):\n " ;
140+ const char stack_msg[] = " 📚 Стек трассировки (точное место изменения счетчика ссылок):\n " ;
116141 write (STDOUT_FILENO, stack_msg, sizeof (stack_msg) - 1 );
117142
143+ // Получаем стек трассировки
144+ const int max_frames = 7 ;
145+ void * buffer[max_frames];
118146 int nframes = backtrace (buffer, max_frames);
119147
120- backtrace_symbols_fd (buffer, nframes, STDOUT_FILENO);
148+ // Используем backtrace_symbols для получения символов
149+ char ** symbols = backtrace_symbols (buffer, nframes);
121150
122- const char end_msg[] = " ================================================\n\n " ;
123- write (STDOUT_FILENO, end_msg, sizeof (end_msg) - 1 );
151+ if (symbols) {
152+ for (int i = 0 ; i < nframes; ++i) {
153+ char frame_msg[500 ];
154+ int frame_len = snprintf (frame_msg, sizeof (frame_msg),
155+ " [%2d] %s\n " , i, symbols[i]);
156+ write (STDOUT_FILENO, frame_msg, frame_len);
157+ }
158+ free (symbols);
159+ } else {
160+ // Fallback - используем backtrace_symbols_fd если symbols == NULL
161+ backtrace_symbols_fd (buffer, nframes, STDOUT_FILENO);
162+ }
124163
125- // instance_->signal_count_.fetch_add(1, std::memory_order_relaxed);
164+ const char end_msg[] = " 🔚 ============================================== 🔚\n\n " ;
165+ write (STDOUT_FILENO, end_msg, sizeof (end_msg) - 1 );
126166}
127167
128168void HardwareSharedPtrTracker::printStackTrace () {
@@ -167,7 +207,7 @@ void HardwareSharedPtrTracker::checkAndSwitchIfNeeded() {
167207 }
168208}
169209
170- void HardwareSharedPtrTracker::startTracking (std::shared_ptr<YamuxedConnection> ptr) {
210+ void HardwareSharedPtrTracker::startTracking (const std::shared_ptr<YamuxedConnection>& ptr) {
171211 if (!enabled_) {
172212 return ;
173213 }
@@ -221,9 +261,9 @@ void HardwareSharedPtrTracker::stopTracking() {
221261 std::cout << " =================================\n\n " ;
222262}
223263
224- void trackNextYamuxedConnection (std::shared_ptr<YamuxedConnection> ptr) {
264+ void trackNextYamuxedConnection (const std::shared_ptr<YamuxedConnection>& ptr) {
225265 auto & tracker = HardwareSharedPtrTracker::getInstance ();
226- tracker.startTracking (std::move ( ptr) );
227- }
266+ tracker.startTracking (ptr);
267+ }
228268
229269} // namespace libp2p::connection
0 commit comments