4

How could I attach a debugger to a running erlang process (rabbitmq)? I have the source code of the same rabbit version that's running. I would like to set a breakpoint on a source line, and attach a debugger to the running rabbit instance. I'm not sure if erlang requires debug symbols async_dirty.

In a perfect world, I would like to be able to do that both locally and remotely.

polo
  • 1,352
  • 2
  • 16
  • 35
  • Erlang doc pages: [`dbg` reference manual](https://erlang.org/doc/man/dbg.html) (no user's guide), `debugger` [reference manual](http://erlang.org/doc/apps/debugger/index.html) and [user's guide](http://erlang.org/doc/apps/debugger/users_guide.html), – toraritte Sep 28 '20 at 16:37
  • Related SO threads: [Using trace and dbg in Erlang](https://stackoverflow.com/questions/1954894/using-trace-and-dbg-in-erlang), [How to debug Erlang code?](https://stackoverflow.com/questions/6438041/how-to-debug-erlang-code), – toraritte Sep 28 '20 at 16:39

2 Answers2

8

From what you're saying, you don't really need to run a debugger. The Erlang VM's concurrency model doesn't fit well with the concept of stop-everything-and-inspect-style debugging.

On the other hand, the VM has great, built-in tracing capabilities. The dbg module is where they are all exposed, but that module's interface is quite difficult to use, especially if you're a beginner. I'd recommend using recon_trace to get a view into what's going on with your process: http://ferd.github.io/recon/recon_trace.html.

If you don't feel like installing recon, start your program from the Erlang shell, and in that shell, type:

%enable tracing capabilities
1> dbg:tracer().  

% Trace Pattern Local-scope 
% (tell the tracer to trace every call in YourModule, even unexported functions).
2> dbg:tpl(YourModule, x). 

% Tell dbg to print calls from all processes calling your module.
3> dbg:p(all,call). 

% Run your traced module
4> YourModule:SomeFun().  

% You should see nice(?) traces of inputs, outputs, and
% exceptions in your shell

Check out the following session, where I fumble around not knowing how to use the queue module:

Eshell V6.3  (abort with ^G)
1> dbg:tracer(), dbg:tpl(queue, x), dbg:p(all, call).
{ok,[{matched,nonode@nohost,26}]}
2> X = queue:new().
(<0.33.0>) call queue:new()
(<0.33.0>) returned from queue:new/0 -> {[],[]}
{[],[]}
3> X = queue:cons(1).
** exception error: undefined function queue:cons/1
4> X = queue:cons(X,1).
(<0.39.0>) call queue:cons({[],[]},1)
(<0.39.0>) call queue:in_r({[],[]},1)
(<0.39.0>) exception_from {queue,in_r,2} {error,badarg}
(<0.39.0>) exception_from {queue,cons,2} {error,badarg}
** exception error: bad argument
     in function  queue:in_r/2
        called as queue:in_r({[],[]},1)
5> X = queue:cons(1,X).
(<0.41.0>) call queue:cons(1,{[],[]})
(<0.41.0>) call queue:in_r(1,{[],[]})
(<0.41.0>) returned from queue:in_r/2 -> {[],[1]}
(<0.41.0>) returned from queue:cons/2 -> {[],[1]}
** exception error: no match of right hand side value {[],[1]}
6> X1 = queue:cons(1,X).
(<0.43.0>) call queue:cons(1,{[],[]})
(<0.43.0>) call queue:in_r(1,{[],[]})
(<0.43.0>) returned from queue:in_r/2 -> {[],[1]}
(<0.43.0>) returned from queue:cons/2 -> {[],[1]}
{[],[1]}

Hope this helps to get you started.

If you want to see how the Erlang wizards do it, watch Mats Cronqvist's talk "Taking the printf out of printf debugging".

toraritte
  • 6,300
  • 3
  • 46
  • 67
Simon Zelazny
  • 386
  • 1
  • 5
0

You can use graphical debugger or in shell using int module. The modules need to be compiled using debug_info option.

The process can be remotely debugged from the connected node using debugger:start(global) or connecting to remote shell (^G).

Vinod
  • 2,243
  • 14
  • 18