2012-03-20 2 views
0

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

E.g.

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“след должен соответствовать последней„называют“след я получил. Поэтому, эта трасса «return_from» должна иметь имя события последней полученной мной «вызова», полученную мной »:

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

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

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

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

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

Другая спецификация, помещенная в F1 (через спецификацию соответствия, используемую в erlang: trace_pattern/3), заключается в том, что, например, когда F1 вызывается с аргументом 20, генерируемая трассировка вызова должна иметь имя события " is_twenty ", а return_trace() должен быть сгенерирован после трассировки вызова. Таким образом, процесс получения сообщения трассировки будут получать:

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

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

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

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

Теперь, если A начинает оценивать F1 (с аргументом arg 10), генерирует трассировку «вызов», выгружается, B начинает оценивать F1 (с аргументом 20), генерирует трассировку «вызов», выгружается, 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» след сообщение соответствует последнему «звонку 'message, он присвойт event_name' is_twenty 'сообщению return_from, когда на самом деле это должно быть' is_ten '.

ответ

1

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

E.g.

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

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

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

и

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

, когда мод: суб/2 вызывается с num1 и Num2 таким образом, что num1 < Num2. Во всех остальных случаях, генерируемый след будет:

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

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

2

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

{след, Pid, ​​return_from, {M, F, Arity}, ReturnValue}

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

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

{след, Pid, ​​вызов, {M, F, Args}}

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

+0

Я действительно думал о «корреляции» двух сообщений трассировки, но это не сработает для моих целей. (Этот раздел комментариев немного ограничивает объяснение ... в основном, у меня может быть более одного типа трассировки (каждый с другим «event_name») для ввода функции, но если событие для возврата из функции doesn ' у меня есть имя, как бы я связал эти два?). Спасибо за ответ в любом случае tzp. – justin

+0

Ну, я все еще думаю, что _almost_ все возможно с ** pan ** callback-модулями. Например. вы видите вызов mod: mul (4,5) call, сделанный процессом P, теперь вы можете сохранить это с тегами с любой необходимой информацией, такой как операция, аргументы, например. магазин {{P, last_call}, {mod, mul, [4,5]}}. Затем вы увидите следующее сообщение _P, return_from, {mod, mul, 2}, 20_, затем найдите {P, last_call} и продолжайте ... – tzp

+0

Хорошо, теперь я понимаю.Вы говорите: «Не просто предположите, что сообщение return_from соответствует последнему сообщению« звонок », которое вы получили, но фактически храните каждый полученный вами вызов (вместе с pid процесса, который его создал), а затем, когда вы получаете a 'return_from' ищет «вызов», когда pid соответствует «return_from». Звучит выполнимо, но есть слишком много проблем с этим подходом к тому, что я делаю 1. эффективность 2. как вы знаете, что процесс didn ' t crash и никогда не генерировал «return_from» и т. д. Тем не менее, это может быть один из способов. Спасибо еще раз. – justin

Смежные вопросы