2017-08-27 3 views
1

Ich habe alle Code wie folgt geladen, warum {lager_default_tracer, []}, wo Strahldatei?Wo ist die Code-Beam-Datei?

([email protected])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"}, 

wenn ich rufe MODULE_INFO(), wird sie wie folgt:

([email protected])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"}]}] 

Wenn ich lager_default_tracer:table(111) nennen, wird es wie folgt:

([email protected])12> lager_default_tracer:table(aaa). 
** exception error: bad argument 
    in function lager_default_tracer:table/1 

Antwort

4

Das lager_default_tracer Modul kein zugehöriges Strahl Datei, weil sie zur Laufzeit erstellt wird. Die lager Anwendung verwendet goldrush, die Laufzeitcode Kompilierung und Laden verwendet.

Wenn Sie durch die goldrush sources schauen, werden Sie sehen, dass es den Standard compile:forms/2 für die dynamische Kompilierung aufruft. Indem wir diesen Aufruf verfolgen, können wir den Quellcode für lager_default_tracer anhand der folgenden Schritte rekonstruieren, die davon ausgehen, dass Sie die lager source repository bereits geklont und erfolgreich kompiliert haben. In einigen der Schritte ist die Ausgabe des Erlang-Shell-Befehls zu groß, um sie hier zu platzieren, daher werden diese Teile mit Ellipsen abgekürzt.

  1. In Ihrem bereits kompilierte geklont lager Repo-Verzeichnis, führen rebar shell eine Erlang-Shell zu starten, die alle erforderlichen Verzeichnisse gewährleistet sind in der Erlang Lastpfad.

  2. In der Shell schalten dbg tracing und Spuren compile:forms/2:

    1> dbg:tracer(), dbg:p(all, call). 
    {ok,[{matched,[email protected],34}]} 
    2> dbg:tpl(compile, forms, []). 
    {ok,[{matched,[email protected],2}]} 
    
  3. Starten Sie die lager Anwendung und deren Abhängigkeiten:

    3> application:ensure_all_started(lager). 
    

    Dies wird die dbg Spur verursachen eine längere Ausgabe zu produzieren wie folgt:

    (<0.94.0>) call compile:forms([{attribute,0,module,lager_default_tracer}, ... {tuple,0,[{integer,0,2},{integer,0,1}]}]}]}]}],[nowarn_unused_vars]) {ok,[syntax_tools,compiler,goldrush,lager]} 08:29:21.478 [info] Application lager started on node [email protected]

    Hier wird die Ausgabe abgekürzt, um nur die erste Zeile und die letzten paar Zeilen anzuzeigen. Die letzten beiden Zeilen sind die Ergebnisse von application:ensure_all_started/1. Alles über diesen Linien ist das abstract format für das lager_default_tracer Modul.

  4. Kopieren Sie die verfolgte Ausgabe beginnend mit [{attribute,0,module,lager_default_tracer} in der ersten Zeile des Ausgabe-Trace den ganzen Weg bis {tuple,0,[{integer,0,2},{integer,0,1}]}]}]}]}] in der letzten Zeile der Ausgabe-Trace. Fügen Sie nicht den Endungstext [nowarn_unused_vars]) in dem ein, was Sie kopieren.

  5. die kopierten Daten einfügen es auf eine Variable M in der Schale Erlang benannt zuweisen:

    4> M = [{attribute,0,module,lager_default_tracer}, ... {tuple,0,[{integer,0,2},{integer,0,1}]}]}]}]}].

    Sie nicht die letzte Periode hinzuzufügen vergessen (auch bekannt als Punkt) um den Ausdruck zu vervollständigen.Schalten Sie

  6. dbg Verfolgung:

    5> dbg:stop_clear(). ok

  7. Kompilieren Sie das abstrakte Format:

    6> {ok, _, B} = compile:forms(M, [no_unused_vars, debug_info]). {ok,lager_default_tracer, <<70,79,82,49,0,0,6,164,66,69,65,77,65,116,85,56,0,0,1,9, 0,0,0,23,20,108,...>>}

    Die Variable B jetzt hält, als binäre, den kompilierten Code für die lager_default_tracer Modul.

  8. Entpacke den Abstraktionscode-Chunk aus dem in B gespeicherten kompiliert binary:

    7> {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(B,[abstract_code]). {ok,{lager_default_tracer, [{abstract_code, ... [{clause,0,[{var,0,'Event'}],[],[{call,...}]}]}]}}]}}

    Die Variable AC hält nun den Abstraktionscode.

  9. den abstrakten Code verwenden, um rekonstruierte Quellcode für das lager_default_tracer Modul zu drucken:

    8> io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]). -module(lager_default_tracer). -export([info/1, reset_counters/1, table/1, handle/1]). ... handle_(Event) -> gr_counter:update_counter(table(counters), filter, {2, 1}). ok

    Dieser letzte Schritt und derjenige, bevor es aus dem beam_lib documentation unter "Rekonstruieren Source Code" getroffen werden.

Wenig überraschend, das rekonstruierte Quellcode zeigt Anrufe von anderen goldrush Funktionen, so dass Sie Zugriff auf die goldrush sources benötigen, wenn Sie das rekonstruierte Code zu verstehen zu versuchen.