Как я могу отладить Perl-программу, которая неожиданно завершает работу? - PullRequest
3 голосов
/ 09 июня 2010

У меня есть программа Perl, основанная на IO::Async, и она иногда просто завершается через несколько часов / дней без вывода какого-либо сообщения об ошибке. В dmesg или /var/log тоже ничего нет. STDOUT / STDERR оба autoflush(1), поэтому данные не должны быть потеряны в буферах. Это на самом деле не выходит из IO::Async::Loop->loop_forever - печать, которую я положил туда, просто чтобы убедиться, что это никогда не сработает.

Теперь одним из способов было бы напечатать программу все большим количеством отпечатков и надеяться, что один из них даст мне некоторую подсказку. Есть ли лучший способ получить информацию о том, что происходило в программе, которая заставляла его выходить / молча падать?

Ответы [ 3 ]

6 голосов
/ 09 июня 2010

Один из приемов, которые я использовал, - запуск программы под strace или ltrace (или присоединение к процессу с помощью strace). Естественно, это было под Linux. В других операционных системах вы бы использовали ktrace или dtrace или что-либо еще подходящее.

Хитрость, которую я использовал для программ, которые показывают только редкие проблемы в течение нескольких дней или недель, а затем только для нескольких сотен систем, заключается в том, чтобы направить вывод из моего трассировщика в FIFO, а пользовательская программа хранит только 10K строк в кольцевом буфере (и с обработчиком SIGPIPE и SIGHUP для выгрузки текущего содержимого буфера в файл. (Это простая программа, но у меня нет удобной копии, и я не собираюсь переписывать ее сегодня вечером ; моя копия была написана для внутреннего пользования и принадлежит бывшему работодателю).

Кольцевой буфер позволяет программе работать бесконечно, опасаясь запуска систем из дискового пространства ... нам обычно требуется всего несколько сотен, даже несколько тысяч строк трассировки в таких случаях.

3 голосов
/ 11 июня 2010

Если вы захватываете STDERR, вы можете запустить программу как perl -MCarp::Always foo_prog. Carp::Always вызывает трассировку стека для всех ошибок.

0 голосов
/ 16 мая 2012

Внезапный выход без какого-либо сообщения об ошибке, возможно, SIGPIPE.Традиционно SIGPIPE используется для остановки таких вещей, как команда cat в следующем конвейере:

cat file | head -10

Обычно это не приводит к тому, что что-либо печатается с помощью libc или perl для указаниячто случилось.

Поскольку в программе на основе IO::Async вы не хотите беззвучно выходить на SIGPIPE, я бы предложил поместить где-нибудь в основной файл программы строку, похожую на

$SIG{PIPE} = sub { die "Aborting on SIGPIPE\n" };

, который хотя бы предупредит вас об этом факте.Если вместо этого вы используете Carp::croak без \n, возможно, вам даже повезет получить номер файла / строки syswrite и т. Д., Который вызвал SIGPIPE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...