Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Большинство других библиотек поддерживают совместимость, включая номер версии в имя библиотеки и позволяя множеству разных версий быть установленными одновременно. Например, инструментальные наборы GTK+ 1.2 и GTK+ 2.0 могут быть одновременно установлены в одной системе, каждый со своим собственным набором заголовочных и библиотечных файлов, путем встраивания в путь к заголовочным файлам и файлам библиотек имени версии.

Раздел стандарта по наименованию разделяемых библиотек в Linux включает старший номер версии для возможности установки в системе множества версий библиотеки. Это используется не очень часто, поскольку в одной системе невозможно скомпоновать новые приложения с множеством версий библиотеки; это просто обеспечивает поддержку лишь обратной совместимости для

существующих приложений, построенных на более старых системах. На практике разработчикам требуется собирать приложения со многими версиями одной и той же библиотеки, поэтому большинство основных библиотек содержат в своем названии и номер версии.

Глава 7

Средства отладки использования памяти

Несмотря на то что С бесспорно является стандартным языком программирования в системах Linux, он имеет ряд особенностей, не дающих программистам возможности писать код, не содержащий тонких ошибок, которые впоследствии очень сложно отладить. Утечки памяти (когда память, выделенная с помощью

malloc
, никогда не освобождается посредством
free
) и переполнение буфера (например, запись за пределы массива) — наиболее распространенные и трудные для обнаружения программные ошибки. Недогрузка буфера (вроде записи перед началом массива) — менее распространенное, но обычно еще более тяжелое для отслеживания явление. В этой главе представлены несколько средств отладки, которые могут значительно упростить обнаружение и изоляцию упомянутых проблем.

7.1. Код, содержащий ошибки

 1: / * broken.с* /

 2:

 3: #include <stdlib.h>

 4: #include <stdio.h>

 5: #include <string.h>

 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] . Для каждого класса памяти эта тестовая программа выполняет запись за пределами зарезервированной области памяти (по одному байту) и также сохраняет байт непосредственно перед зарезервированной областью. К тому же в коде имеется утечка памяти, что позволит продемонстрировать, как с помощью различных средств отследить эти утечки.

9

К сожалению, ни одно из средств, описанных в этой главе, не может отследить ошибки в памяти, связанные с глобальными переменными; для этого нужна помощь компилятора. В первом издании этой книги рассматривался инструмент под названием Checker, который представлял собой модифицированную версию компилятора

gcc
, однако он больше не поддерживается. К официальному компилятору
gcc
добавлена новая технология под названием mudflap, которая описана в текущем руководстве по
gcc
.

Несмотря на то что в представленном коде кроется много проблем, в действительности, он работает нормально. Не означает ли это, что проблемы подобного рода не важны? Ни в коем случае! Переполнение буфера часто приводит к неправильному поведению программы задолго до фактического его переполнения, а утечки памяти в программах, работающих длительное время, приводят к пустой растрате ресурсов компьютера. Более того, переполнение буфера является классическим источником уязвимостей безопасности, как описано в главе 22.

Ниже показан пример выполнения программы.

$ gcc -Wall -о broken broken.с

$ ./broken

1: 12345

2: 12345678

3: 12345678

4: 12345

5: 12345

6: 12345

7: 12345

7.2. Средства проверки памяти, входящие в состав

glibc

Библиотека GNU С (

glibc
) предлагает три простых средства проверки памяти. Первые два —
mcheck
и
MALLOC_CHECK_
— вызывают проверку на непротиворечивость структуры данных кучи, а третье средство —
mtrace
— выдает трассировку распределения и освобождения памяти для дальнейшей обработки.

7.2.1. Поиск повреждений кучи

Когда память распределяется в куче, функциям управления памятью необходимо место для хранения информации о распределениях. Таким местом является сама куча; это значит, что куча состоит из чередующихся областей памяти, которые используются программами и самим функциями управления памятью. Это означает, что переполнения или недополнение буфера может фактически повредить структуру данных, которую отслеживают функции управления памятью. В такой ситуации есть много шансов, что сами функции управления памятью, в конце концов, приведут к сбою программы.

Поделиться:
Популярные книги

Эпоха Опустошителя. Том I

Павлов Вел
1. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том I

Проблема майора Багирова

Майер Кристина
1. Спецназ
Любовные романы:
современные любовные романы
6.60
рейтинг книги
Проблема майора Багирова

Законы Рода. Том 13

Андрей Мельник
13. Граф Берестьев
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 13

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

О, Путник!

Арбеков Александр Анатольевич
1. Квинтет. Миры
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
О, Путник!

Прометей: каменный век

Рави Ивар
1. Прометей
Фантастика:
альтернативная история
6.82
рейтинг книги
Прометей: каменный век

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Цвет сверхдержавы - красный. Трилогия

Симонов Сергей
Цвет сверхдержавы - красный
Фантастика:
попаданцы
альтернативная история
8.06
рейтинг книги
Цвет сверхдержавы - красный. Трилогия

Болтливый мертвец

Фрай Макс
7. Лабиринты Ехо
Фантастика:
фэнтези
9.41
рейтинг книги
Болтливый мертвец

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Лишняя дочь

Nata Zzika
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Лишняя дочь