1

我有一个项目,它有很多模块,每个模块都有不同的运行线程。我写了一个小脚本,它遍历每个脚本并安全地重新加载代码(用于热交换):

reload_all() ->                
    ?MODULE:reload_all(?MODULE_LIST).
reload_all([]) -> ok;          
reload_all([T|C]) ->
    io:fwrite("Purging ~w\n",[T]),  
    try_purge(T),              
    {module,T} = code:load_file(T), 
    ?MODULE:reload_all(C).     

try_purge(T) -> try_purge(T,1).
try_purge(T,Wait) ->           
    case code:soft_purge(T) of 
    true -> ok;
    false ->
        io:fwrite("* Waiting ~w seconds for ~w module\n",[Wait,T]),
        timer:sleep(Wait*1000),
        try_purge(T,Wait+1)    
    end.

它使用 soft_purge() 函数,该函数仅在没有线程运行将被正常清除命令杀死的“旧”代码时清除代码。它将以越来越长的间隔等待并继续尝试。我已经设计了这个项目,因此等待总时间不应该超过一分钟,但实际上它应该或多或少是即时的。

我遇到的问题是,有时一个模块会有一个错误,导致它由于某种原因无限期地阻塞,而我的 reload_all() 脚本永远不会完成。这是期望的行为,它让我知道出了点问题。问题在于,追踪 bug 需要对代码进行大量的测试和分析,这有时甚至不起作用,因为 bug 只出现在生产环境中,而不出现在测试环境中。

我的问题是:有没有办法识别哪些线程正在运行模块中的“旧”代码,并查看它们当前卡在哪个函数中?

4

1 回答 1

1

您可以使用 erlang:check_old_code/1 和 erlang:check_process_code/2 检查您使用的是旧版本还是新版本的模块。只需查看Erlang 手册

于 2012-05-08T08:17:03.387 回答