Брутальный heap trace: узнай, какая сволочь запорола кучу
Добавлено: 10.07.2014 10:31:59
- Замедляет работу программы страшно (я об эффективности этой приблуды особо не заботился)
- Это *сырец* который будет ещё допиливаться (в тестовом примере не выдаются номера строк, только голые адреса, lineinfo не работает почему-то)
- НЕ совместимо с многими алгоритмами (мне пришлось в одном месте один парсинг переделывать чтобы работал дважды: на первом проходе выяснялось число элементов, а на втором - заполнялся массив. Иначе SetLength(x, Length(x) + 1) моментально съедали 800 мегабайт)
Но оно работает, и номера строк отображаются в моём игровом движке (далеко не для всех адресов, блджад! ), что уже позволило выгрести два куска *страшного* говнокода, от которого всё падало (в частности, шла работа с уничтоженным экземпляром класса).
Принципы
- Блоки памяти и информация об аллокации хранятся раздельно, на растоянии в несколько сот мегабайт. Запарывание кучи не убьёт сам менеджер памяти.
- Вокруг блоков оставляются широкие поля, заполненные $55.
- Освобождённые блоки памяти на самом деле никуда не освобождаются, а хранятся вечно, с бектрейсом кто освободил и контрольной суммой. Если у вас идёт добавление к массиву по элементику - исчерпание памяти гарантировано.
- любые некорректные операции с памятью обнаруживаются и подробно журналятся
- периодически, при выходе или по команде выполняет проверку всех блоков памяти: не насрал ли кто на защитные поля, не изменилась ли контрольная сумма освобождённых блоков, и т.п.
- может затирать все освобождённые блоки памяти $55, чтобы программа громко падала при работе с ними.
- Это *сырец* который будет ещё допиливаться (в тестовом примере не выдаются номера строк, только голые адреса, lineinfo не работает почему-то)
- НЕ совместимо с многими алгоритмами (мне пришлось в одном месте один парсинг переделывать чтобы работал дважды: на первом проходе выяснялось число элементов, а на втором - заполнялся массив. Иначе SetLength(x, Length(x) + 1) моментально съедали 800 мегабайт)
Но оно работает, и номера строк отображаются в моём игровом движке (далеко не для всех адресов, блджад! ), что уже позволило выгрести два куска *страшного* говнокода, от которого всё падало (в частности, шла работа с уничтоженным экземпляром класса).
Принципы
- Блоки памяти и информация об аллокации хранятся раздельно, на растоянии в несколько сот мегабайт. Запарывание кучи не убьёт сам менеджер памяти.
- Вокруг блоков оставляются широкие поля, заполненные $55.
- Освобождённые блоки памяти на самом деле никуда не освобождаются, а хранятся вечно, с бектрейсом кто освободил и контрольной суммой. Если у вас идёт добавление к массиву по элементику - исчерпание памяти гарантировано.
- любые некорректные операции с памятью обнаруживаются и подробно журналятся
- периодически, при выходе или по команде выполняет проверку всех блоков памяти: не насрал ли кто на защитные поля, не изменилась ли контрольная сумма освобождённых блоков, и т.п.
- может затирать все освобождённые блоки памяти $55, чтобы программа громко падала при работе с ними.
- Код: Выделить всё
Cheb's Brutal Heap Tracer started.
A change in a DEALLOCATED memory block detected
Before:
$0040B018 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0040A19A (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0040A7B8 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$00450AE0, line 457 of \cl_main.inc in D:\chentrah\chentrah.exe
$0045040F, line 380 of \cl_main.inc in D:\chentrah\chentrah.exe
$0040191D, line 99 of \chentrah.lpr in D:\chentrah\chentrah.exe
$0040EAD1 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
After:
$0040B018 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$00453944, line 119 of \cl_log.inc in D:\chentrah\chentrah.exe
$004233AC, line 787 of \cge.pp in D:\chentrah\chentrah.exe
$00450AB7, line 454 of \cl_main.inc in D:\chentrah\chentrah.exe
$0045040F, line 380 of \cl_main.inc in D:\chentrah\chentrah.exe
$0040191D, line 99 of \chentrah.lpr in D:\chentrah\chentrah.exe
$0040EAD1 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
Memory block #128140:
Size: 80
Allocated by:
$0040AFE2 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0044FBE8, line 240 of \cl_main.inc in D:\chentrah\chentrah.exe
$0040191D, line 99 of \chentrah.lpr in D:\chentrah\chentrah.exe
$0040EAD1 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
Freed by:
$0040B018 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$00408A92 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0045040F, line 380 of \cl_main.inc in D:\chentrah\chentrah.exe
$0040191D, line 99 of \chentrah.lpr in D:\chentrah\chentrah.exe
$0040EAD1 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0040B018 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0040A19A (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$0040A7B8 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe
$00450AE0, line 457 of \cl_main.inc in D:\chentrah\chentrah.exe
$0045040F, line 380 of \cl_main.inc in D:\chentrah\chentrah.exe
$0040191D, line 99 of \chentrah.lpr in D:\chentrah\chentrah.exe
$0040EAD1 (no debug info: doesn't include this address range) in D:\chentrah\chentrah.exe