- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
49 lines
3.5 KiB
Markdown
49 lines
3.5 KiB
Markdown
# mem (Memory Wrappers с отслеживанием утечек)
|
||
|
||
## 1. Назначение
|
||
|
||
Обёртки над стандартными `malloc`/`calloc`/`realloc`/`free`/`strdup` с детекцией:
|
||
- **Buffer overflow/underflow** — каждый блок окружён канарейками (`0xDEADBEEF`) и padding-областями, которые проверяются при `u_free` и `u_realloc`. При повреждении — подробный дамп блока и аварийное завершение.
|
||
- **Double free** — двусвязный список всех живых аллокаций; повторное освобождение детектируется по отсутствию блока в списке.
|
||
- **Утечки памяти** — `u_report_unfreed_blocks()` при завершении выводит все незакрытые блоки с местом аллокации (`файл:строка`), размером и hex-дампом данных.
|
||
|
||
Функции потокобезопасны (мьютекс/критическая секция).
|
||
|
||
## 2. Как пользоваться
|
||
|
||
```c
|
||
#include "mem.h"
|
||
|
||
// Вместо malloc/calloc/realloc/free/strdup используй соответствующие макросы:
|
||
void* buf = u_malloc(data_size);
|
||
char* str = u_strdup("hello");
|
||
buf = u_realloc(buf, new_size);
|
||
u_free(buf);
|
||
u_free(str);
|
||
|
||
// В конце main (перед return) — отчёт о незакрытых блоках:
|
||
u_report_unfreed_blocks();
|
||
|
||
// Текущее число живых аллокаций (для диагностики):
|
||
size_t count = u_get_allocated_count();
|
||
```
|
||
|
||
**Важно:**
|
||
- Макросы (`u_malloc`, `u_calloc`, `u_free`, и т.д.) автоматически подставляют `__FILE__:__LINE__` через `LOCATION` — это нужно для диагностики утечек и повреждений. Напрямую вызывай `_impl`-функции только если нужно явно передать location.
|
||
- `u_realloc(NULL, size)` эквивалентен `u_malloc(size)`, `u_realloc(ptr, 0)` эквивалентен `u_free(ptr)`.
|
||
- Потокобезопасность гарантирована, но аллокации с метаданными заметно дороже обычного `malloc` — используй `memory_pool` для hot-path объектов.
|
||
- При обнаружении повреждения (overflow/underflow/double-free) программа завершается через `exit(EXIT_FAILURE)` после вывода отладочной информации.
|
||
|
||
## 3. API
|
||
|
||
| Функция/макрос | Описание |
|
||
|---|---|
|
||
| `u_malloc(size)` | Аналог `malloc` с boundary check и трекингом |
|
||
| `u_calloc(nmemb, size)` | Аналог `calloc` (выделяет + обнуляет) |
|
||
| `u_realloc(ptr, size)` | Аналог `realloc`, с проверкой целостности старого блока |
|
||
| `u_free(ptr)` | Освобождение с проверкой canary, double-free и удалением из списка |
|
||
| `u_strdup(s)` | Аналог `strdup` через u_malloc |
|
||
| `u_report_unfreed_blocks()` | Выводит все незакрытые блоки с дампом; вызывается при shutdown |
|
||
| `u_get_allocated_count()` | Возвращает количество живых аллокаций |
|
||
| `u_check(ptr, text, location)` | Ручная проверка целостности блока (canary + padding) |
|