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

标签 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.

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

最佳答案

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

int:get_binding()
              ^
              |

不是:
int:get_bindings() 
               ^
               |

即使这样,重新编译模块也未能成功停止执行。为了让事情正常工作,我不得不退出调试器:我关闭了所有的调试器窗口,然后我发出了命令:
82> debugger:stop().
ok 

(我找不到函数 debugger:stop() 的任何信息,所以我不知道这是否有必要或什至有什么作用。)

然后我重新编译了两个模块:
83> c(my, [debug_info]).
{ok,my}
84> c(c_test).
{ok,c_test}

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

调试器:start() 启动 Monitor window ,并且在监视器窗口处于事件状态时,我选择了菜单项:
Module > Interpret 

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

然后在 Monitor 窗口仍然处于事件状态的情况下,我选择了菜单项:
 Break>Conditional Break 

...我填写了信息。您也可以双击 Monitor 窗口中显示的模块名称,然后使用 View Module window打开设置断点。 View Module 窗口显示您的源代码,该窗口还有一个 Break 菜单项,允许您设置各种类型的断点。在 View Module 窗口中,您可以使用快捷方式来创建 Line 断点,即常规断点:您可以通过双击代码中的一行来设置断点。

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

欢呼!

然后我双击监视器窗口中列出的进程,并打开一个附加进程窗口。附加进程窗口显示代码中执行停止的位置,它为您提供了单步执行代码的方法。

返回监控窗口,如果您选中复选框 On Break ,然后当执行在断点处停止时,将自动打开一个附加进程窗口。据我所知,每次运行代码时都需要打开一个新的附加进程窗口。

顺便说一下,模块名称c_test和函数名 c_break()可以是任何名称。他们的名字并不重要,比如我把模块名改成了conditional_breaks函数名称为 break1() .

关于debugging - 如何让 Erlang 调试器执行条件中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32774872/

相关文章:

erlang - 打破折叠的简单方法

c# - Visual Studio F5 调试比附加到进程慢

javascript - 如何找到哪个脚本修改了所选属性的CSS

android - 错误 : device offline

erlang - 理解 spawn 的返回值

list - Erlang列表问题

c++ - OpenGL 3.3 2D 渲染 : VAO not properly configured?

cocoa - Xcode调试: View value of NSNumber?

erlang - 如何通过命令行将应用程序作为守护进程启动?

erlang - 在 Erlang 中的每次递归之前创建一个小延迟?