如何让Erlang调试器执行条件中断?

时间:2015-09-25 04:35:45

标签: debugging erlang

给定正数N,我的print_even()函数打印出1和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.

这里有一些示例输出:

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

以下是我用于条件中断的代码:

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

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

我在print_even()中的以下行设置了条件中断:

    case Current rem 2 of

......根据Erlang debugger docs应该是合法的。但无论我做什么,我都无法执行我的c_break()函数。当Current等于3时,我期望执行在断点处停止,但代码运行完成,并跳过断点。我甚至尝试过:

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

但执行仍然不会在断点处停止。

更新:如果我使用以下函数进行条件中断,可以停止执行:

c_break(_) ->
    true.

如果我改为:

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

......然后再次执行不会停止。

1 个答案:

答案 0 :(得分:3)

!@#$!@#$ @!它应该是:

int:get_binding()
              ^
              |

int:get_bindings() 
               ^
               |

即使这样,重新编译模块也无法成功停止执行。为了让事情变得有效,我不得不退出调试器:我关闭了所有的调试器窗口,然后发出了命令:

82> debugger:stop().
ok 

(我无法找到函数调试器的任何信息:stop(),因此我不知道是否有必要甚至做任何事情。)

然后我重新编译了两个模块:

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

然后:

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

debugger:start()启动Monitor window,并且在Monitor窗口处于活动状态时,我选择了菜单项:

Module > Interpret 

...我从弹出窗口中选择了my.erl - 其中my.erl是包含我想要暂停执行的函数的模块。

然后在Monitor窗口仍处于活动状态时,我选择了菜单项:

 Break>Conditional Break 

......我填写了这些信息。您还可以双击“监视器”窗口中显示的模块名称,然后使用打开的View Module window设置断点。 “查看模块”窗口显示源代码,窗口还有“中断”菜单项,允许您设置各种类型的断点。在“视图模块”窗口中,您可以使用快捷方式创建换行符,即常规断点:您可以通过双击代码中的一行来设置断点。

最后:

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

乌拉!

然后,我双击Monitor窗口中列出的进程,打开Attach Process窗口。 Attach Process窗口显示代码中停止执行的位置,它为您提供了逐步执行代码的方法。

返回Monitor窗口,如果选中复选框On Break,则执行在断点处停止时将自动打开Attach Process窗口。据我所知,每次运行代码时都需要打开一个新的Attach Process窗口。

顺便说一下,模块名c_test和函数名c_break()可以是任何名称。它们的名称并不重要,例如我将模块名称更改为conditional_breaks,将函数名称更改为break1()