Вход/Регистрация
Linux: Полное руководство
вернуться

Аллен Питер В.

Шрифт:

Рис. 22.3. Программа KDbg

Программа KDbg понравилась мне еще тем, что позволяет удобно просматривать регистры, потоки, память, стек и прочее, имеющее непосредственное отношение к процессу отладки. Однако имейте в виду, что интерфейс KDbg сильно ограничивает возможности отладки, потому что позволяет выполнять лишь базовые функции.

Существуют и другие оболочки для отладчика gdb, например, DDD. Эта оболочка обладает чуть большими возможностями, чем KDbg, но все же она является лишь надстройкой над gdb. Оболочек много, a gdb — один. Вы можете выбрать оболочку на свой вкус, а я вообще предпочитаю gdb без всяких оболочек.

Рис. 22.4. Оболочка DDD

22.4. Трассировка системных вызовов

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

Проследить, какие системные вызовы использует наша программа, позволяет программа strace. Для ее установки нужно установить пакет strace.

Формат вызова команды strace следующий:

strace [-dffhiqrtttTvxx] [-acolumn] [-eexpr] ... [-ofile] [-ppid] ... [-sstrsize] [-uusername] [command | arg ...]]

Ключи программы перечислены в таблице 22.3.

Ключи командной строки strace Таблица 22.3

Ключ Назначение
– с Подсчитывать время, затраченное на каждый вызов и обработку ошибок. В конце трассировки будет представлен подробный отчет
– d Выводить отладочные сообщения самой программы strace на стандартный вывод ошибки
– f Трассировать дочерние процессы, созданные уже трассируемыми процессами
– ff Данная опция применятся только вместе с опцией -o имя_файла. Каждый трассируемый процесс будет записан в файл имя_файла.pid
– F Следовать вызовам vfork. Данную опцию нельзя использовать вместе с опцией -f
– h Вывести справку
– i Выводить указатель инструкции во время системного вызова
– q «Тихий режим». Подавляет вывод некоторых сообщений
– r Выводить относительную метку времени для каждого вызова
– t Перед каждой строкой выводить текущее время
– tt То же, что и -t, но будут выводиться также микросекунды
– T Показывать время, потраченное на системный вызов (то есть разницу между временем запуска и временем завершения вызова). Для каждого вызова
– v Получение дополнительной информации
– V Вывести номер версии strace
– X Выводить не-ASCII строки в шестнадцатеричном формате
– XX Выводить все строки в шестнадцатеричном формате
– a столбец Выровнять возвращаемые вызовами значения в указанном столбце (по умолчанию 40)
– e выражение Позволяет задать отслеживаемые события. За более подробной информацией обратитесь к справочной системе
– e trace=набор Определить набор отслеживаемых вызовов. Например, trace=open,close,read,write
– e trace=file Будут отслеживаться только вызовы для работы с файлами (open, stat, chmod, unlink и т.д.)
– e trace=process Отслеживаются вызовы для работы с процессами (fork, exec, wait и др.)
– e trace=network Отслеживаются сетевые вызовы
– e trace=signal Отслеживаются вызовы для работы с сигналами
– e trace=ipc Отслеживаются IPC-вызовы
– e abbrev=набор Сокращает вывод каждого члена структуры. Например, abbrev=all или abbrev=none
– e verbose=набор Различать структуры различных системных вызовов, по умолчанию verbose=all
– e raw=set Выводит не декодированные значения аргументов системных вызовов. Данный аргумент полезен, если вы не доверяете декодированию или хотите знать точное числовое представление аргумента
– e signal=набор Определяет набор трассируемых сигналов. По умолчанию signal=all. Вы можете использовать восклицательный знак для отрицания, например, signal=!SIGIO означает, что сигнал SIGIO не будет трассирован
– e read=набор Выполнять полный шестнадцатиричный и ASCII-дамп всех прочитанных вызовом read данных. Например, чтобы видеть все данные, поступающие через дескрипторы 2 и 7, введите read=2,7
– e write=набор То же, что и -e read, но только для записи
– o имя_файла Перенаправить вывод программы в указанный файл. Данный файл будет полезен для дальнейшего анализа трассировки
– p pid Присоединиться к процессу с PID=pid и начать трассировку
– s размер Установить максимальный размер строки (по умолчанию 32). Имена файлов не рассматриваются как строки, поэтому всегда будут напечатаны полностью
– S критерий Сортирует вывод гистограммы, которая выводится опцией -с, по заданному критерию: time (время), calls (вызовы), name (имя) и nothing (без сортировки)
– u имя_пользователя Запустить программу от имени указанного пользователя. Эта опция будет полезной, если вы, зарегистрировавшись как root, будете проверять корректность работы программы, если бы она была запущена под другим пользователем

Вы даже не можете себе представить, какие системные вызовы использует такая маленькая программка:

Листинг 22.2. Файл prog.с

#include <stdio.h>

int main {

 printf("Hello\n");

 return 0;

}

Откомпилируйте эту программу (

gcc -o prog prog.c
) и запустите strace:

$ strace prog

Вы увидите следующий вывод:

execve("./a.out", ["./а.out"], [/* 21 vars */]) = 0

uname((sys="Linux", node="localhost.localdomain", ...}) = 0

brk(0) = 0x80495b4

open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY) = 7

fstat64(7, {st_mode=S_IFREG|0644, st_size=31578, ...}) = 0

old_mmap(NULL, 31578, PROT_READ, MAP_PRIVATE, 7, 0) = 0x40014000

close(7) = 0

open("/lib/i686/libc.so.6", O_RDONLY) =7

read(7, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`u\1В4\0"..., 1024) = 1024

fstat64(7, {st_mode=S_IFREG|0755, st_size=1401027, ...}) = 0

old_mmap(0x42000000, 1264928, PROT_READ|PROT_EXEC, MAP_PRIVATE, 7, 0) = 0x42000000

mprotect(0x4212c000, 36128, PROT_NONE) = 0

old_mmap(0x4212c000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 7, 0x12c000) = 0x4212c000

old_mmap(0x42131000, 15648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x42131000

close(7) = 0

munmap(0x40014000, 31578) = 0

brk(0) = 0x80495b4

brk(0x80495e4) = 0x80495e4

brk(0x804a000) = 0x804a000

fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000

write(1, "Hello\n", 6) =6

munmap(0x40014000, 4096) = 0

_exit(0) = ?

Читать вызовы нужно так:

имя системного вызова = возвращаемое значение

В нашем случае мы вывели на консоль шесть символов, поэтому вызов write возвратит значение 6.

В случае, если системный вызов завершился неудачно (обычно код ошибки -1), программа strace выводит не только код, но и описание ошибки:

open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

  • Читать дальше
  • 1
  • ...
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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