debugging vim emacs erlang

debugging - ¿Cómo depurar el código de Erlang?



vim emacs (4)

Tengo algunos antecedentes de Ruby y Java y estoy acostumbrado a tener números exactos de líneas en los registros de errores.

Entonces, si hay un error en el código compilado, veré el número de línea que causó la excepción en la salida de la consola.

Como en este ejemplo de Ruby:

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

Es simple y rápido: solo voy a la línea número 13 y soluciono el error.

Por el contrario, Erlang solo dice algo como:

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

No hay números de línea para mirar.

Y si tengo dos líneas como

X = Param1, Y = Param2,

en ''my_fun'', ¿cómo se puede entender en qué línea se encuentra el problema?

Además, he intentado cambiar a Emacs + Elang-mode desde Vim, pero el único bono que tengo hasta ahora es la capacidad de recorrer los errores de compilación dentro de Emacs (Ck `).

Por lo tanto, el proceso de escribir código y buscar errores lógicos simples como "no coincidir con el lado derecho" parece ser un poco engorroso.

He intentado agregar muchas líneas "io: format" en el código, pero es un trabajo adicional que lleva tiempo.

También he intentado usar distel , pero se requieren 10 pasos para abrir un depurador una vez.

Preguntas:

  1. ¿Cuál es la forma más directa y sencilla de depurar el código Erlang?
  2. ¿El modo erlang de Emacs tiene algo superior en términos de desarrollo de Erlang en comparación con Vim?
  3. ¿Qué ciclo de desarrollo ''escribir-compilar-depurar'' prefieres? ¿Dejas que Emacs compile y ejecute el código en el terminal? ¿Cómo buscar errores en su código de Erlang?

Depurar el código de Erlang puede ser complicado a veces, sobre todo tratar con errores de badmatch . En general, dos buenas pautas a tener en cuenta son:

  • Mantener las funciones cortas
  • Use valores de retorno directamente si puede, en lugar de vincular variables temporales (esto le dará la ventaja de obtener errores de function_clause , etc. que son mucho más informativos)

Dicho esto, normalmente se requiere que los depuradores lleguen rápidamente al fondo de los errores. Recomiendo usar el depurador de línea de comandos, dbg , en lugar del gráfico, debugger (es mucho más rápido cuando sabes cómo usarlo, y no tienes que cambiar el contexto desde el shell Erlang a una GUI).

Dado el ejemplo de expresión que proporcionó, a menudo el caso es que tiene más que solo variables asignadas a otras variables (lo cual es absolutamente innecesario en Erlang):

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

La depuración de un error badmatch aquí se facilita mediante el uso del depurador de línea de comandos:

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)

Busque {matched,_,1} en el valor de retorno ... si este hubiera sido 0 lugar de 1 (o más), eso significaría que ninguna función coincidió con el patrón. La documentación completa para el módulo dbg se puede encontrar here .

Dado que tanto something/1 como other:do/1 siempre devuelve ok, podría suceder lo siguiente:

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

Aquí podemos ver todo el procedimiento de llamada y los valores de retorno que se dieron. Si lo llamamos con algo que sabemos fallará:

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

Aquí podemos ver que obtuvimos una excepción de badmatch , se llamó something/1 , pero nunca other:do/1 para que podamos deducir que el badmatch ocurrió antes de esa llamada.

Lograrte con el depurador de línea de comandos te ahorrará mucho tiempo, ya sea badmatch errores simples (pero difíciles) de errores de badmatch o algo mucho más complejo.

¡Con suerte, todo esto será más fácil cuando Erlang R15 salga con números de línea en excepciones!


Puede usar "debug_info" en el momento de compilación del archivo y "debugger"

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

Más detalles sobre cómo realizar la depuración en Erlang puede seguirlo mediante un enlace al video: https://vimeo.com/32724400


Puede utilizar el depurador Erlang para recorrer su código y ver qué línea está fallando.

Desde erl , inicie el depurador con:

debugger:start().

Luego, puede elegir qué módulos desea en el modo interpretado (requerido para la depuración) mediante la interfaz de usuario o la consola con ii:

ii(my_module).

La adición de puntos de interrupción se realiza de nuevo en la interfaz de usuario o la consola:

ib(my_module, my_func, func_arity).

Además, en Erlang R15 finalmente tendremos el número de línea en los seguimientos de pila.


Si reemplaza su instalación erlang con una reciente, tendrá números de línea, que se agregaron a partir de la versión 15.

Si las nuevas versiones aún no están disponibles en su sistema operativo, puede compilar desde la fuente o intentar obtener una versión empaquetada aquí: http://www.erlang-solutions.com/section/132/download-erlang-otp