kmemleak: Memory leak detected — Поиск утечек памяти в ядре Linux
Архитектура ошибки и симптомы сбоя
Сообщение «kmemleak: Memory leak detected inside kernel subsystem» генерируется встроенным ядерным детектором утечек памяти Kernel Memory Leak Detector (kmemleak). Механизм kmemleak отслеживает все аллокации памяти через kmalloc(), kmem_cache_alloc(), vmalloc(). Если указатель на выделенный блок памяти теряется и на него больше не ссылается ни один живой указатель в ядре (Unreferenced Object), kmemleak фиксирует утечку невыгружаемой физической памяти (RAM) ядра и сохраняет точный стектрейс аллокатора.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| unreferenced object | Physical Memory Block | Блок памяти ядра, потерявший ссылки и не освобожденный через kfree(). |
| backtrace | Kernel Call Stack | Точная цепочка функций ядра и драйверов, выполнивших сбойную аллокацию. |
| Impact | Slow OOM / Host Freeze | Постепенное полное исчерпание физической RAM без отображения в процессах. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Просмотр обнаруженных утечек памяти в debugfs
# Монтирование debugfs (если не смонтирован):
sudo mount -t debugfs none /sys/kernel/debug
# Принудительный запуск сканирования памяти на утечки:
echo scan | sudo tee /sys/kernel/debug/kmemleak
# Просмотр детального отчета с адресами и backtrace функций:
sudo cat /sys/kernel/debug/kmemleakСценарий 2: Анализ стектрейса и локализация сбойного модуля ядра
Пример отчета kmemleak:
unreferenced object 0xffff8881234a5000 (size 256):
comm "modprobe", pid 1234, jiffies 4294967296 (age 120.450s)
backtrace:
[<ffffffff81234567>] kmalloc_trace+0x27/0x60
[<ffffffffa0123456>] my_faulty_driver_init+0x42/0x100 [my_driver]
[<ffffffff81002345>] do_one_initcall+0x45/0x200В данном случае утечка вызвана сторонним модулем my_driver в функции my_faulty_driver_init.
Сценарий 3: Очистка лога kmemleak после анализа
# Очистка текущего журнала детектированных объектов:
echo clear | sudo tee /sys/kernel/debug/kmemleakСценарий 4: Анализ кэшей SLAB/SLUB в реальном времени (если kmemleak выключен)
Если kmemleak не собран в ядре (требует CONFIG_DEBUG_KMEMLEAK=y), используйте утилиту slabtop:
# Мониторинг растущих ядерных кэшей:
sudo slabtop -s c
# Детальная статистика распределения Slab:
cat /proc/slabinfo | sort -n -k3 -r | head -n 15ITSTM проведет глубокое профилирование ядра Linux (Kmemleak / BPF kmalloc-tracer), локализует утечки в сторонних драйверах и оптимизирует распределение пулов SLUB.
Частые вопросы (FAQ)
Включен ли kmemleak по умолчанию в стандартных ядрах Ubuntu / RHEL?
Обычно нет. Из-за высоких накладных расходов на процессор и память (до 10-20% RAM) опция CONFIG_DEBUG_KMEMLEAK по умолчанию отключена в production-ядрах и активируется в debug-сборках (пакеты linux-image-*-dbg / kernel-debug).
Бывают ли у kmemleak ложные срабатывания (False Positives)?
Да. Если драйвер маскирует указатели (например, выполняет XOR-кодирование, упаковывает адреса в битовые поля или хранит указатели в аппаратуре устройства), kmemleak может посчитать такой живой объект утекшим.
Как отключить сканирование kmemleak на лету?
Выполните команду: echo off | sudo tee /sys/kernel/debug/kmemleak. Это остановит фоновый поток сканера и снизит нагрузку на CPU.
Чем kmemleak отличается от Valgrind / AddressSanitizer?
Valgrind и ASan предназначены для отладки приложений в пространстве пользователя (User Space). Механизм kmemleak встроен непосредственно в ядро Linux и работает исключительно с системной памятью Ring 0.