2015-02-05 2 views
3

erlang에서 seq_trace를 현재 실행중인 프로세스로 설정할 수 있음을 이해합니다. 그러나 셸이나 dbg 추적과 같은 원격 셸에서 다른 프로세스를 설정하려면 어떻게해야합니까?다른 프로세스에서 seq_trace 설정

+0

죄송합니다 - 왜 이것을 Elixir에 표시하셨습니까? 내가 누락 된 엘릭서의 요소가 여기 있니? –

+0

기본적으로 깔끔한 태그 뽑기. Erlang 도구는 엘릭서 용으로도 사용할 수 있으므로 엘 립서에서 사용하는 사람은 누구나이 질문에 답할 수 있습니다. –

답변

3

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/0x: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}]} 

이제 우리는 원인 두 번째 인수 tracex: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_tracedbg 매뉴얼 페이지 및 match specification chapter of the Erlang Run-Time System Application (ERTS) User's Guide을 참조하십시오.

+0

매우 차갑고, 내가 뭘했는지 정확하게. –