Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"

Рис. 15.1. Адресное пространство Linux/Unix, включая специальные области
Первым пакетом отладки, реализовавшим эту схему, был Electric Fence. Electric Fence является вставляемым заместителем для
malloc()После компоновки программы с Electric Fence любой доступ за пределами выделенной памяти генерирует
SIGSEGV1 /* ch15-badmem1.с --- плохо обращается с памятью */23 #include <stdio.h>4 #include <stdlib.h>56 int main(int argc, char **argv)7 {8 char *p;9 int i;1011 p = malloc(30);1213 strcpy(p, "not 30 bytes");14 printf("p = <%s>n", p);1516 if (argc ==2) {17 if (strcmp(argv[1], "-b") == 0)18 p[42] = 'a'; /* коснуться за пределами границы */19 else if (strcmp(argv[1], "-f") == 0) {20 free(p); /* освободить память, затем использовать ее */21 p[0] = 'b';22 }23 }2425 /* освобождение (p); */2627 return 0;28 }Эта программа осуществляет простую проверку опций командной строки, чтобы решить, как вести себя плохо:
-b-fОдним из способов использования Electric Fence, способом, который гарантированно работает на различных системах Unix и GNU/Linux, является статическая компоновка с ним вашей программы. Затем программа должна быть запущена из отладчика. (Документация Electric Fence явно указывает, что Electric Fence не следует компоновать с двоичным файлом готового изделия.) Следующий сеанс демонстрирует эту процедуру и показывает, что происходит для обеих опций командной строки:
$ <b>cc -g ch15-badmem1.c -lefence -о ch15-badmem1</b> /* Откомпилировать; компоновка статическая */$ <b>gdb ch15-badmem1</b> /* Запустить из отладчика */GNU gdb 5.3...(gdb) <b>run -b</b> /* Попробовать опцию -b */Starting program: /home/arnold/progex/code/ch15/ch15-badmem1 -b[New Thread 8192 (LWP 28021)]Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <[email protected]>p = <not 30 bytes>Program received signal SIGSBGV, Segmentation fault.SIGSBGV: GDB prints where[Switching to Thread 8192 (LWP 28021)]0x080485b6 in main (argc=2, argv=0xbffff8a4) at ch15-badmem1.c:1818 p[42] = 'a'; /* коснуться за пределами границы */(gdb) <b>run -f</b> /* Теперь попробовать опцию -f */The program being debugged has been started already.Start it from the beginning? (y or n) <b>y</b> /* Да */Starting program: /home/arnold/progex/code/ch15/ch15-badmem1 -f[New Thread 8192 (LWP 28024)]Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <[email protected]>p = <not 30 bytes>Program received signal SIGSEGV, Segmentation fault. /* Снова SIGSEGV */[Switching to Thread 8192 (LWP 28024)]0x080485e8 in main (argc=2, argv=0xbffff8a4) at ch15-badmem1.c:2121 p[0] = 'b';На системах, которые поддерживают разделяемые библиотеки и переменную окружения
LD_PRELOADefenceefХотя мы не описали механизмы подробно, GNU/Linux (и другие системы Unix) поддерживают разделяемые (shared) библиотеки, особые версии библиотечных процедур, которые хранятся в одном файле на диске, вместо того, чтобы копироваться в каждый отдельный двоичный исполняемый файл программы. Разделяемые библиотеки экономят дисковое пространство и могут сохранить системную память, поскольку все программы, использующие разделяемые библиотеки, используют одну и ту же копию библиотеки в памяти. Платой за это является замедление загрузки программы, поскольку программу и разделяемую библиотеку нужно подключить друг к другу прежде, чем программа сможет начать выполнение. (Обычно это прозрачно для вас, пользователя.)
Переменная окружения
LD_PRELOADefmalloc()ef