debug: реорганизация категорий — SYS(1), ETCP(4) расширен, CONNECTION(3) очищен; fix stcp_client.c sock_err до connect()

Категории:
- DEBUG_CATEGORY_SYS=1: u_async + ll_queue + memory + timing (было 4)
- DEBUG_CATEGORY_ETCP=4: ETCP + normalizer + BBR (было 3)
- DEBUG_CATEGORY_CONNECTION=3: только события статуса линка/подключения (INFO)
- DEBUG_CATEGORY_KEEPALIVE=21: только периодический мониторинг (DEBUG)
- Удалены: NORMALIZER, BBR, CONNECTIVITY
- Устаревшие DB_SYNC → CHAT_SYNC + MEMBER_SYNC (предыдущий коммит)

CONNECTION+INFO — только: Connection UP/DOWN, Link UP/down, Link initialized/added,
  NAT address init/changed, init server/client.
CONNECTION+DEBUG — retry, collision, reinit, socket register.
KEEPALIVE — init_timer SUPPRESSED, timer started, keepalive skipped.
REINIT — ETCP+INFO.
Connection status changed — GENERAL (пользовательский callback).
Dedup link_status: if(old_link_status) перед Link down.
Убран дублирующий Conn:%s из Link down, добавлен link_id в client added link.
Молчаливые ошибки: +DEBUG_ERROR в 15 местах (merkle_sync, member_sync, db_sync).

Fix: stcp_client.c — socket_get_error() вызывался ДО connect(), проверяя
застарелое errno вместо ошибки connect(). Неблокирующий connect() возвращает
-1+EINPROGRESS (норма), но сравнивался с мусором → ложный FAIL.
Все 4 STCP-теста исправлены (68/68 pass).
This commit is contained in:
evgeny committed 2026-08-05 10:43:32 +03:00
1 parent 1895f23034
commit be0e76c9a6
38 files changed
+721 -722

No files matched your search

