Есть ли способ добавлять сообщения при использовании return_trace ()? - PullRequest
0 голосов
/ 20 марта 2012

Я подозреваю, что ответ, вероятно, "нет", но на всякий случай, есть ли способ добавить данные в отслеживаемое событие при использовании return_trace ()?

Например,

1> erlang:trace(all, true, [call]).
...
2> MatchSpec = dbg:fun2ms(fun([Num1, Num2]) when Num1 < Num2 -> 
                     return_trace(), message({event_name, neg_sub_event}); 
                   (_) -> 
                     return_trace(), message({event_name, sub_event}) end).
...
3> erlang:trace_pattern({mod, sub, 2}, MatchSpec, [local]).
...
4> flush().
ok
5> spawn(mod, sub, [4, 5]).
...
6> flush().
Shell got {trace,<0.64.0>,call,
             {mod,sub,[4,5]},
             {event_name,neg_sub_event}}
Shell got {trace,<0.64.0>,return_from,{mod,sub,2},-1}
ok
7> spawn(mod, sub, [6, 5]).
...
8> flush().
Shell got {trace,<0.67.0>,call,{mod,sub,[6,5]},{event_name,sub_event}}
Shell got {trace,<0.67.0>,return_from,{mod,sub,2},1}
ok

Я только что придумал пример, не задумываясь об этом ... в этом случае я мог выяснить, является ли это neg_sub_event или sub_event из возвращаемого значения, включенного в трассировку return_from ... но дело в том, что я хотел бывключить {event_name, Name} не только при возникновении события вызова, но и при создании события return_from.

Возможно ли это даже?

Спасибо.

Редактировать

Вот почему я не могу просто получить трассировку 'return_from' и сказать "хорошо, поэтому эта трассировка" return_from "должна соответствовать последней трассе" call ", которую я получил. Поэтомуэта трассировка 'return_from' должна иметь имя_символа последней полученной трассировки 'call':

Рассмотрим 2 процесса A и B. Оба вызывают функцию F1, которая отслеживается со спецификацией, которая утверждает, что в одномсазe (например, F1 вызывается с аргументом 10), сгенерированная трассировка вызова должна иметь имя-события event_ten, а return_trace () должна быть сгенерирована после трассировки вызова.Следовательно, процесс, получающий сообщения трассировки, получит:

{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_ten}}

, когда F1 вызывается с аргументом 10, и

{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}

, когда F1 вызывается с аргументом 10,вычисляется и возвращается.

Другая спецификация, помещенная в F1 (через спецификацию соответствия, используемую в erlang: trace_pattern / 3), заключается в том, что, например, когда F1 вызывается с аргументом 20, трассировка 'call'сгенерированный должен иметь имя-события «is_twenty», и return -trace () должен быть сгенерирован после трассировки вызова.Следовательно, процесс, получающий сообщения трассировки, получит:

{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_twenty}}

, когда F1 вызывается с аргументом 20, и

{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}

, когда F1 вызывается с аргументом 20,вычисляется и возвращается.

Теперь, если A начинает оценивать F1 (с аргументом 10), генерирует трассировку 'call', выгружается, B начинает оценивать F1 (с аргументом 20), генерирует трассировку 'call',выгружается, A завершает оценку F1 и генерирует трассировку return_from, процесс, получающий сообщения трассировки, получит:

{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_ten}}
{trace, Pid, call, {Mod, Fun, Args}, {event_name, is_twenty}}
{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}

На этом этапе, если процесс, получающий сообщения трассировки, предполагает, что каждый return_from'trace message соответствует последнему полученному сообщению' call ', он назначит имя_события' is_twenty 'сообщению return_from, хотя на самом деле это должно быть' is_ten '.

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Согласно документу для erlang: trace / 3 ,

{trace, Pid, ​​return_from, {M, F, Arity}, ReturnValue}

отправлено в процесс трассировки, поэтому я думаю, что вы не можете прикрепить больше данных. (Ну, очевидный взлом, если возвращаемое значение содержит аргумент вызова ... но это было бы ужасно.)

Однако, если вы выполняете трассировку с отслеживанием состояния (то есть отслеживаете последовательность сообщений трассировки), то вы можете сопоставить

{trace, Pid, ​​call, {M, F, Args}}

сообщение с последующим return_from выше. Вы можете использовать, например, pan для этого с модулем обратного вызова, см. мой другой пост .

1 голос
/ 22 марта 2012

Нет. Вы можете добавить дополнительную информацию в трассировку 'call', используя message (Data) в MatchSpec. Кроме того, при написании тела спецификации вы можете добавить return_trace (). Это сгенерирует сообщение трассировки return_from при возврате отслеживаемой функции, НО, в отличие от сообщения трассировки, которое отправляется при вызове рассматриваемой функции, вы не можете добавить дополнительную информацию к сообщению трассировки, которое отправляется, когда функция в возвращается вопрос.

* 1003 Е.Г. *

dbg:fun2ms(fun([Num1, Num2]) when Num1 < Num2 -> 
                 return_trace(), message({event_name, neg_sub_event}); 
               (_) -> 
                 message({event_name, sub_event}) end).

Спецификация соответствия, сгенерированная выше, применительно к функции mod: sub / 2 с использованием erlang: trace_pattern ({mod, sub, 2}, MatchSpec, [local]), сгенерирует следующие события трассировки (когда отслеживаемые процессы включите флаг 'call', используя erlang: trace / 3):

{trace, Pid, call, {Mod, Fun, Args}, {event_name, neg_sub_event}}

и

{trace, Pid, return_from, {Mod, Fun, Arity}, ReturnVal}

когда mod: sub / 2 вызывается с Num1 и Num2, так что Num1

{trace, Pid, call, {Mod, Fun, Args}, {event_name, sub_event}}

Таким образом, вы не можете добавить дополнительную информацию, такую ​​как "{event_name, Name}", к трассировке 'return_from', потому что нет способа указать это в спецификации соответствия.

...