Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#include
int sethostname(const char * name, size_t len);
int setdomainname(const char * name, size_t len);
Оба этих системных вызова принимают указатель на строку (не обязательно завершающуюся NULL
), которая содержит подходящее имя, и целочисленный аргумент, указывающий размер строки.
6.3. Совместимость
Приложения, которые скомпилированы с заголовочными файлами из библиотеки glibc
и привязанные к одной из ее версий, будут работать и с более поздними версиями библиотеки. Эта обратная совместимостьобычно означает, что программисту не придется пересобирать свои приложения только из-за того, что выпущена новая версия glibc
.
Существуют практические ограничения для обратной совместимости. Во-первых, смешивание объектов из разных версий glibc
в одном исполняемом файле может иногда работать, но специально для такой совместимости ничего не предпринимается. Следует отметить, что это касается динамически загружаемых, а также статически связанных объектов. Во-вторых, приложение должно использовать только стандартные возможности glibc
. Приложение, которое зависит от побочных эффектов ошибок или основано на неопределенном поведении одной из версий glibc
, может не работать с более поздними версиями этой библиотеки. Приложение, компонуемое с приватными символами glibc
(обычно они имеют префикс а_
), также вряд ли будет работать с более новыми версиями glibc
.
Обратная совместимость поддерживается тогда, когда задействованы символы, разработанные специально для соответствия стандартам версий. Когда разработчики glibc
хотят внести несовместимое изменение в glibc
, они сохраняют оригинальную реализацию или пишут совместимую реализацию данного интерфейса и помечают его более старым номером версии glibc
. Затем они реализуют новый интерфейс (который может отличаться по семантике, сигнатуре или и тем, и другим) и помечают его новым номером версии glibc
. Приложения, построенные на базе старой версии glibc
, используют старый интерфейс, а приложения, построенные на основе новой версии — новый интерфейс.
Большинство других библиотек поддерживают совместимость, включая номер версии в имя библиотеки и позволяя множеству разных версий быть установленными одновременно. Например, инструментальные наборы GTK+ 1.2 и GTK+ 2.0 могут быть одновременно установлены в одной системе, каждый со своим собственным набором заголовочных и библиотечных файлов, путем встраивания в путь к заголовочным файлам и файлам библиотек имени версии.
Раздел стандарта по наименованию разделяемых библиотек в Linux включает старший номер версии для возможности установки в системе множества версий библиотеки. Это используется не очень часто, поскольку в одной системе невозможно скомпоновать новые приложения с множеством версий библиотеки; это просто обеспечивает поддержку лишь обратной совместимости для существующих приложений, построенных на более старых системах. На практике разработчикам требуется собирать приложения со многими версиями одной и той же библиотеки, поэтому большинство основных библиотек содержат в своем названии и номер версии.
Глава 7
Средства отладки использования памяти
Несмотря на то что С бесспорно является стандартным языком программирования в системах Linux, он имеет ряд особенностей, не дающих программистам возможности писать код, не содержащий тонких ошибок, которые впоследствии очень сложно отладить. Утечки памяти(когда память, выделенная с помощью malloc()
, никогда не освобождается посредством free()
) и переполнение буфера(например, запись за пределы массива) — наиболее распространенные и трудные для обнаружения программные ошибки. Недогрузка буфера(вроде записи перед началом массива) — менее распространенное, но обычно еще более тяжелое для отслеживания явление. В этой главе представлены несколько средств отладки, которые могут значительно упростить обнаружение и изоляцию упомянутых проблем.
7.1. Код, содержащий ошибки
1: / * broken.с* /
2:
3: #include
4: #include
5: #include
6:
7: char global[5];
8:
9: int broken(void){
10: char *dyn;
11: char local[5];
12:
13: /* Для начала немного перезаписать буфер */
14: dyn = malloc(5);
15: strcpy(dyn, "12345");
16: printf ("1: %s\n", dyn);
17: free(dyn);
18:
19: /* Теперь перезаписать буфер изрядно */
20: dyn = malloc(5);
21: strcpy(dyn, "12345678");
22: printf("2: %s\n", dyn);
23:
24: /* Пройти перед началом выделенного с помощью malloc локального буфера */
25: * (dyn-1) ='\0';
26: printf ("3: %s\n", dyn);
27: /* обратите внимание, что указатель не освобожден! */
28:
29: /* Теперь двинуться после переменной local */
30: strcpy(local, "12345");
31: printf ("4: %s\n", local);
32: local[-1] = '\0';
33: printf("5: %s\n", local);
34:
35: /* Наконец, атаковать пространство данных global */
36: strcpy(global, "12345");
37: printf ("6: %s\n", global);
38:
39: /* И записать поверх пространства перед буфером global */
40: global[-1] = '\0';
41: printf("7: %s\n", global);
42:
43: return 0;
44: }
45:
46: int main (void) {
47: return broken();
48: }
В этой главе мы рассмотрим проблемы в показанном выше сегменте кода. Этот код разрушает три типа областей памяти: память, выделенную из динамического пула памяти ( кучи) с помощью malloc()
, локальные переменные размещенные в стеке программы и глобальные переменные, хранящиеся в отдельной области памяти, которая была статически распределена при запуске программы [9] К сожалению, ни одно из средств, описанных в этой главе, не может отследить ошибки в памяти, связанные с глобальными переменными; для этого нужна помощь компилятора. В первом издании этой книги рассматривался инструмент под названием Checker, который представлял собой модифицированную версию компилятора gcc , однако он больше не поддерживается. К официальному компилятору gcc добавлена новая технология под названием mudflap, которая описана в текущем руководстве по gcc .
. Для каждого класса памяти эта тестовая программа выполняет запись за пределами зарезервированной области памяти (по одному байту) и также сохраняет байт непосредственно перед зарезервированной областью. К тому же в коде имеется утечка памяти, что позволит продемонстрировать, как с помощью различных средств отследить эти утечки.
Несмотря на то что в представленном коде кроется много проблем, в действительности, он работает нормально. Не означает ли это, что проблемы подобного рода не важны? Ни в коем случае! Переполнение буфера часто приводит к неправильному поведению программы задолго до фактического его переполнения, а утечки памяти в программах, работающих длительное время, приводят к пустой растрате ресурсов компьютера. Более того, переполнение буфера является классическим источником уязвимостей безопасности, как описано в главе 22.
Читать дальшеИнтервал:
Закладка: