Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get the Erlang debugger to execute a conditional break?

Given a positive number N, my print_even() function prints out all the even numbers between 1 and N:

-module(my).
-compile(export_all).

print_even(N) when N>0 -> even_helper(1, N).

even_helper(Current, N) when Current =< N ->
    io:format("(Current = ~w)~n", [Current]),
    case Current rem 2 of
        0 -> io:format("Number: ~p~n", [Current]);
        _ -> do_nothing
    end,
    even_helper(Current+1, N);
even_helper(Current, N) when Current > N ->
    ok.

Here's some sample output:

28> my:print_even(10).
(Current = 1)
(Current = 2)
Number: 2
(Current = 3)
(Current = 4)
Number: 4
(Current = 5)
(Current = 6)
Number: 6
(Current = 7)
(Current = 8)
Number: 8
(Current = 9)
(Current = 10)
Number: 10
ok

Below is the code I'm using for a conditional break:

-module(c_test).
-compile(export_all).

c_break(Bindings) ->
    case int:get_bindings('Current', Bindings) of
        {value, 3}  -> true;
        _           -> false
    end.

I set a conditional break on the following line in print_even():

    case Current rem 2 of

...which according to the Erlang debugger docs should be legal. But no matter what I do, I can't get my c_break() function to execute. I expected execution to halt at the breakpoint when Current is equal to 3, but the code runs to completion, and the breakpoint is skipped. I even tried:

c_break(Bindings) ->
    case int:get_bindings('Current', Bindings) of
        _  -> true;
    end.

But execution still won't halt at the breakpoint.

Update: I can get execution to halt if I use the following function for my conditional break:

c_break(_) ->
    true.

If I change that to:

c_break(X) ->
    io:format("~w~n", [X]),
    true.

...then once again execution won't halt.

like image 393
7stud Avatar asked Sep 27 '22 15:09

7stud


1 Answers

!@#$!@#$@!! It should be:

int:get_binding()
              ^
              |

not:

int:get_bindings() 
               ^
               |

Even then, recompiling the module did not succeed in getting execution to halt. To get things to work, I had to quit the debugger: I closed all the debugger windows, then I issued the command:

82> debugger:stop().
ok 

(I can't find any information for the function debugger:stop(), so I don't know if that is necessary or even does anything.)

Then I recompiled both modules:

83> c(my, [debug_info]).
{ok,my}
84> c(c_test).
{ok,c_test}

Then:

85> debugger:start().
{ok,<0.305.0>}

debugger:start() launches the Monitor window, and with the Monitor window active I chose the menu item:

Module > Interpret 

...and I selected my.erl from the popup--where my.erl is the module containing the function where I want to halt execution.

Then with the Monitor window still active, I chose the menu item:

 Break>Conditional Break 

...and I filled in the information. You can also double click your module name displayed in the Monitor window, and then use the View Module window that opens to set breakpoints. The View Module window displays your source code, and the window also has a Break menu item, which allows you to set the various types of breakpoints. In the View Module window, you can use a shortcut for creating a Line breakpoint, i.e. a regular breakpoint: you can set a breakpoint by double clicking a line in your code.

Finally:

86> my:print_even(10).  
(Current = 1)
(Current = 2)
Number: 2
(Current = 3)

Hurray!

Then I double clicked on the process listed in the Monitor window, and an Attach Process window opened. The Attach Process window shows where execution halted in your code, and it provides the means for you to step through the code.

Back in the Monitor window, if you check the checkbox On Break, then an Attach Process window will open automatically when execution halts at a breakpoint. As far as I can tell, you need to open a new Attach Process window every time you run your code.

By the way, the module name c_test and the function name c_break() can be any name. Their names are not important, for instance I changed the module name to conditional_breaks and the function name to break1().

like image 60
7stud Avatar answered Sep 30 '22 03:09

7stud