+27 -27
View File
@@ -22,7 +22,7 @@ static inline void queue_check_thread(struct ll_queue* q) {
#ifdef _WIN32
DWORD current = GetCurrentThreadId();
if (q->owner_thread != current) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': thread mismatch! owner=%lu current=%lu",
q->name ? q->name : "unknown",
(unsigned long)q->owner_thread,
(unsigned long)current);
@@ -32,7 +32,7 @@ static inline void queue_check_thread(struct ll_queue* q) {
#else
pthread_t current = pthread_self();
if (!pthread_equal(q->owner_thread, current)) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': thread mismatch! owner=%lu current=%lu",
q->name ? q->name : "unknown",
(unsigned long)q->owner_thread,
(unsigned long)current);
@@ -99,7 +99,7 @@ struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, uint16_t index_o
}
}
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_new: created queue %p, hash_size=%zu", q, hash_size);
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_new: created queue %p, hash_size=%zu", q, hash_size);
return q;
}
@@ -124,7 +124,7 @@ struct ll_entry* ll_alloc_lldgram(uint16_t len) {
void queue_free(struct ll_queue* q) {
if (!q) return;
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_free: freeing queue %p, head=%p, tail=%p, count=%d",
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_free: freeing queue %p, head=%p, tail=%p, count=%d",
q, q->head, q->tail, q->count);
// ВАЖНО: Не освобождаем элементы в очереди - они должны быть извлечены отдельно
@@ -210,7 +210,7 @@ struct ll_entry* queue_entry_new(size_t data_size) {
entry->len = 0;
entry->pool = NULL; // Выделено через u_malloc
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_entry_new: created entry %p, size=%zu", entry, data_size);
// DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_entry_new: created entry %p, size=%zu", entry, data_size);
return entry;
}
@@ -226,7 +226,7 @@ struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool) {
entry->len = 0;
entry->pool = pool; // Выделено из пула
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_entry_new_from_pool: created entry %p from pool %p", entry, pool);
// DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_entry_new_from_pool: created entry %p from pool %p", entry, pool);
return entry;
}
@@ -265,7 +265,7 @@ static void add_to_hash(struct ll_queue* q, struct ll_entry* entry) {
if (!q || !entry) return;
if (q->hash_size == 0 || q->index_size == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] Empty hash_size=%d or index_size=%d",q->name, q->hash_size, q->index_size);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] Empty hash_size=%d or index_size=%d",q->name, q->hash_size, q->index_size);
return;
}
@@ -307,13 +307,13 @@ static void waiter_defer_cb(void* arg) {
struct queue_waiter_handle* h = (struct queue_waiter_handle*)arg;
h->call_soon_id = NULL;
if (h->defer_cb) h->defer_cb(h->defer_q, h->defer_arg);
else DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "waiter_defer_cb: NULL callback (stale?) q=%p", (void*)h->defer_q);
else DEBUG_ERROR(DEBUG_CATEGORY_SYS, "waiter_defer_cb: NULL callback (stale?) q=%p", (void*)h->defer_q);
}
static inline void queue_waiter_call(struct ll_queue* q, queue_threshold_callback_fn cb, void* arg,
struct queue_waiter_handle* h) {
if (q->waiter_defer) {
if (h->call_soon_id) { DEBUG_WARN(DEBUG_CATEGORY_LL_QUEUE, "queue_waiter_call: overwriting existing call_soon_id=%p", h->call_soon_id); uasync_call_soon_cancel(q->ua, h->call_soon_id); }
if (h->call_soon_id) { DEBUG_WARN(DEBUG_CATEGORY_SYS, "queue_waiter_call: overwriting existing call_soon_id=%p", h->call_soon_id); uasync_call_soon_cancel(q->ua, h->call_soon_id); }
h->defer_q = q; h->defer_cb = cb; h->defer_arg = arg;
h->call_soon_id = uasync_call_soon(q->ua, h, waiter_defer_cb);
} else {
@@ -341,7 +341,7 @@ static void check_waiters(struct ll_queue* q) {
u_free(waiter);
if (cb) {
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "check_waiters: waking head waiter, count=%d<=%d, bytes=%zu<=%zu",
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "check_waiters: waking head waiter, count=%d<=%d, bytes=%zu<=%zu",
q->count, q->threshold_max_packets, q->total_bytes, q->threshold_max_bytes);
queue_waiter_call(q, cb, arg, h);
}
@@ -354,13 +354,13 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry) {
#endif
if (entry->prev || entry->next || q->head == entry || q->tail == entry) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] double put detected! entry=%p prev=%p next=%p len=%u",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] double put detected! entry=%p prev=%p next=%p len=%u",
q->name, (void*)entry, (void*)entry->prev, (void*)entry->next, entry->len);
abort();
}
if (q->hash_size > 0) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] Put no-hash data to hash queue",q->name);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] Put no-hash data to hash queue",q->name);
queue_dgram_free(entry);
queue_entry_free(entry);
return -1;
@@ -401,13 +401,13 @@ int queue_data_put_with_index(struct ll_queue* q, struct ll_entry* entry) {
#endif
if (entry->prev || entry->next || q->head == entry || q->tail == entry) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] double put_with_index detected! entry=%p prev=%p next=%p",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] double put_with_index detected! entry=%p prev=%p next=%p",
q->name, (void*)entry, (void*)entry->prev, (void*)entry->next);
abort();
}
if (q->index_size == 0 || (size_t)q->index_offset + q->index_size > (size_t)entry->size) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] invalid index: offset=%u size=%u (data_size=%u)",q->name, q->index_offset, q->index_size, entry->size);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] invalid index: offset=%u size=%u (data_size=%u)",q->name, q->index_offset, q->index_size, entry->size);
queue_dgram_free(entry);
queue_entry_free(entry);
return -1;
@@ -450,13 +450,13 @@ int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry) {
#endif
if (entry->prev || entry->next || q->head == entry || q->tail == entry) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] double put_first detected! entry=%p prev=%p next=%p",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] double put_first detected! entry=%p prev=%p next=%p",
q->name, (void*)entry, (void*)entry->prev, (void*)entry->next);
abort();
}
if (q->hash_size > 0) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] Put no-hash data to hash queue",q->name);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] Put no-hash data to hash queue",q->name);
queue_dgram_free(entry);
queue_entry_free(entry); // как было в оригинале
return -1;
@@ -489,13 +489,13 @@ int queue_data_put_first_with_index(struct ll_queue* q, struct ll_entry* entry)
#endif
if (entry->prev || entry->next || q->head == entry || q->tail == entry) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] double put_first_with_index detected! entry=%p prev=%p next=%p",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] double put_first_with_index detected! entry=%p prev=%p next=%p",
q->name, (void*)entry, (void*)entry->prev, (void*)entry->next);
abort();
}
if (q->index_size == 0 || (size_t)q->index_offset + q->index_size > (size_t)entry->size) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] invalid index: offset=%u size=%u (data_size=%u)",q->name, q->index_offset, q->index_size, entry->size);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] invalid index: offset=%u size=%u (data_size=%u)",q->name, q->index_offset, q->index_size, entry->size);
queue_dgram_free(entry);
queue_entry_free(entry);
return -1;
@@ -552,7 +552,7 @@ struct ll_entry* queue_data_get(struct ll_queue* q) {
remove_from_hash(q, entry);
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_data_get: got entry %p (id=%u), count=%d", entry, entry->id, q->count);
// DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_data_get: got entry %p (id=%u), count=%d", entry, entry->id, q->count);
// Приостановить коллбэки для предотвращения рекурсии
q->callback_suspended = 1;
@@ -582,7 +582,7 @@ int queue_check_consistency(struct ll_queue* q) {
if (!q) return -1;
if (q->count > 0 && !q->head) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': count=%d but head is NULL!",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': count=%d but head is NULL!",
q->name ? q->name : "unknown", q->count);
return -1;
}
@@ -594,7 +594,7 @@ int queue_check_consistency(struct ll_queue* q) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': CYCLE detected! entry=%p count=%d",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': CYCLE detected! entry=%p count=%d",
q->name ? q->name : "unknown", (void*)slow, q->count);
abort();
}
@@ -610,7 +610,7 @@ int queue_check_consistency(struct ll_queue* q) {
actual_bytes += current->int_len;
if (current->next) {
if (current->next->prev != current) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': prev/next error at entry %p != %p entries: %d!=%d bytes: %zu!=%zu",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': prev/next error at entry %p != %p entries: %d!=%d bytes: %zu!=%zu",
q->name ? q->name : "unknown", (void*)current, (void*)current->next->prev, actual_count, q->count, actual_bytes, q->total_bytes);
return -1;
}
@@ -620,13 +620,13 @@ int queue_check_consistency(struct ll_queue* q) {
// Проверить хвост
if (q->tail && q->tail->next != NULL) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': tail error", q->name ? q->name : "unknown");
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': tail error", q->name ? q->name : "unknown");
return -1; // Хвост должен иметь next == NULL
}
// Сравнить с сохранёнными значениями
if (actual_count != q->count || actual_bytes != q->total_bytes) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': count error entries: %d!=%d or bytes: %zu!=%zu",
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "Queue '%s': count error entries: %d!=%d or bytes: %zu!=%zu",
q->name ? q->name : "unknown", actual_count, q->count, actual_bytes, q->total_bytes);
return -1;
}
@@ -678,7 +678,7 @@ int queue_waiter_wait(struct ll_queue* q, struct queue_waiter_handle* h,
struct queue_waiter* waiter = u_malloc(sizeof(struct queue_waiter));
if (!waiter) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] queue_waiter_wait: u_malloc failed", q->name);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] queue_waiter_wait: u_malloc failed", q->name);
return -1;
}
waiter->next = NULL;
@@ -705,7 +705,7 @@ void queue_waiter_cancel(struct ll_queue* q, struct queue_waiter_handle* h) {
curr = curr->next;
}
if (!curr) {
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "[%s] queue_waiter_cancel: waiter not in list", q->name);
DEBUG_ERROR(DEBUG_CATEGORY_SYS, "[%s] queue_waiter_cancel: waiter not in list", q->name);
h->internal = NULL;
return;
}
@@ -780,7 +780,7 @@ int queue_remove_data(struct ll_queue* q, struct ll_entry* entry) {
remove_from_hash(q, entry);
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_remove_data: removed entry %p (id=%u), count=%d", entry, entry->id, q->count);
// DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "queue_remove_data: removed entry %p (id=%u), count=%d", entry, entry->id, q->count);
#ifdef QUEUE_DEBUG
queue_check_consistency(q);// !!!! for debug
#endif