Erlang 代码束文件在哪里?

Erlang 代码束文件在哪里?,erlang,lager,Erlang,Lager,我已经打印了所有加载的代码如下,为什么 {lager_default_tracer,[]},beam文件在哪里 (lager_test_1@macbook.local)10> io:format("~p",[code:all_loaded()]). [{io,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/io.beam"}, {erl_distribution,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/e

我已经打印了所有加载的代码如下,为什么 {lager_default_tracer,[]},beam文件在哪里

(lager_test_1@macbook.local)10> io:format("~p",[code:all_loaded()]).
[{io,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/io.beam"},
 {erl_distribution,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/erl_distribution.beam"},
 {edlin,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/edlin.beam"},
 {beam_clean,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/beam_clean.beam"},
 {v3_core,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/v3_core.beam"},
 {erl_epmd,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/erl_epmd.beam"},
 {love_misc,"/usr/local/bin/lager_test/lib/hanoch-0.0.1.6/ebin/love_misc.beam"},
 {zlib,preloaded},
 {error_handler,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/error_handler.beam"},
 {io_lib,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/io_lib.beam"},
 {lib,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/lib.beam"},
 {mnesia,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia.beam"},
 {lager_test_app,"/usr/local/bin/lager_test/lib/lager_test-0.0.1.0/ebin/lager_test_app.beam"},
 {beam_jump,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/beam_jump.beam"},
 {v3_codegen,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/v3_codegen.beam"},
 {beam_flatten,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/beam_flatten.beam"},
 {mnesia_tm,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_tm.beam"},
 {prim_eval,preloaded},
 {beam_bool,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/beam_bool.beam"},
 {error_logger_lager_h,"/usr/local/bin/lager_test/lib/lager-2.0.0/ebin/error_logger_lager_h.beam"},
 {lager_msg,"/usr/local/bin/lager_test/lib/lager-2.0.0/ebin/lager_msg.beam"},
 {mnesia_frag,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_frag.beam"},
 {filename,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/filename.beam"},
 {lager_default_tracer,[]},
 {lager_default_formatter,"/usr/local/bin/lager_test/lib/lager-2.0.0/ebin/lager_default_formatter.beam"},
 {mnesia_locker,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_locker.beam"},
 {mnesia_recover,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_recover.beam"},
 {mnesia_dumper,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_dumper.beam"},
 {mnesia_kernel_sup,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_kernel_sup.beam"},
 {mnesia_sp,"/usr/local/lib/erlang/lib/mnesia-4.12.4/ebin/mnesia_sp.beam"},
 {erts_internal,preloaded},
 {unicode,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/unicode.beam"},
 {lager_backend_throttle,"/usr/local/bin/lager_test/lib/lager-2.0.0/ebin/lager_backend_throttle.beam"},
 {beam_type,"/usr/local/lib/erlang/lib/compiler-5.0.3/ebin/beam_type.beam"},
 {orddict,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/orddict.beam"},
 {gb_sets,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/gb_sets.beam"},
 {sofs,"/usr/local/lib/erlang/lib/stdlib-2.3/ebin/sofs.beam"},
 {inet_db,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/inet_db.beam"},
 {lager_test_a,"/usr/local/bin/lager_test/lib/lager_test-0.0.1.0/ebin/lager_test_a.beam"},
 {inet,"/usr/local/lib/erlang/lib/kernel-3.1/ebin/inet.beam"},
调用module_info()时,如下所示:

(lager_test_1@macbook.local)11> lager_default_tracer:module_info().
[{exports,[{table,1},
           {handle,1},
           {module_info,0},
           {module_info,1},
           {info,1}]},
 {imports,[]},
 {attributes,[{vsn,[203040246025344403396962742072895880482]}]},
 {compile,[{options,[]},
           {version,"5.0.3"},
           {time,{2017,8,27,5,43,32}},
           {source,"/private/tmp/lager_test-0.0.1.0"}]}]
(lager_test_1@macbook.local)12> lager_default_tracer:table(aaa).
** exception error: bad argument
     in function  lager_default_tracer:table/1 
当我调用
lager\u default\u tracer:table(111)
时,它如下所示:

(lager_test_1@macbook.local)11> lager_default_tracer:module_info().
[{exports,[{table,1},
           {handle,1},
           {module_info,0},
           {module_info,1},
           {info,1}]},
 {imports,[]},
 {attributes,[{vsn,[203040246025344403396962742072895880482]}]},
 {compile,[{options,[]},
           {version,"5.0.3"},
           {time,{2017,8,27,5,43,32}},
           {source,"/private/tmp/lager_test-0.0.1.0"}]}]
(lager_test_1@macbook.local)12> lager_default_tracer:table(aaa).
** exception error: bad argument
     in function  lager_default_tracer:table/1 

lager\u default\u tracer
模块没有关联的beam文件,因为它是在运行时创建的。
lager
应用程序使用,它使用运行时代码编译和加载

如果您仔细查看,您会发现它调用了动态编译的标准。通过跟踪该调用,我们可以使用以下步骤重构
lager\u default\u tracer
的源代码,这些步骤假定您已经克隆并成功编译了。在某些步骤中,erlangshell命令的输出太大,无法放在这里,因此这些部分使用省略号缩写

  • 在已编译的克隆
    lager
    repo目录中,运行
    rebar shell
    启动Erlang shell,以确保所有必要的目录都位于Erlang加载路径中

  • 在shell中,打开并跟踪
    compile:forms/2

    1> dbg:tracer(), dbg:p(all, call).
    {ok,[{matched,nonode@nohost,34}]}
    2> dbg:tpl(compile, forms, []).
    {ok,[{matched,nonode@nohost,2}]}
    
  • 启动
    lager
    应用程序及其依赖项:

    3> application:ensure_all_started(lager).
    
    这将导致
    dbg
    跟踪产生如下冗长的输出:

    ()调用compile:forms([{attribute,0,module,lager\u default\u tracer},
    ...
    {tuple,0,[{integer,0,2},{integer,0,1}]}]}]}],[nowarn\u unused\u vars])
    {好的,[语法工具,编译器,goldrush,lager]}
    08:29:21.478[信息]节点上的应用程序已启动nonode@nohost
    

    这里,输出缩写为仅显示第一行和最后几行。最后两行是
    应用程序的结果:确保\u所有\u已启动/1
    。这些行上方的所有内容都是
    lager\u default\u tracer
    模块的内容

  • 将跟踪输出从输出跟踪第一行的
    [{attribute,0,module,lager\u default\u tracer}
    一直复制到输出跟踪最后一行的
    {tuple,0,[{integer,0,2},{integer,0,1}]}]
    。不要在复制内容中包含结尾文本
    [nowarn\u unused\u vars])

  • 粘贴复制的数据,将其分配给Erlang shell中名为
    M
    的变量:

    4>M=[{attribute,0,module,lager\u default\u tracer},
    ...
    {tuple,0,[{integer,0,2},{integer,0,1}]}]}]。
    

    不要忘记添加最后一个句点(也称为句号)来完成表达式

  • 关闭
    dbg
    跟踪:

    5>dbg:stop_clear()。
    好啊
    

  • 编译摘要格式:

    6>{ok,u,B}=compile:forms(M,[no_unused_vars,debug_info])。
    {好的,大杯啤酒,
    }
    

    变量
    B
    现在以二进制形式保存
    lager\u default\u tracer
    模块的编译代码

  • 从存储在
    B
    中的已编译二进制文件中提取抽象代码块:

    7>{ok,{{{uu,[{abstract\u code,{uu,AC}]}}=beam\u lib:chunks(B,[abstract\u code])。
    {好的,{lager\u default\u tracer,
    [{抽象代码,
    ...
    [{子句,0,[{var,0,'Event'}],[{call,…}]}]}]}}
    

    变量
    AC
    现在保存抽象代码

  • 使用抽象代码打印
    lager\u default\u tracer
    模块的重构源代码:

    8>io:fwrite(“~s~n”,[erl\u prettypr:format(erl\u语法:form\u list(AC)))。
    -模块(较大的默认跟踪程序)。
    -导出([info/1,重置计数器/1,表/1,句柄/1])。
    ...
    句柄(事件)->
    gr_计数器:更新_计数器(表(计数器)、过滤器、,
    {2, 1}).
    好啊
    

    这最后一步和它之前的一步是从“重构源代码”下的


  • 毫不奇怪,重构的源代码显示了对其他
    goldrush
    函数的调用,因此如果您想尝试理解重构的代码,您需要访问。

    较大的默认跟踪程序模块没有相关联的beam文件,因为它是在运行时创建的。
    lager
    应用程序使用,它使用运行时代码编译和加载

    如果您仔细查看,您会发现它调用了动态编译的标准。通过跟踪该调用,我们可以使用以下步骤重构
    lager\u default\u tracer
    的源代码,这些步骤假定您已经克隆并成功编译了。在某些步骤中,erlangshell命令的输出太大,无法放在这里,因此这些部分使用省略号缩写

  • 在已编译的克隆
    lager
    repo目录中,运行
    rebar shell
    启动Erlang shell,以确保所有必要的目录都位于Erlang加载路径中

  • 在shell中,打开并跟踪
    compile:forms/2

    1> dbg:tracer(), dbg:p(all, call).
    {ok,[{matched,nonode@nohost,34}]}
    2> dbg:tpl(compile, forms, []).
    {ok,[{matched,nonode@nohost,2}]}
    
  • 启动
    lager
    应用程序及其依赖项:

    3> application:ensure_all_started(lager).
    
    这将导致
    dbg
    跟踪产生如下冗长的输出:

    ()调用compile:forms([{attribute,0,module,lager\u default\u tracer},
    ...
    {tuple,0,[{integer,0,2},{integer,0,1}]}]}]}],[nowarn\u unused\u vars])
    {好的,[语法工具,编译器,goldrush,lager]}
    08:29:21.478[信息]节点上的应用程序已启动nonode@nohost
    

    这里,输出缩写为仅显示第一行和最后几行。最后两行是
    应用程序的结果:确保\u所有\u已启动/1
    。这些行上方的所有内容都是
    lager\u default\u tracer
    模块的内容

  • 将跟踪输出从输出跟踪第一行的
    [{attribute,0,module,lager\u default\u tracer}
    一直复制到输出跟踪最后一行的
    {tuple,0,[{integer,0,2},{integer,0,1}]}]
    。不要在您复制的内容中包含结尾文本
    [nowarn\u unused\u vars])