web-dev-qa-db-ja.com

Erlangコードをデバッグする方法は?

RubyとJavaの背景があり、エラーログに正確な行数を記録することに慣れています。

したがって、コンパイルされたコードにエラーがある場合、コンソール出力に例外の原因となった行数が表示されます。

このようにRuby例:

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

シンプルで高速です。行番号13に移動して、エラーを修正します。

それどころか、Erlangは次のように言っています。

** 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

確認する行番号はありません。

そして、私が次のような2行がある場合

X = Param1,
Y = Param2,

'my_fun'で、問題がどの行にあるかをどのように理解できますか?

さらに、VimからEmacs + Elangモードに切り替えようとしましたが、これまでに得た唯一のボーナスは、Emacs(C-k `)内のコンパイルエラーを循環する機能です。

したがって、コードを記述して「右側の一致がない」などの単純な論理エラーを探すプロセスは、少し面倒なようです。

コードに「io:format」行をたくさん追加しようとしましたが、時間がかかる追加作業です。

distel も使用しようとしましたが、デバッガーを1回開くだけで10ステップ必要です。

質問:

  1. Erlangコードをデバッグするための最も簡単で簡単な方法は何ですか?
  2. EmacsのerlangモードはVimと比較してErlang開発の点で優れていますか?
  3. どの開発の「書き込み-コンパイル-デバッグ」サイクルが好きですか?ターミナルでコードをコンパイルして実行するためにEmacsを離れますか? Erlangコードのエラーをどのように検索しますか?
29
Kirill

Erlangコードのデバッグは、特にbadmatchエラーの処理が難しい場合があります。一般に、維持すべき2つの適切なガイドラインは次のとおりです。

  • 関数を短くする
  • 可能であれば、一時変数をバインドする代わりに、戻り値を直接使用します(これにより、はるかに有益な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/1other:do/1の両方が常にokを返すとすると、次のことが起こります。

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が例外で行番号で出てくるとき、これはすべて簡単になるでしょう!

33
Adam Lindberg

Erlangデバッガー を使用してコードをステップ実行し、どの行が失敗しているかを確認できます。

erlから、次のコマンドでデバッガーを起動します。

debugger:start().

次に、UIを使用するか、iiでコンソールを使用して、インタープリターモード(デバッグに必要)にするモジュールを選択できます。

ii(my_module).

ブレークポイントの追加は、UIまたはコンソールで再度実行されます。

ib(my_module, my_func, func_arity).

また、Erlang R15では、スタックトレースに行番号がついに追加されます!

18
Rob Harrop

Erlangのインストールを最近のものに置き換えると、行番号が表示されます。これらはバージョン15から追加されています。

新しいバージョンがオペレーティングシステムでまだ利用できない場合は、ソースからビルドするか、ここでパッケージバージョンを入手してみてください: http://www.erlang-solutions.com/section/132/download-erlang -otp

4
mit

ファイルのコンパイル時に「debug_info」と「debugger」を使用できます

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

ビデオへのリンクでErlangでのデバッグを行う方法の詳細-- https://vimeo.com/327244

0
Viacheslav