Разработка приложений в среде Linux - [23]
>41: printf("7: %s\n", global);
>42:
>43: return 0;
>44: }
>45:
>46: int main (void) {
>47: return broken();
>48: }
В этой главе мы рассмотрим проблемы в показанном выше сегменте кода. Этот код разрушает три типа областей памяти: память, выделенную из динамического пула памяти (кучи) с помощью >malloc()
, локальные переменные размещенные в стеке программы и глобальные переменные, хранящиеся в отдельной области памяти, которая была статически распределена при запуске программы[9]. Для каждого класса памяти эта тестовая программа выполняет запись за пределами зарезервированной области памяти (по одному байту) и также сохраняет байт непосредственно перед зарезервированной областью. К тому же в коде имеется утечка памяти, что позволит продемонстрировать, как с помощью различных средств отследить эти утечки.
Несмотря на то что в представленном коде кроется много проблем, в действительности, он работает нормально. Не означает ли это, что проблемы подобного рода не важны? Ни в коем случае! Переполнение буфера часто приводит к неправильному поведению программы задолго до фактического его переполнения, а утечки памяти в программах, работающих длительное время, приводят к пустой растрате ресурсов компьютера. Более того, переполнение буфера является классическим источником уязвимостей безопасности, как описано в главе 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. Поиск повреждений кучи
Когда память распределяется в куче, функциям управления памятью необходимо место для хранения информации о распределениях. Таким местом является сама куча; это значит, что куча состоит из чередующихся областей памяти, которые используются программами и самим функциями управления памятью. Это означает, что переполнения или недополнение буфера может фактически повредить структуру данных, которую отслеживают функции управления памятью. В такой ситуации есть много шансов, что сами функции управления памятью, в конце концов, приведут к сбою программы.
Если вы установили переменную окружения >MALLOC_CHECK_
, выбирается другой, несколько более медленный набор функций управления памятью. Этот набор более устойчив к ошибкам и может обнаруживать ситуации, когда >free()
вызывается более одного раза для одного и того же указателя, а также когда происходят однобайтные переполнения буфера. Если >MALLOC_CHECK_
установлена в >0
, функции управления памятью просто более устойчивы к ошибкам, но не выдают никаких предупреждений. Если >MALLOC_CHECK_
установлена в >1
, функции управления памятью выводят предупреждения о стандартных ошибках при замеченной проблеме. Если >MALLOC_CHECK_
установлена в >2
, функции управления памятью вызывают >abort()
, когда замечают проблемы.
Установка >MALLOC_CHECK_
в >0
может оказаться полезной, если вам мешает найти ошибку в памяти другая ошибка, которую в этот момент исправить нет возможности; эта установка позволяет работать с другими средствами отслеживания ошибок памяти.
Установка >MALLOC_CHECK_
в >1
полезна в случае, когда никаких проблем не видно, поэтому определенные уведомления могут помочь.
Установка >MALLOC_CHECK_
в >2
наиболее полезна при работе в отладчике, поскольку при возникновении ошибки он позволяет выполнить обратную трассировку вплоть до функций управления памятью. В результате вы максимально приблизитесь к месту возникновения ошибки.
>$ MALLOC_CHECK_=1 ./broken
>malloc: using debugging hooks
>malloc: используются отладочные функции
>1: 12345
>free(): invalid pointer 0x80ac008!
>free(): недопустимый указатель 0x80ac008!
>2: 12345678
>3: 12345678
>4: 12345
>5: 12345
>6: 12345
>7: 12345
>$ MALLOC_CHECK_=2 gdb ./broken
>...
>(gdb) run
>Starting program: /usr/src/lad/code/broken
>Запуск программы: /usr/src/lad/code/broken
>1: 12345
>Program received signal SIGABRT, Aborted.
>Программа получила сигнал SIGABRT, прервана.
>0x00 с 64 с 32 in _dl_sysinfo_int80() from/lib/ld-linux.so.2
>(gdb) where
>#0 0x00c64c32 in _dl_sysinfo_int80() from /lib/ld-linux.so.2
>#1 0x00322969 in raise() from /lib/tls/libc.so.6
>#2 0x00324322 in abort() from /lib/tls/libc.so.6
>#3 0x0036d9af in free_check() from /lib/tls/libc.so.6
>#4 0x0036afa5 in free() from /lib/tls/libc.so.6
>#5 0x0804842b in broken() at broken.c:17
>#6 0x08048520 in main() at broken.с:47
Другой способ заставить >glibc
проверить кучу на непротиворечивость — воспользоваться функцией >mcheck()
:
>typedef void(*mcheck Callback)(enummcheck_status status);
>void mcheck(mcheck Callback cb) ;
В случае вызова функции >mcheck()
, функция >malloc()
размещает известные последовательности байтов перед и после возвращенной области памяти, чтобы можно было обнаружить переполнение или недогрузку буфера, >free()
ищет эти сигнатуры и, если они были повреждены, вызывает функцию, указанную аргументом
Одно из немногих изданий на русском языке, которое посвящено старейшей глобальной компьютерной сети "Fidonet". Сатирический справочник о жизни и смерти самого древнего сетевого сообщества, которое до сих пор существует среди нас.
В пособии излагаются основные тенденции развития организационного обеспечения безопасности информационных систем, а также подходы к анализу информационной инфраструктуры организационных систем и решению задач обеспечения безопасности компьютерных систем.Для студентов по направлению подготовки 230400 – Информационные системы и технологии (квалификация «бакалавр»).
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.Для программистов-пользователей операционной системы UNIX.
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса.
Применение виртуальных машин дает различным категориям пользователей — от начинающих до IT-специалистов — множество преимуществ. Это и повышенная безопасность работы, и простота развертывания новых платформ, и снижение стоимости владения. И потому не случайно сегодня виртуальные машины переживают второе рождение.В книге рассмотрены три наиболее популярных на сегодняшний день инструмента, предназначенных для создания виртуальных машин и управления ими: Virtual PC 2004 компании Microsoft, VMware Workstation от компании VMware и относительно «свежий» продукт — Parallels Workstation, созданный в компании Parallels.
Книга содержит подробные сведения о таких недокументированных или малоизвестных возможностях Windows XP, как принципы работы с программами rundll32.exe и regsvr32.exe, написание скриптов сервера сценариев Windows и создание INF-файлов. В ней приведено описание оснасток, изложены принципы работы с консолью управления mmc.exe и параметрами реестра, которые изменяются с ее помощью. Кроме того, рассмотрено большое количество средств, позволяющих выполнить тонкую настройку Windows XP.Эта книга предназначена для опытных пользователей и администраторов, которым интересно узнать о нестандартных возможностях Windows.