Вы пробовали -fmudflap
с GCC? Это проверки во время выполнения, но они полезны, поскольку чаще всего вам все равно приходится иметь дело с вычисляемыми во время выполнения показателями. Вместо того, чтобы молча продолжать работать, он сообщит вам об этих ошибках.
-fmudflap -fmudflapth -fmudflapir
Для интерфейсов, которые его поддерживают (C и C ++), инструмент все рискованно
разыменование указателя / массива
операции, некоторые стандартные
строковые / кучевые функции библиотеки и некоторые другие связанные
конструирует с тестами диапазона / валидности.
Модули с инструментами
должен быть защищен от переполнения буфера, недопустимого использования кучи и некоторых
другие классы программирования C / C ++
ошибки. Инструмент
tation полагается на отдельную библиотеку времени выполнения (libmudflap), которая
будет связан с программой, если
-fmudflap дается по ссылке
время. Поведение инструментальной программы во время выполнения контролируется
средой MUDFLAP_OPTIONS
переменная. Смотри "env
MUDFLAP_OPTIONS = -help a.out "для его параметров.
Используйте -fmudflapth вместо -fmudflap для компиляции и компоновки, если ваша программа многопоточная. использование
-фмудфлапир, дополнительно
в -fmudflap или -fmudflapth, если инструментарий должен игнорировать чтение указателя. Это производит
меньше инструментов (и там
для более быстрого выполнения) и по-прежнему обеспечивает некоторую защиту от
откровенно искажает память пишет, но
позволяет ошибочно
читать данные для распространения в программе.
Вот то, что дает мне брызговик для вашего примера:
[js@HOST2 cpp]$ gcc -fstack-protector-all -fmudflap -lmudflap mudf.c
[js@HOST2 cpp]$ ./a.out
*******
mudflap violation 1 (check/write): time=1229801723.191441 ptr=0xbfdd9c04 size=56
pc=0xb7fb126d location=`mudf.c:4:3 (main)'
/usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7fb126d]
./a.out(main+0xb9) [0x804887d]
/usr/lib/libmudflap.so.0(__wrap_main+0x4f) [0xb7fb0a5f]
Nearby object 1: checked region begins 0B into and ends 16B after
mudflap object 0x8509cd8: name=`mudf.c:3:7 (main) a'
bounds=[0xbfdd9c04,0xbfdd9c2b] size=40 area=stack check=0r/3w liveness=3
alloc time=1229801723.191433 pc=0xb7fb09fd
number of nearby objects: 1
[js@HOST2 cpp]$
У него есть куча вариантов. Например, он может отключить процесс GDB при нарушениях, может показать вам, где произошла утечка вашей программы (используя -print-leaks
) или обнаружить неинициализированные чтения переменных. Используйте MUDFLAP_OPTIONS=-help ./a.out
, чтобы получить список опций. Поскольку mudflap выводит только адреса, а не имена файлов и строки источника, я написал небольшой скрипт gawk:
/^ / {
file = gensub(/([^(]*).*/, "\\1", 1);
addr = gensub(/.*\[([x[:xdigit:]]*)\]$/, "\\1", 1);
if(file && addr) {
cmd = "addr2line -e " file " " addr
cmd | getline laddr
print $0 " (" laddr ")"
close (cmd)
next;
}
}
1 # print all other lines
Передайте вывод грязевого потока в него, и он будет отображать исходный файл и строку каждой записи обратной трассировки.
Также -fstack-protector[-all]
:
-fstack-protector
Выдать дополнительный код для проверки переполнения буфера, например, атак с разбиванием стека. Это делается путем добавления переменной защиты к функциям с уязвимыми объектами. Это включает в себя функции, которые вызывают alloca, и функции с буферами, размер которых превышает 8 байтов. Защитные устройства инициализируются при входе в функцию, а затем проверяются при выходе из функции. Если контрольная проверка не пройдена, выводится сообщение об ошибке и программа завершается.
-fstack-protector-all
Аналогично -fstack-protector за исключением того, что все функции защищены.