2011-06-22 13 views
27

Tengo algunos antecedentes de Ruby y Java y estoy acostumbrado a tener un número exacto de líneas en los registros de errores.¿Cómo depurar el código de Erlang?

Por lo tanto, 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 Ruby:

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

Es muy sencillo y rápido - acabo de ir a la línea número 13 y corregir el error.

Por el contrario, Erlang se limita a decir algo así 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 a la vista.

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 la única ventaja que tengo hasta ahora es la capacidad de recorrer los errores de compilación dentro de Emacs (C-k `).

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

He tratado de 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 simplemente abrir un depurador una vez.

Preguntas:

  1. ¿Cuál es la forma más simple y directa para depurar 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 'write-compile-debug' prefiere? ¿Dejas Emacs para compilar y ejecutar el código en la terminal? ¿Cómo busca errores en su código de Erlang?
+0

Seleccione la respuesta que resolvió su pregunta, si corresponde. –

Respuesta

17

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

De erl, iniciar el depurador con:

debugger:start(). 

continuación, puede elegir los módulos que desea en modo interpretado (necesario para la depuración) utilizando la interfaz de usuario o el uso de la consola con ii:

ii(my_module). 

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

ib(my_module, my_func, func_arity). 

¡Además, en Erlang R15 finalmente tendremos el número de línea en los rastros de pila!

+0

Pero todavía creo que el depurador de Erlang está en desarrollo ... ¿Es estable? – niting112

+1

Todavía hay trabajo en el depurador, pero creo que es lo suficientemente estable como para usarlo.Lo he usado bastante para solucionar problemas cuando estoy trabajando en RabbitMQ o complementos asociados, es una base de código de Erlang bastante considerable. –

+0

@ niting112 Erlang Debugger es una herramienta probada en producción que es sólida. Es una parte estándar y probada de la distribución. Cuando se lanzó la versión de wx, hubo algunas regresiones de estabilidad, pero desde entonces se han abordado. –

33

Depuración El código de Erlang puede ser complicado a veces, especialmente cuando se trata de errores badmatch. En general, dos buenas pautas a tener son:

  • Mantenga funciones corto
  • valores Uso de retorno directamente si es posible, en lugar de variables temporales de unión (esto le dará el beneficio de obtener function_clause errores, etc, que están muy más informativo)

Dicho esto, utilizar los depuradores generalmente es necesario para llegar 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 del shell de Erlang a una GUI).

Dada la expresión de ejemplo que nos ha facilitado, el caso es a menudo que usted tiene más que sólo las variables que se asignan a otras variables (que es absolutamente innecesario en Erlang):

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

la depuración de un error badmatch aquí está ayudada utilizando el 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,[email protected],29}]} 
3> dbg:tpl(my_module, something, x).  % tpl = trace local functions as well 
{ok,[{matched,[email protected],1},{saved,x}]} 
4> dbg:tp(other, do, x).     % tp = trace exported functions 
{ok,[{matched,[email protected],1},{saved,x}]} 
5> dbg:tp(my_module, run, x).    % x means print exceptions 
{ok,[{matched,[email protected],1},{saved,x}]} % (and normal return values) 

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

dado que tanto something/1other:do/1 y siempre devuelve bien, el siguiente podría ocurrir:

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 qué valores de retorno se les dio. Si lo llamamos con algo que sabemos que se producirá un error:

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 nos dieron una excepción badmatch, something/1 se llamaba, pero nunca other:do/1 por lo que podemos deducir que el BadMatch ocurrió antes de esa llamada.

Ser competente con el depurador de línea de comandos le ahorrará mucho tiempo, ya sea que depure errores simples (¡pero engañosos!) 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!

4

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

Si las nuevas versiones todavía no están disponibles en su sistema operativo, se puede construir a partir de fuente o intente obtener una versión empaquetada aquí: http://www.erlang-solutions.com/section/132/download-erlang-otp

Cuestiones relacionadas