The Erlang debugger was designed so that the user interface part is decoupled from the actual debugger. This TTY interface was developed in parallel to the initial (PXW-based) graphical user interface (GUI). However, it was never released and was soon forgotten. Now, the cobweb has been removed and the TTY interface is functioning again.
In the examples below we assume that you initially have called the debugger as:
unix> erl
Erlang (JAM) emulator version 47.4.0
Eshell V47.4.0 (abort with ^G)
1> ii(test),ib(test,19).
ok
2> test:start().
<0.38.0>
3>
This will start a monitor process which will print something like:
3> tdb:start().
*** Entering the debugger in TTY mode
*** hit the '?' key to get the help
# Pid Initial Func Status Info
-- --- ------------ ------ -----
1 <0.23.0> test:start/0 idle
2 <0.38.0> test:init/1 break {test,19}
tdb>
This corresponds to the GUI monitor window. You are now in monitor mode, which is reflected by the new prompt 'tdb>'. To see what commands there is in this mode, type '?', which will result in the following being printed.
tdb> ?
*** Interpreter monitor commands:
*** q - Quit monitor
*** p - Show process info (refresh and clear)
*** a - Attach process (a N)
*** c - Continue process (c N)
*** k - Kill process (k N)
*** b - Break (b Mod Line)
*** bp - Print all break point info
*** d - Delete Break (d Mod Line)
*** dx - Delete all breakpoints
*** ? - This text
tdb>
If you have used the GUI version of the debugger, these commands should look familiar to you. For example, we can set a new break point and print information about all break points as:
tdb> b test 23
*** Break point set at line: 23 in module: test !
tdb> bp
Module Line Break Point Info
------ ---- ----------------
test 23 [active,enable,all,null]
test 19 [active,enable,all,null]
tdb>
Now let us attach ourself to the second process in the first printout:
tdb> a 2
*** Process <0.38.0> attached at line: 19
*** in module: test, status <break - {test,19}>
---
14:
15: start() ->
16: spawn(test, init, [self()]).
17:
18: init(From) ->
19: = loop(From).
20:
21: loop(From) ->
22: receive
23: B X ->
24: io:format("Got: ~w~n",[X]),
---
<0.38.0> =>
We have now entered the attach mode, as you can see from the new prompt, indicating which process we have attached to. From the first information printed we can see that we are stopped at a break point. The code listed is centered around that line, the current line. This is indicated by a '=' character in the 7:th column. Further more, we can see that we have a break point at line 23, indicated by a 'B' character. Again, if you type a '?' character you'll get a menu printed with all the commands available. Continue from here by your own, e.g by practicing single-step, how to inspect variables or avoid avaluating expressions (skip), etc...
If you want to be attached to several processes at the same time, then make use of the job control mode. By typing 'C-g' you'll enter the job control mode. Start a new shell and connect yourself to it. From the new shell call tdb. This will make it possible for you to jump back and forth between several shells which are all running tdb.
If you are an Emacs user, then you can use tdb from the Erlang shell buffer.
If you're lazy put 'tdb()' in you shell default file.
Learn some of the nice shell defaults that already exists, e.g ii/0, ib/2.