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

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

Мини-картинка

71 Код, содержащий ошибки / broken. с / include include include char global [5];

int broken(void){ char dyn; char local[5];

/ Для начала немного перезаписать буфер / dyn malloc (5); strcpy(dyn, "12345"); printf("1: %s\n", dyn); free(dyn);

/ Теперь перезаписать буфер изрядно / dyn malloc (5); strcpy(dyn, "12345678"); printf ("2: %s\n", dyn);

24 / Пройти перед началом выделенного с помощью malloc локального буфера / 25 (dyn1) \0 1;

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

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


Ведете ли вы блог?

Да
Нет
Планирую


Результаты опроса

Новостной блок