![]() |
![]() |
|
|
mi
Author / Автор: Сергей Сацкий
|
![]() |
![]() |
Запуск mi с тестовым примером:
satsky.homelinux.com:~> ./mi.py ./test/test-bad-lock-order-elf
Test (improper lock order, elf) t0: m1.lock -> m2.lock -> m3.lock -> m3.unlock -> m2.unlock -> m1.unlock
t1: m1.lock -> m3.lock -> m2.lock -> m2.unlock -> m3.unlock -> m1.unlock
|
В результате работы mi создается файл протокола:
satsky.homelinux.com:~> ll mi.log -rw-rw-r-- 1 guest guest 4411 2010-01-31 20:54 mi.log |
Теперь можно запустить скрипт, анализирующий протокол работы:
swift@satsky.homelinux.com:~> ./statmi.py
Execution environment:
application: /home/guest/test/test-bad-lock-order-elf
log file: /home/guest/mi.log
libpthread.so path: /lib64/libpthread.so.0
do not print stack trace
Number of threads: 3
Number of mutexes: 4
Successfull operations: 56
Failed operations: 0
Collecting chains and statistics...
Threads legend:
t0 -> 140209742624528
t1 -> 140209742620944
t2 -> 140209732131088
Mutexes legend:
m0 -> 0x310baf7040
m1 -> 0x6013c0
m2 -> 0x601400
m3 -> 0x601440
--- E000 -- t2: m3 -> m2 -- t1: m2 -> m3
ERROR: potential dead lock detected
Thread t2 lock stack:
Operation: lock Object: 0x601400(m2) Thread: 140209732131088(t2) Return code: 0 Clocks: 0
Operation: lock Object: 0x601440(m3) Thread: 140209732131088(t2) Return code: 0 Clocks: 0
Operation: lock Object: 0x6013c0(m1) Thread: 140209732131088(t2) Return code: 0 Clocks: 0
Thread t1 lock stack:
Operation: lock Object: 0x601440(m3) Thread: 140209742620944(t1) Return code: 0 Clocks: 0
Operation: lock Object: 0x601400(m2) Thread: 140209742620944(t1) Return code: 0 Clocks: 0
Operation: lock Object: 0x6013c0(m1) Thread: 140209742620944(t1) Return code: 0 Clocks: 0
--- E000
|
Каждое сообщение об ошибке обрамляется выводом строк, начинающихся с трех тире:
--- E000 -- t2: m3 -> m2 -- t1: m2 -> m3 . . . --- E000 |
Символ E означает, что это ошибка. Символ W используется для предупреждений. Далее следует трехзначный номер ошибки.
В заголовке ошибки кратко описывается смысл ошибки. Запись:
t2: m3 -> m2 -- t1: m2 -> m3 |
следует читать так – поток t2 выполнил захват мьютекса m3, а затем мьютекса m2; поток t1, в свою очередь, выполнил захват мьютекса m2, а затем мьютекса m3.
Подробная информация об ошибке содержит информацию о порядке захвата мьютексов каждым из потоков. Порядок захвата мьютексов указывается в обратном хронологическом порядке, то есть сначала следует мьютекс, захваченный последним.
Более подробную информацию, включающую стек вызова функций для каждой операции захвата мьютексов, можно получить, если утилита mi запущена с опцией --option stack, например:
satsky.homelinux.com:~mi> ./mi.py --option stack ./test/test-bad-lock-order-elf
Test (improper lock order, elf) t0: m1.lock -> m2.lock -> m3.lock -> m3.unlock -> m2.unlock -> m1.unlock
t1: m1.lock -> m3.lock -> m2.lock -> m2.unlock -> m3.unlock -> m1.unlock
|
И затем:
satsky.homelinux.com:~> ./statmi.py
Execution environment:
application: /home/guest/test/test-bad-lock-order-elf
log file: /home/guest/mi.log
libpthread.so path: /lib64/libpthread.so.0
print stack trace
Number of threads: 3
Number of mutexes: 4
Successfull operations: 56
Failed operations: 0
Collecting chains and statistics...
Threads legend:
t0 -> 140490701883152
t1 -> 140490701879568
t2 -> 140490691389712
Mutexes legend:
m0 -> 0x310baf7040
m1 -> 0x6013c0
m2 -> 0x601400
m3 -> 0x601440
--- E000 -- t2: m3 -> m2 -- t1: m2 -> m3
ERROR: potential dead lock detected
Thread t2 lock stack:
Operation: lock Object: 0x601400(m2) Thread: 140490691389712(t2) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x400a57]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
Operation: lock Object: 0x601440(m3) Thread: 140490691389712(t2) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x400a4d]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
Operation: lock Object: 0x6013c0(m1) Thread: 140490691389712(t2) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x400a43]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
Thread t1 lock stack:
Operation: lock Object: 0x601440(m3) Thread: 140490701879568(t1) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x4009fe]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
Operation: lock Object: 0x601400(m2) Thread: 140490701879568(t1) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x4009f4]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
Operation: lock Object: 0x6013c0(m1) Thread: 140490701879568(t1) Return code: 0 Clocks: 0
Backtrace:
/home/guest/test/test-bad-lock-order-elf [0x4009ea]
/lib64/libpthread.so.0 [0x310640685a]
/lib64/libc.so.6 : clone()+0x6d
--- E000
|
Стеки вызовов функций для каждой операции захвата мьютекса печатаются в обратном хронологическом порядке, аналогично стеку захвата мьютексов.
mi использует следующие пакеты:
Для сборки библиотеки, перехватывающей вызовы pthread_mutex_zzz(...) запустите:
make love |
mi не требует никакой специальной установки. Просто скопируйте файлы mi (libmi.so, mi.py, statmi.py) в то место, где вы хотите их хранить.
Может быть имеет смысл сделать символические ссылки и подправить переменную PATH соответствующим образом.
mi тестировалась на Fedora 11.
Чтобы получить справку, наберите:
./mi.py –help |
mi-0.0.1.tar.bz2 (13610 байт)
Changelog (07-Feb-2010):
Вопрос: как запустить mi, если проверяемая программа запускается из скрипта?
Ответ: необходимо указать путь к libpthread.so с помощью ключа --pthread в момент запуска mi.py, например:
satsky.homelinux.com:~> ./mi.py --pthread /lib/libpthread-2.10.2.so my_prog.sh |
Вопрос: нужны ли дополнительные шаги для проверки программы-демона?
Ответ: нет. Запуск демона осуществляется так же, как и обычной программы. Однако до запуска statmi.py необходимо дождаться завершения работы демона.
Вопрос: какие коды возврата у statmi.py?
Ответ: 0 – в случае отсутствия ошибок и предупреждений. 1 – в случае, если есть хотя бы одно предупреждение и ни одной ошибки в проверяемой программе. 2 – в случае, если есть по крайней мере одна ошибка в проверяемой программе. 3 – в случае ошибок выполнения statmi.py.
Вопрос: statmi.py выводит информацию о мьютексах, которых нет в моей программе. Это ошибка mi?
Ответ: нет. Окружение времени выполнения может использовать мьютексы для внутренних целей и mi регистрирует активность с этими мьютексами. Обычно эти мьютексы отличаются диапазоном адресов (см. мьютекс m0 в примере сеанса работы с mi) и действия с ними заканчиваются до начала действий с мьютексами проверяемой программы.
mi разрабатывалась для развлечения, хотя преследовались и другие цели:
Утилита mi не закончена. Если она вам понравилась и вы хотите помочь ее улучшить – добро пожаловать!