erlang에서 seq_trace를 현재 실행중인 프로세스로 설정할 수 있음을 이해합니다. 그러나 셸이나 dbg 추적과 같은 원격 셸에서 다른 프로세스를 설정하려면 어떻게해야합니까?다른 프로세스에서 seq_trace 설정
답변
dbg
을 사용하여 다른 프로세스에서 순차적 추적을 사용할 수 있습니다. 예를 들어, 우리가 보낸 call/2
기능 모듈 x
있다고 가정 해 봅시다 :
call(Pid, Msg) ->
Pid ! {self(), Msg},
receive
{Pid, Reply} -> Reply
end.
이 기능은 간단한 전화 응답을 구현합니다.
loop() ->
receive
{Pid, Msg} ->
seq_trace:print({?MODULE, self(), Pid, Msg}),
Pid ! {self(), {Msg, os:timestamp()}};
_ -> ok
end,
?MODULE:loop().
이 기능은 x:call/2
에서 전송 형식의 메시지를 기대하고, 하나를받을 때 활성화 된 경우는, 순차적 추적에 메시지를 출력 :의는 또한 우리가 반복 수신 기능을 가진 모듈 y
있다고 가정 해 봅시다 , 원래의 메시지를 타임 스탬프로 보완 된 호출자에게 되돌려 보냅니다. 다른 모든 메시지를 무시합니다.
또한 순차 추적을 수집하는 기능이 필요합니다. 아래의 재귀 systracer/1
기능은 목록에 seq_trace
튜플를 수집하고 물었을 때 seq_trace
메시지의 목록을 생성합니다
systracer(Acc) ->
receive
{seq_trace,_,_,_}=S ->
systracer([S|Acc]);
{seq_trace,_,_}=S ->
systracer([S|Acc]);
{dump, Pid} ->
Pid ! lists:reverse(Acc),
systracer([]);
stop -> ok
end.
이의 우리의 systracer/1
기능뿐만 아니라 모듈 x
에서 내 보낸 가정하자.
Erlang 쉘을 사용하여이 모든 것을 설정해 보겠습니다. 먼저, y:loop/0
및 x:systracer/1
를 생성하자
1> Y = spawn(y,loop,[]).
<0.36.0>
2> S = spawn(x,systracer,[[]]).
<0.38.0>
3> seq_trace:set_system_tracer(S).
false
x:systracer/1
산란 후 우리는 seq_trace
시스템 추적 등의 과정을 설정합니다.
4> dbg:tracer(), dbg:p(all,call).
{ok,[{matched,[email protected],28}]}
이 dbg
호출이 꽤 표준,하지만 당신은뿐만 아니라 디버그 세션 동안 dbg
추적을 사용할 계획 특히 당신은 필요에 따라 다양하게 자유롭게 느낄 수있다 : 이제 우리는 dbg
를 시작해야합니다.
dbg
을 사용하여 순차적 추적을 활성화 할 때 실제로는 함수에 대한 특정 인수를 입력하여 수행합니다. 이를 통해 특정 함수 호출의 모든 호출에 대한 추적을 가져 오지 않고 해당 함수 호출에 특정한 추적을 얻을 수 있습니다. 이 라인을 따라 x:call/2
이 두 번째 인수의 값이 원자 trace
인 경우 호출 할 때 dbg:tpl/3
을 사용하여 순차 추적 플래그를 켭니다. 첫째, 우리는 우리가 원하는 순차적 추적 플래그를 사용하려면 적절한 매치 사양을 만들 dbg:fun2ms/1
를 사용하여, 우리는 dbg:tpl/3
와 일치 사양을 적용 할 수 있습니다 :
5> Ms = dbg:fun2ms(fun([_,trace]) -> set_seq_token(send,true), set_seq_token('receive',true), set_seq_token(print,true) end).
[{['_',trace],
[],
[{set_seq_token,send,true},
{set_seq_token,'receive',true},
{set_seq_token,print,true}]}]
6> dbg:tpl(x,call,Ms).
{ok,[{matched,[email protected],1},{saved,1}]}
이제 우리는 원인 두 번째 인수 trace
와 x:call/2
를 호출 할 수 있습니다 순차적 추적이 발생합니다. 우리가 이전에 dbg:p(all, call)
을 지정한 이후
7> spawn(fun() -> x:call(Y, trace), x:call(Y, foo) end).
(<0.46.0>) call x:call(<0.36.0>,trace)
<0.46.0>
출력의 첫 번째 라인은 정상 dbg
추적에서 온다 : 우리는 생성 된 프로세스에서이 호출이 쉘에게 결과 추적에 나타나는 I/O 관련 메시지를 것을 방지 할 수 있습니다.순차적 인 추적 결과를 얻으려면, 우리는 우리의 systrace/1
과정에서 덤프를 얻을 필요가 :
8> S ! {dump, self()}.
{dump,<0.34.0>}
이것은 우리의 쉘 프로세스에 지금까지 수집 된 모든 순차적 인 추적을 보낸다. 우리는 그들을 볼 수 쉘 flush()
명령을 사용할 수 있습니다
9> flush().
Shell got [{seq_trace,0,{send,{0,1},<0.47.0>,<0.36.0>,{<0.47.0>,trace}}},
{seq_trace,0,{'receive',{0,1},<0.47.0>,<0.36.0>,{<0.47.0>,trace}}},
{seq_trace,0,{print,{1,2},<0.36.0>,[],{y,<0.36.0>,<0.47.0>,trace}}},
{seq_trace,0,
{send,{1,3},
<0.36.0>,<0.47.0>,
{<0.36.0>,{trace,{1423,709096,206121}}}}},
{seq_trace,0,
{'receive',{1,3},
<0.36.0>,<0.47.0>,
{<0.36.0>,{trace,{1423,709096,206121}}}}},
{seq_trace,0,{send,{3,4},<0.47.0>,<0.36.0>,{<0.47.0>,foo}}},
{seq_trace,0,{'receive',{3,4},<0.47.0>,<0.36.0>,{<0.47.0>,foo}}},
{seq_trace,0,{print,{4,5},<0.36.0>,[],{y,<0.36.0>,<0.47.0>,foo}}},
{seq_trace,0,
{send,{4,6},
<0.36.0>,<0.47.0>,
{<0.36.0>,{foo,{1423,709096,206322}}}}},
{seq_trace,0,
{'receive',{4,6},
<0.36.0>,<0.47.0>,
{<0.36.0>,{foo,{1423,709096,206322}}}}}]
그리고 확실히 충분히, 이들은 우리가 볼 것으로 예상되는 순차적 인 추적 메시지입니다. 먼저 trace
원자를 포함하는 메시지의 경우 x:call/2
에서 수신하고 y:loop/0
에서 수신하고 seq_trace:print/1
의 결과를 보낸 다음 y:loop/0
에서 x:call/2
의 발신자에게 다시 보냅니다. 그런 다음 x:call(Y,foo)
이 동일한 프로세스에서 호출되었으므로 모든 순차 추적 플래그가 여전히 사용 가능하므로 순차 추적 메시지의 첫 번째 세트에는 x:call(Y,foo)
호출에 대한 유사한 세트가 뒤 따른다. 우리가 x:call(Y,foo)
를 호출하는 경우
우리는 우리가 더 순차적 인 추적 메시지를 얻을 볼 수 있습니다 : 우리의 일치 스펙 x:call/2
에 두 번째 인수는 원자 trace
이다 순차 추적을 가능하게하기 때문에
10> spawn(fun() -> x:call(Y, foo) end).
<0.55.0>
11> S ! {dump, self()}.
{dump,<0.34.0>}
12> flush().
Shell got []
이입니다.
자세한 내용은 seq_trace
및 dbg
매뉴얼 페이지 및 match specification chapter of the Erlang Run-Time System Application (ERTS) User's Guide을 참조하십시오.
매우 차갑고, 내가 뭘했는지 정확하게. –
죄송합니다 - 왜 이것을 Elixir에 표시하셨습니까? 내가 누락 된 엘릭서의 요소가 여기 있니? –
기본적으로 깔끔한 태그 뽑기. Erlang 도구는 엘릭서 용으로도 사용할 수 있으므로 엘 립서에서 사용하는 사람은 누구나이 질문에 답할 수 있습니다. –