Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
==30882== malloc/free: 2 allocs, 1 frees, 10 bytes allocated.
==30882== For a detailed leak analysis, rerun with: --leak-check=yes
==30882== For counts of detected ERRORS, rerun with: -v
==30882== ИТОГИ ПО ОШИБКАМ: 22 ошибки в 12 контекстах (подавлено: 0 из 0)
==30882== malloc/free: используются после завершения: 5 байт в 1 блоке.
==30882== malloc/free: 2 распределения, 1 освобождение, 10 байт распределено.
==30882== Для детального анализа утечек памяти запустите с: --leak-check=yes
==30882== Для подсчета обнаруженных ошибок запустите с: -v
Обратите внимание, что Valgrind нашел все, кроме глобального переполнения и недогрузки, и указал на ошибки более точно, нежели любое другое ранее описанное средство.
Имеется опция, позволяющая включить агрессивную проверку утечек памяти, при которой для каждого распределения находятся все доступные указатели, хранящие ссылку на эту память. Это более точный способ, поскольку часто в программе память распределяют, но в конце не освобождают, так как память в любом случае будет возвращена операционной системе после того, как программа завершится.
$ valgrind --leak-check=yes ./broken
...
==2292== searching for pointers to 1 not-freed blocks.
==2292== checked 5318724 bytes.
==2292== поиск указателей на 1 неосвобожденный блок.
==2292== проверено 5318724 байт.
==2292==
==2292== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2292== 5 байт в 1 блоке определенно потеряны в потерянной записи 1 из 1
==2292== at 0хЕС528В: malloc (vg_replace_malloc.с:153)
==2292== by 0x8048437: broken (broken.с:20)
==2292== by 0x804851F: main (broken.с:47)
==2292== by 0x126BAE: __libc_start_main (in /lib/libc-2.3.2.so)
==2292==
==2292== LEAK SUMMARY:
==2292== definitely lost: 5 bytes in 1 blocks.
==2292== possibly lost: 0 bytes in 0 blocks.
==2292== still reachable: 0 bytes in 0 blocks.
==2292== suppressed: 0 bytes in 0 blocks.
==2292== Reachable blocks (those to which a pointer was found) are not shown.
==2292== To see them, rerun with: --show-reachable=yes
==2292== ИТОГИ ПО УТЕЧКАМ:
==2292== определенно потеряно: 5 байт в 1 блоке.
==2292== возможно потеряно: 0 байт в 0 блоке.
==2292== пока достижимы: 0 байт в 0 блоке.
==2292== подавлено: 0 байт в 0 блоке.
==2292== Достижимые блоки (на которые найдены указатели) не показаны.
==2292== Чтобы увидеть их, запустите с: --show-reachable=yes
Инструмент Valgrind включает детализированную информацию по своим возможностям и поддерживает множество опций командной строки, которые модифицируют его поведение. Поскольку Valgrind использует эмулятор центрального процессора, программа в нем выполняется во много раз медленнее, чем обычно в системе. Точное замедление зависит от программы, однако Valgrind задумывался для интерактивных программ.
Valgrind могут слегка ввести в заблуждение программы, скомпилированные с высокими уровнями оптимизации. Если вы получаете отчет об ошибке памяти, которая не выглядит осмысленно, попробуйте перекомпилировать программу с -О
вместо -O2
(или выше) и сгенерировать новый отчет.
7.5. Electric Fence
Следующее средство, которое мы рассмотрим — это Electric Fence (доступен на ftp://sunsite.unc.edu/pub/Linux/devel/lang/c и во многих дистрибутивах). Несмотря на то что Electric Fence не обнаруживает утечки памяти, он очень помогает в изоляции переполнений буфера. Каждый современный компьютер (включая все машины, работающие под Linux) обеспечивают аппаратную защиту памяти. Linux этим пользуется для изоляции программ друг от друга (например, сеанс vi
не имеет доступа к памяти gcc
) и для безопасного разделения кода между процессами, делая его только для чтения. Системный вызов mmap()
в Linux (см. главу 13) позволяет процессу воспользоваться также аппаратной защитой памяти.
Electric Fence заменяет обычную функцию malloc()
библиотеки С версией, которая распределяет запрошенную память и (обычно) непосредственно после запрошенной выделяет фрагмент памяти, доступ к которой процессу не разрешен. Если процесс попытается получить доступ к этой памяти, ядро немедленно остановит его с выдачей ошибки сегментации. За счет такого распределения памяти Electric Fence обеспечивает уничтожение программы, если та предпримет попытку чтения или записи за границей буфера, распределенного malloc()
. Детальную информацию по использованию Electric Fence можно прочитать на его man-странице ( man libefence
).
7.5.1. Использование Electric Fence
Одна из наиболее примечательных особенностей Electric Fence заключается в простоте ее использования. Нужно всего лишь скомпоновать свою программу с библиотекой libefence.а
, указав -lefence
в качестве последнего аргумента. В результате код будет готов к отладке. Давайте посмотрим, что происходит при запуске тестовой программы с применением Electric Fence.
$ ./broken
Electric Fence 2.2.0 Copyright (C) 1987 - 1999 Bruce Perens.
1: 12345
Segmentation fault (core dumped)
Ошибка сегментации (дамп ядра сброшен)
Хотя Electric Fence непосредственно не указывает на место, где произошла ошибка, проблема становится намного очевидней. Можно легко и точно определить проблемный участок, запустив программу под управлением отладчика, например gdb
. Для того чтоб gdb
смог точно указать на проблему, соберите программу с отладочной информацией, указав для gcc
флажок -g
, затем запустите gdb
и зададите имя исполняемого файла, который нужно отладить. Когда программы уничтожается, gdb
точно показывает, в какой строке произошел сбой.
Вот как выглядит описанная процедура.
$ gcc -ggdb -Wall -о broken broken.с -lefence
$ gdb broken
...
(gdb) run
Starting program: /usr/src/lad/code/broken
Electric Fence 2.2.0 Copyright (C) 1987 - 1999 Bruce Perens.
1: 12345
Program received signal SIGSEGV, Segmentation fault.
Программа получила сигнал SIGSEGV, ошибка сегментации.
0х007948с6 in strcpy() from /lib/tls/libc.so.6
(gdb) where
#0 0x007948c6 in strcpy() from /lib/tls/libc.so.6
#1 0x08048566 in broken() at broken.c:21
#2 0x08048638 in main() at broken.c:47
(gdb)
Благодаря Electric Fence и gdb
, становится понятно, что в строке 21 файла broken.с
имеется ошибка, связанная со вторым вызовом strcpy()
.
7.5.2. Выравнивание памяти
Хотя инструмент Electric Fence очень помог в обнаружении второй проблемы в коде, а именно — вызова strcpy()
, переполнившего буфер, первое переполнение буфера найдено не было.
Проблему в этом случае нужно решать с помощью выравнивания памяти. Большинство современных компьютеров требуют, чтобы многобайтные объекты начинались с определенных смещений в оперативной памяти. Например, процессоры Alpha требуют, чтобы 8-байтовый тип — длинное целое ( long
) — начинался с адреса, кратного 8. Это значит, что длинное целое может располагаться по адресу 0x1000 или 0x1008, но не 0x1005 [11] Большинство традиционных систем Unix передают ошибку шины ( SIGBUS ) процессу, который пытается использовать невыровненные данные. Ядро Linux обрабатывает доступ к невыровненным данным так, чтобы процесс мог нормально продолжать работу, хотя за это приходится платить существенным снижением производительности.
.
Интервал:
Закладка: