Re: [erlang] Почему при краше процесса не видно стектрейс?
От: Mikl Kurkov Россия  
Дата: 10.09.09 10:30
Оценка: 3 (1)
Здравствуйте, Васильич, Вы писали:

В>Почему так, куда пропадает стек в первом случае? Я уже и гуглил, и изучал исходники proc_lib, gen_*, sys — ну нет там чего-то такого, что могло бы приводить к такому результату. А без стектрейсов отлаживать просто нереально. Сейчас приходится отказываться от proc_lib и даваемых ей преимуществ, запускать через spawn().


По-моему есть путаница в вопросах исключений и трейса. Попробую разъяснить.

В Erlang три вида исключений


При возникновении исключения никакого трейса в нем нет, только тип и причина. Трейс добавляет оператор catch и только для исключений рантайма.
Можно сравнить вывод catch для разных видов исключений.

  {catch erlang:error(err), catch exit(ext), catch throw(thr)}.

{{'EXIT',{err,[{erl_eval,do_apply,5},
               {erl_eval,expr,5},
               {erl_eval,expr_list,6},
               {erl_eval,expr,5},
               {shell,exprs,6},
               {shell,eval_exprs,6},
               {shell,eval_loop,3}]}},
 {'EXIT',ext},
 thr}


Здесь видно что catch не позволяет однозначно опрделить тип исключения и было ли оно вообще.
Это мешало полноценно их использовать, и поэтому появилась конструкция try...catch...end .

При обработке исключения в try..catch..end трейса нет:

  try erlang:error(err) catch C:E -> {C,E} end.
{error,err}


Но вместе c try..catch..end была добавлена функция erlang:get_stacktrace(),которая позволяет добавить трейс при необходимости.

 try erlang:error(err) catch C:E -> {C,E,erlang:get_stacktrace()} end.
{error,err,
       [{erl_eval,do_apply,5},
        {erl_eval,try_clauses,8},
        {shell,exprs,6},
        {shell,eval_exprs,6},
        {shell,eval_loop,3}]}


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

Для отладки кстати удобно включить трассировку вызовов функций.
У Joel Reymont есть удобная обертка для включения выключения трассировки всех функций конкретного модуля — здесь.

Подробности про исключения в Erlang — Erlang's Exception Handling Revisited

--
Mikl
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.