Как отладить код Erlang? - PullRequest
       15

Как отладить код Erlang?

27 голосов
/ 22 июня 2011

У меня есть некоторый опыт работы с Ruby и Java, и я привык иметь точное количество строк в журналах ошибок.

Итак, если в скомпилированном коде будет ошибка, я увижу номер строки, вызвавшей исключение в выводе консоли.

Как в этом примере Ruby:

my_ruby_code.rb:13:in `/': divided by 0 (ZeroDivisionError)
    from my_ruby_code.rb:13

Это просто и быстро - я просто иду на строку № 13 и исправляю ошибку.

Наоборот, Эрланг просто говорит что-то вроде:

** exception error: no match of right hand side value [xxxx]
 in function my_module:my_fun/1
 in call from my_module:other_fun/2

Естьнет номеров строк, чтобы посмотреть.

И если у меня есть две строки, такие как

X = Param1,
Y = Param2,

в 'my_fun', как понять, в какой строке находится проблема?

Кроме того, я попытался переключиться в Emacs + Elang-mode из Vim, но единственный бонус, который я получил, - это возможность циклически проходить через ошибки компиляции внутри Emacs (Ck `).

Итак, процесс написания кода и поиска простых логических ошибок, таких как «нет соответствия правой части», кажется немного громоздким.

Я пытался добавить много «io: format»строк в коде, но это дополнительная работа, которая требует времени.

Я также пытался использовать distel , но для открытия одного отладчика нужно всего 10 шагов.

Вопросы:

  1. Какой самый простой и простой способ отладки кода Erlang?
  2. Обладает ли Emacs-режим erlang чем-то превосходным с точки зрения разработки Erlang по сравнению с Vim?
  3. Какой цикл разработки «запись-компиляция-отладка» вы предпочитаете?Вы оставляете Emacs для компиляции и запуска кода в терминале?Как вы ищите ошибки в вашем коде Erlang?

Ответы [ 4 ]

33 голосов
/ 22 июня 2011

Отладка кода Erlang иногда бывает сложной, особенно в случае ошибок badmatch. В целом, два хороших принципа:

  • Сохраняйте функции короткими
  • Используйте возвращаемые значения напрямую, если можете, вместо привязки временных переменных (это даст вам преимущество в получении function_clause ошибок и т. Д., Которые более информативны)

При этом использование отладчиков обычно требуется, чтобы быстро докопаться до ошибок. Я рекомендую использовать отладчик командной строки, dbg, вместо графического debugger (это намного быстрее, когда вы знаете, как его использовать, и вам не нужно переключать контекст с оболочки Erlang на GUI ).

Учитывая предоставленное вами примерное выражение, часто случается так, что у вас есть больше, чем просто переменные, назначаемые другим переменным (что абсолютно необязательно в Erlang):

run(X, Y) ->
    X = something(whatever),
    Y = other:do(more_data),

Отладке ошибки badmatch здесь помогает отладчик командной строки:

1> dbg:tracer().                            % Start the CLI debugger
{ok,<0.55.0>}
2> dbg:p(all, c).                           % Trace all processes, only calls
{ok,[{matched,nonode@nohost,29}]}
3> dbg:tpl(my_module, something, x).        % tpl = trace local functions as well
{ok,[{matched,nonode@nohost,1},{saved,x}]}
4> dbg:tp(other, do, x).                    % tp = trace exported functions  
{ok,[{matched,nonode@nohost,1},{saved,x}]}
5> dbg:tp(my_module, run, x).               % x means print exceptions
{ok,[{matched,nonode@nohost,1},{saved,x}]}  % (and normal return values)

Ищите {matched,_,1} в возвращаемом значении ... если бы это было 0 вместо 1 (или более), это означало бы, что ни одна функция не соответствовала шаблону. Полную документацию по модулю dbg можно найти здесь .

Учитывая, что и something/1, и other:do/1 всегда возвращаются нормально, может произойти следующее:

6> my_module:run(ok, ok).
(<0.72.0>) call my_module:run(ok,ok)
(<0.72.0>) call my_module:something(whatever)
(<0.72.0>) returned from my_module:something/1 -> ok
(<0.72.0>) call other:do(more_data)
(<0.72.0>) returned from other:do/1 -> ok
(<0.72.0>) returned from my_module:run/2 -> ok
ok

Здесь мы можем увидеть всю процедуру вызова и какие возвращаемые значения были даны. Если мы назовем это с чем-то, что мы знаем, потерпит неудачу:

7> my_module:run(error, error).
** exception error: no match of right hand side value ok
(<0.72.0>) call my_module:run(error,error)
(<0.72.0>) call my_module:something(whatever)
(<0.72.0>) returned from my_module:something/1 -> ok
(<0.72.0>) exception_from {my_module,run,2} {error,{badmatch,ok}}

Здесь мы видим, что мы получили исключение badmatch, был вызван something/1, но никогда other:do/1, поэтому мы можем сделать вывод, что сбой произошел до этого вызова.

Опыт работы с отладчиком командной строки сэкономит вам много времени, если вы будете отлаживать простые (но сложные!) badmatch ошибки или что-то гораздо более сложное.

Надеюсь, все это будет проще, когда Erlang R15 выйдет с номерами строк в исключениях!

18 голосов
/ 22 июня 2011

Вы можете использовать отладчик Erlang , чтобы просмотреть ваш код и увидеть, какая строка не работает.

С erl запустите отладчик с помощью:

debugger:start().

Затем вы можете выбрать, какие модули вы хотите использовать в интерпретируемом режиме (необходим для отладки), используя пользовательский интерфейс или консоль сii:

ii(my_module).

Добавление точек останова снова выполняется в пользовательском интерфейсе или консоли:

ib(my_module, my_func, func_arity).

Кроме того, в Erlang R15 мы наконец-то получим номер строки в трассировке стека!

4 голосов
/ 15 июля 2012

Если вы замените установку erlang на последнюю, у вас будут номера строк, они были добавлены начиная с версии 15.

Если новые версии еще не доступны в вашей операционной системе, вы можете собратьиз исходного кода или попробуйте получить упакованную версию здесь: http://www.erlang -solutions.com / section / 132 / download-erlang-otp

0 голосов
/ 30 июня 2018

Вы можете использовать "debug_info" во время компиляции файла и "отладчик"

1> c(test_module, [debug_info]).
{ok, test_module}
2> debugger:start().

Подробнее о том, как сделать отладку в Erlang вы можете перейти по ссылке на видео - https://vimeo.com/32724400

...