Когда что-то случается с вашей ОС, вы можете попробовать продиагностировать её с помощью разных утилит, входящих в её состав. Знание этих утилит и спрособов их эффективного использования поможет вам решить множество общих проблем. Вот список некоторых утилит: Strace, ltrace, lsof, top, Traceroute, ping, hexdump. О них будет рассказано в этой статье.
Strace
Иногда приложение, которое вы успешно откомпилировали выдает ошибку во время работы. Если повезет, то сообщение об ошибке может содержать детали о том, что пошло не так. Но обычно этого не происходит. Обычно сообщение об ошибке слабо помогает в поиске её причины.
Strace может помочь в этой ситуации. Эта утилита отслеживает системные вызовы программы во время её исполнения. Системный вызов - это функция ядра Linux, котрая обеспечивает безопасный доступ к системмным ресурсам, таким как память, диск или сеть.
Strace легко использовать - просто передайте ей имя приложения, которое надо выполнить в качестве аргумента. Для примера узнаем что выдаст утилита для программы "Hello, world!":
#include
int main()
{
printf("Hello, world!\n");
return 0;
}
$gcc -o hello hello.c
$strace ./hello
execve("./hello", ["./hello"], [/* 94 vars */]) = 0
brk(0) = 0x804b000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7eff000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/tls/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/tls/i686/sse2", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/tls/i686", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/tls/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/tls/sse2", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/tls", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/i686/sse2", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/i686", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib/sse2", 0xbf91d630) = -1 ENOENT (No such file or directory)
open("/opt/wx/2.8/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/opt/wx/2.8/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=186839, ...}) = 0
mmap2(NULL, 186839, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7ed1000
close(3)
= 0 open("/lib/libc.so.6", O_RDONLY) = 3
.
.
.
write(1, "Hello, world!\n", 14Hello, world!
) = 14
exit_group(0) = ?
Process 6006 detached
В этом выводе вы можете видеть как работает программа, производя системные вызовы pen, read, write, close и т.д. Обратите внимание, что здесь много неудачных вызовов открытия библиотеки libc.so.6. Это произошло из-за того, что линкер искал эту библиотеку в разных местах. Успешный вызов открытия этой библиотеки произошел, когда линкер нашел её в /lib, как показано в строке, выделенной жирным шрифтом. Системный вызов вернул значение "3", что означает, что операция открытия прошла успешно. Если бы мы могли заставить программу искать сначала в /lib, то не было бы необходимости делать много лишних вызовов. Мы можем это сделать, добавив строку /lib в начало переменной окружения LD_LIBRARY_PATH, которая используется линкером для поиска библиотек, необходимых для выполнения программы.
$export LD_LIBRARY_PATH=/lib
Вывод strace может быть громоздким при выводе в консоль. Часто перенаправляют его в текстовый файл, используя опцию "-o". Другая часто используемая опция - "-p", или PID, которая позволяет соединиться с выполняющейся программой и посмотреть её вывод. Это полезно случае демонов, которые нельзя легко перезапустить, или которые необходимо контролировать очень редко.
Хороший пример использования strace описан пользователем, который установил кодеки, включая libdvdcss, позволяющие ему проигрывать защищенные DVD. Но когда он их использовать, то получил странную ошибку. Запустив DVD плеера с помощью strace, он выяснил, что линкер искал установленные кодеки не в том месте. После копирования их в директорию, в которой линкер мог их найти, он смог запустить плеер и посмотреть свои DVD.
ltrace
ltrace - приложени, похожее на strace. Она работает также, но вместо обработки системных вызовов, она обрабатывает вызовы динамических библиотек. Запустим с помощью ltrace программу "Hello, world!". Получим следующий вывод:
$ltrace ./hello
__libc_start_main(0x80483b4, 1, 0xbfacb0d4, 0x80483f0, 0x80483e0
puts("\001"Hello, world!
) = 14
+++ exited (status 0) +++
Вывод показывает, что программа использует только одну функцию библиотеки, которая называется "puts" и используется для вывода строки "Hello, world!\n" в консоль.
ltrace используется не так часто как strace. Её используют, когда требуется детальная трассировка программы, особенно когда когда интересуются деталями функций динамической библиотеки, используемых программой, таких как malloc(), gethostbyname() и setenv().
lsof
утилита lsof используется для показа списка всех открытых файлов. Помните, что по идеологии Unix, почти все является файлом. Вы обращаетесь к оборудованию, используя файлы, расположенные в /dev, информация о процессоре, памяти и других устройствах находится в файлах, расположенных в /proc, а сетевые подключения (сокеты) также иногда представляют собой файлы.
lsof часто используется, когда вы хотите узнать какие файлы открыл процесс, или какие процессы используют файл:
$lsof
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,1 4096 2 /
init 1 root rtd DIR 8,1 4096 2 /
init 1 root txt REG 8,1 533224 1658100 /sbin/init
init 1 root 10u FIFO 0,14 2941 /dev/initctl
migration 2 root cwd DIR 8,1 4096 2 /
migration 2 root rtd DIR 8,1 4096 2 /
lsof выдает список запущенных команд, их идентификаторов процессов (PID), пользователей, которым процессы принадлежат, дескрипторов открытых файлов, типов открытых файлов, главных и дополнительных номеров файлов устройств, размеров файлов, номеров узлов, имен открытых файлов или точек монтирования устройств.
Что бы вывести список файлов, открытых процессом определенного пользователя, выполните следующую команду:
$lsof -u user
Что бы вывести список файлов, открытых отдельным процессом, выполните следующую команду:
$lsof -p pid
Иногда не получается отмонтировать устройство, так как система сообщает, что оно занято, даже если вы думаете что оно не используется никаким процессом. Чтоюы посмотреть, какой процесс его использует, выполните следующую команду:
$lsof /dev/mount-point
Она выдаст список процессов, использующих устройство. Завершите процессы и можете отмонтировать устройство.
top
Top выводит список основных процессов, запущеных в системе в определенное время. Критерием служет использование процессора, памяти и т.д.
$top
top - 18:21:33 up 1:40, 4 users, load average: 0.30, 0.21, 0.27
Tasks: 155 total, 2 running, 148 sleeping, 0 stopped, 5 zombie
Cpu(s): 6.9%us, 2.7%sy, 0.0%ni, 80.5%id, 9.6%wa, 0.1%hi, 0.1%si, 0.0%st
Mem: 506908k total, 492384k used, 14524k free, 12900k buffers
Swap: 1052248k total, 39836k used, 1012412k free, 144944k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 15 0 744 124 80 S 0 0.0 0:01.37 init
2 root RT 0 0 0 0 S 0 0.0 0:00.00 migration/0
3 root 34 19 0 0 0 S 0 0.0 0:00.00 ksoftirqd/0
4 root RT 0 0 0 0 S 0 0.0 0:00.00 migration/1
5 root 34 19 0 0 0 S 0 0.0 0:00.00 ksoftirqd/1
Утилита top полезна, когда вы хотите узнать какой процесс сколько ресурсов системы использует. В частности, если процесс использует слишком много памяти, вы можете обнаружить его в верху списка и предпринять необходимые действия, чтобы уменьшить использование памяти.
Traceroute
Traceroute - утилита, для устранения проблем с сетью. Сетевым пакетам, посланным с вашего компьютера на удаленный необходимо пройти через различные маршрутизаторы. Иногда компьютеры не могут передавать данные друг другу из-за того что пакеты пропадают где-то между ними. Чтобы остледить где пакеты пропадают используется утилита traceroute:
$traceroute google.com
Hop (ms) (ms) (ms) IP Address Host name
1 0 0 0 66.98.244.1 gphou-66-98-244-1.ev1servers.net
2 0 1 0 66.98.241.16 gphou-66-98-241-16.ev1servers.net
.
.
.
13 29 28 28 72.14.232.57 -
14 34 35 36 64.233.175.42 -
15 28 28 29 64.233.167.99 py-in-f99.google.com
Вывод показывает, что пакеты проходят через 15 различных машин по пути к google.com. Показывается список IP адресов и имен (если доступны) всех машин через которые проходит пакет.
ping
Ping может помочь, если вы хотите убедиться, что компьютер включен и подключен к сети. Ping посылает ICMP сообщения удаленному компьютеру и выводит полученные ответы. Иногда системные администраторы отключают ICMP сообщения на своих компьютерах, что означает, что ping не получит ответ от части компьютеров, даже если они есть в сети, так что убедитесь, что компьютер, который вас интересует отвечает на ICMP.
$ping google.com
PING google.com (72.14.207.99) 56(84) bytes of data.
64 bytes from eh-in-f99.google.com (72.14.207.99): icmp_seq=1 ttl=238 time=265 ms
64 bytes from eh-in-f99.google.com (72.14.207.99): icmp_seq=2 ttl=238 time=269 ms
64 bytes from eh-in-f99.google.com (72.14.207.99): icmp_seq=3 ttl=238 time=272 ms
64 bytes from eh-in-f99.google.com (72.14.207.99): icmp_seq=4 ttl=238 time=263 ms
hexdump
Утилита hexdump полезна для просмотра содержимого бинарного файла в удобном для чтения формате. Это может быть ASCII, шестнадцатиричный, восьмиричный или десятичный формат. Например, посмотрим содержимое файла /bin/ls в шестнадцатиричном и ASCII формате:
$hexdump -C /bin/ls
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 80 9c 04 08 34 00 00 00 |............4...|
00000020 0c 5c 01 00 00 00 00 00 34 00 20 00 0a 00 28 00 |.\......4. ...(.|
00000030 1f 00 1e 00 06 00 00 00 34 00 00 00 34 80 04 08 |........4...4...|
00000040 34 80 04 08 40 01 00 00 40 01 00 00 05 00 00 00 |4...@...@.......|
.
.
.
Информация слева - это файл в шестнадцатиричных кодах, а текст между вертикальными черточками - его ASCII представление.
Hexdump полезна для поиска строки текста внутри исполняемого файла, которая может быть не доступна в исходном коде. Она может помочь найти определённое сообщение об ошибке и место, где она появляется в файле.
Заключение
Решение проблем в Linux - это искусство, но эти утилиты помогут вам научиться ему. Вы можете узнать детали использования утих утилит в соответствующих страницах помощи. Помните, что знание как использовать утилиту, не означает знания когда её использовать. Когда вы встретите различные проблемы и определите каким инструментом их можно решить, вы в конце концов овладеете искусством диагностики и решения проблем в Linux.
LilFox 2007-02-22 08:54:21 (#)
В качестве ping нужно использовать telnet напополам с traceroute'ом.. Для достижения нормальной эффективности :), точнее не забывать про них.