让Erlang自动编译并加载代码
- Andy - Intridea East Blog最近参与的项目使用了ejabberd,得此锲机第一次接触了Erlang. 作为一个函数式编程语言(functional language),除了函数式语言本身特点之外,
因为Erlang是为分布式,高并发,高容错系统量身设计的,所以也有一些属于自己的独门秘籍. 譬如热更新(hot swapping): 系统可以在运行过程中替换部分代码,更神奇的是,新旧代码还可以部分共存.
原创文章,转载请注明: 转载自Erlang非业余研究
本文链接地址: Erlang代码反编译以及查看汇编码
Erlang的代码是先翻译成abstract_code,再到目标代码的,如果有符号信息很容易恢复源代码,通常我们部署系统的时候需要把符号信息去掉,reltool就可以干这个事情!
我们演示下:
$ cat server.erl -module(server). -compile(export_all). start() -> start(1234). start(Port) -> register(?MODULE, self()), spawn_link(fun ()-> S= listen(Port), accept(S) end), receive Any -> io:format("~p~n", [Any]) end. %% to stop: test!stop. listen(Port) -> Opts = [{active, false}, binary, {backlog, 256}, {packet, raw}, {reuseaddr, true}], {ok, S} = gen_tcp:listen(Port, Opts), S. accept(S) -> case gen_tcp:accept(S) of {ok, Socket} -> spawn_opt(?MODULE, loop, [Socket,0], []); Error -> erlang:error(Error) end, accept(S). loop(S, N) -> case gen_tcp:recv(S, 1024) of {ok, _Data} -> io:format("~p got ~w, ~w~n",[S, size(_Data), N]), timer:sleep(100), loop(S, N+1); Error -> io:format("tcp ~p~n", [Error]), Error end. $ erlc +debug_info server.erl $ erl Erlang R14B04 (erts-5.8.5) 1 [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.5 (abort with ^G) 1> f(),{ok, {_, [{abstract_code, {_,Abs}}]}} = beam_lib:chunks("server.beam", [abstract_code]),io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(Abs))]). -file("./server.erl", 1). -module(server). -compile(export_all). start() -> start(1234). start(Port) -> register(server, self()), spawn_link(fun () -> S = listen(Port), accept(S) end), receive Any -> io:format("~p~n", [Any]) end. listen(Port) -> Opts = [{active, false}, binary, {backlog, 256}, {packet, raw}, {reuseaddr, true}], {ok, S} = gen_tcp:listen(Port, Opts), S. accept(S) -> case gen_tcp:accept(S) of {ok, Socket} -> spawn_opt(server, loop, [Socket, 0], []); Error -> erlang:error(Error) end, accept(S). loop(S, N) -> case gen_tcp:recv(S, 1024) of {ok, _Data} -> io:format("~p got ~w, ~w~n", [S, size(_Data), N]), timer:sleep(100), loop(S, N + 1); Error -> io:format("tcp ~p~n", [Error]), Error end. ok 2>
想查看模块的汇编码,也很容易,这样就好:
$ erl Erlang R14B04 (erts-5.8.5) 1 [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.5 (abort with ^G) 1> erts_debug:df(server). ok 2> $ cat server.dis 0117F108: i_func_info_IaaI 0 server start 0 0117F11C: i_move_call_only_fcr server:start/1 1234 x(0) 0117F128: i_func_info_IaaI 0 server start 1 0117F13C: allocate_zero_tt 1 1 0117F144: self_x x(1) 0117F14C: move_ry x(0) y(0) 0117F154: move_cr server x(0) 0117F15C: call_bif2_e erlang:register/2 0117F164: move_yr y(0) x(0) 0117F16C: i_make_fun_It 18102836 1 0117F178: init_y y(0) 0117F180: i_call_ext_e erlang:spawn_link/1 0117F188: i_loop_rec_fr f(0117F1B8) x(0) 0117F190: remove_message 0117F194: test_heap_It 2 1 0117F1A0: put_list_rnx x(0) [] x(1) 0117F1A8: i_move_call_ext_last_ePcr io:format/2 1 "~p~n" x(0) 0117F1B8: wait_locked_f f(0117F188) 0117F1C0: i_func_info_IaaI 0 server listen 1 0117F1D4: allocate_tt 0 1 0117F1DC: move_x1_c [{active,false},binary,{backlog,256},{packet,raw},{reuseaddr,true}] 0117F1E4: i_call_ext_e gen_tcp:listen/2 0117F1EC: is_tuple_of_arity_frA f(0117F218) x(0) 2 0117F1F8: extract_next_element2_x x(1) 0117F200: i_is_eq_exact_immed_fxc f(0117F218) x(1) ok 0117F210: move_deallocate_return_xrQ x(2) x(0) 0 0117F218: badmatch_r x(0) 0117F21C: i_func_info_IaaI 0 server accept 1 0117F230: allocate_tt 1 1 0117F238: move_ry x(0) y(0) 0117F240: i_call_ext_e gen_tcp:accept/1 0117F248: is_tuple_of_arity_frA f(0117F2AC) x(0) 2 0117F254: extract_next_element2_x x(1) 0117F25C: i_is_eq_exact_immed_fxc f(0117F2AC) x(1) ok 0117F26C: test_heap_It 2 3 0117F278: put_list_xcx x(2) [0] x(2) 0117F284: move_x1_c loop 0117F28C: move_nx [] x(3) 0117F294: i_move_call_ext_cre server x(0) erlang:spawn_opt/4 0117F2A0: move_call_last_yrfQ y(0) x(0) server:accept/1 1 0117F2AC: call_bif1_e erlang:error/1 0117F2B4: i_func_info_IaaI 0 server loop 2 0117F2C8: allocate_tt 2 2 0117F2D0: move_xy x(1) y(0) 0117F2D8: move_x1_c 1024 0117F2E0: move_ry x(0) y(1) 0117F2E8: i_call_ext_e gen_tcp:recv/2 0117F2F0: is_tuple_of_arity_frA f(0117F388) x(0) 2 0117F2FC: extract_next_element2_x x(1) 0117F304: i_is_eq_exact_immed_fxc f(0117F388) x(1) ok 0117F314: i_gc_bif1_jIsId j(00000000) 151104 x(2) 3 x(0) 0117F32C: test_heap_It 6 3 0117F338: put_list_ynx y(0) [] x(2) 0117F340: put_list_rxr x(0) x(2) x(0) 0117F348: put_list_yrx y(1) x(0) x(1) 0117F350: i_move_call_ext_cre "~p got ~w, ~w~n" x(0) io:format/2 0117F35C: i_move_call_ext_cre 100 x(0) timer:sleep/1 0117F368: i_increment_yIId y(0) 1 0 x(1) 0117F37C: move_call_last_yrfQ y(1) x(0) server:loop/2 2 0117F388: test_heap_It 2 1 0117F394: move_ry x(0) y(1) 0117F39C: put_list_ynx y(1) [] x(1) 0117F3A4: i_trim_I 1 0117F3AC: i_move_call_ext_cre "tcp ~p~n" x(0) io:format/2 0117F3B8: move_deallocate_return_yrQ y(0) x(0) 1 0117F3C0: i_func_info_IaaI 0 server module_info 0 0117F3D4: move_cr server x(0) 0117F3DC: allocate_tt 0 1 0117F3E4: call_bif1_e erlang:get_module_info/1 0117F3EC: deallocate_return_Q 0 0117F3F4: i_func_info_IaaI 0 server module_info 1 0117F408: move_rx x(0) x(1) 0117F410: move_cr server x(0) 0117F418: allocate_tt 0 2 0117F420: call_bif2_e erlang:get_module_info/2 0117F428: deallocate_return_Q 0 0117F430: i_func_info_IaaI 0 server '-start/1-fun-0-' 1 0117F444: allocate_tt 0 1 0117F44C: i_call_f server:listen/1 0117F454: i_call_last_fP server:accept/1 0
了解更多汇编码,请参考这里
祝玩得开心!
Post Footer automatically generated by wp-posturl plugin for wordpress.