erl_tracer, trace_status and pids

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

erl_tracer, trace_status and pids

Loïc Hoguin-3
Hello,

I am optimizing an erl_tracer tracer NIF. Can you give light on the
following questions? I tried to look into the source but want to double
check my understanding.

* trace_status is always called on enabled/3, not on enabled_*/3

* when you use enabled_*/3 and trace_*/5 functions for everything, the
trace/5 function will never be called

* trace_status is always called before any other enabled_*/3 so I should
be fine just doing nothing in enabled_*/3, right? I'm only checking that
the tracer processes are still alive anyway.

Basically if you could shed light on the circumstances around
trace_status that would help a lot for optimizing this. :-)

Another question, I have a pool of tracer processes and want to send the
events to one of them depending on the pid (all events of a pid gets to
the same tracer process). Is this a valid solution?

nth = (tracee.pid >> 4) % len;

This gives me the number of the tracer I will send the message to.

Thanks!

--
Loïc Hoguin
https://ninenines.eu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: erl_tracer, trace_status and pids

Lukas Larsson-8
Hello,

On Fri, May 26, 2017 at 2:41 PM, Loïc Hoguin <[hidden email]> wrote:

* trace_status is always called on enabled/3, not on enabled_*/3

yes
 
* when you use enabled_*/3 and trace_*/5 functions for everything, the trace/5 function will never be called
hmm, that should be true in the current implementation. That may change in the future though.
 
* trace_status is always called before any other enabled_*/3 so I should be fine just doing nothing in enabled_*/3, right? I'm only checking that the tracer processes are still alive anyway.

no, trace_status is not always called before enabled_*. The only event that I know of where it is called is enabled_call/3, there may be a couple of more but not all of them.
 
Basically if you could shed light on the circumstances around trace_status that would help a lot for optimizing this. :-)

the check for trace_status call is made in various places in the vm code where the VM finds it convenient to do a check and see if the tracer is still alive. There are no specific rules about when it is called.

Another question, I have a pool of tracer processes and want to send the events to one of them depending on the pid (all events of a pid gets to the same tracer process). Is this a valid solution?

nth = (tracee.pid >> 4) % len;

This gives me the number of the tracer I will send the message to.

It is one way to do it, but you are relying on the internal representation of a PID, which may change, and I don't think you get a very good hash.

In OTP-20 there is a new nif called enif_hash/3 that can be used to get a better hash value. (http://erlang.org/documentation/doc-9.0-rc1/erts-9.0/doc/html/erl_nif.html#enif_hash)

Lukas

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: erl_tracer, trace_status and pids

Loïc Hoguin-3
Thanks for the replies!

On 05/29/2017 01:26 PM, Lukas Larsson wrote:
>     * when you use enabled_*/3 and trace_*/5 functions for everything,
>     the trace/5 function will never be called
>
> hmm, that should be true in the current implementation. That may change
> in the future though.

I'll change it in the future then. :-)

>     * trace_status is always called before any other enabled_*/3 so I
>     should be fine just doing nothing in enabled_*/3, right? I'm only
>     checking that the tracer processes are still alive anyway.
>
>
> no, trace_status is not always called before enabled_*. The only event
> that I know of where it is called is enabled_call/3, there may be a
> couple of more but not all of them.

Alright. I'm a bit confused still. Would it make sense to only perform
some checks for trace_status, for example checking that the tracer
process exists? Then for other enabled_*/3 calls I would just reject
events I don't need.

>     Basically if you could shed light on the circumstances around
>     trace_status that would help a lot for optimizing this. :-)
>
>
> the check for trace_status call is made in various places in the vm code
> where the VM finds it convenient to do a check and see if the tracer is
> still alive. There are no specific rules about when it is called.

It sounds like the answer to my question is a yes. :-)

>     Another question, I have a pool of tracer processes and want to send
>     the events to one of them depending on the pid (all events of a pid
>     gets to the same tracer process). Is this a valid solution?
>
>     nth = (tracee.pid >> 4) % len;
>
>     This gives me the number of the tracer I will send the message to.
>
>
> It is one way to do it, but you are relying on the internal
> representation of a PID, which may change, and I don't think you get a
> very good hash.
>
> In OTP-20 there is a new nif called enif_hash/3 that can be used to get
> a better hash value.
> (http://erlang.org/documentation/doc-9.0-rc1/erts-9.0/doc/html/erl_nif.html#enif_hash)

Thanks, I will use it on OTP 20+ then.

--
Loïc Hoguin
https://ninenines.eu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: erl_tracer, trace_status and pids

Loïc Hoguin-3
On 05/30/2017 10:14 AM, Loïc Hoguin wrote:

>>     * trace_status is always called before any other enabled_*/3 so I
>>     should be fine just doing nothing in enabled_*/3, right? I'm only
>>     checking that the tracer processes are still alive anyway.
>>
>>
>> no, trace_status is not always called before enabled_*. The only event
>> that I know of where it is called is enabled_call/3, there may be a
>> couple of more but not all of them.
>
> Alright. I'm a bit confused still. Would it make sense to only perform
> some checks for trace_status, for example checking that the tracer
> process exists? Then for other enabled_*/3 calls I would just reject
> events I don't need.
>
>>     Basically if you could shed light on the circumstances around
>>     trace_status that would help a lot for optimizing this. :-)
>>
>>
>> the check for trace_status call is made in various places in the vm
>> code where the VM finds it convenient to do a check and see if the
>> tracer is still alive. There are no specific rules about when it is
>> called.
>
> It sounds like the answer to my question is a yes. :-)

Answering myself.

I think what I was looking for can be found in this sentence of the
documentation:

"It is called in multiple scenarios, but most significantly it is used
when tracing is started using this tracer."

If correct, then this means trace_status is always called at least once
before anything happens; and that's good enough for me. That would allow
me to remove traces for the tracer processes immediately when receiving
the trace_status, and not have to worry about that in enabled_*/3 calls.

Cheers,

--
Loïc Hoguin
https://ninenines.eu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: erl_tracer, trace_status and pids

Lukas Larsson-8
On Tue, May 30, 2017 at 11:40 AM, Loïc Hoguin <[hidden email]> wrote:
On 05/30/2017 10:14 AM, Loïc Hoguin wrote:
    * trace_status is always called before any other enabled_*/3 so I
    should be fine just doing nothing in enabled_*/3, right? I'm only
    checking that the tracer processes are still alive anyway.


no, trace_status is not always called before enabled_*. The only event that I know of where it is called is enabled_call/3, there may be a couple of more but not all of them.

Alright. I'm a bit confused still. Would it make sense to only perform some checks for trace_status, for example checking that the tracer process exists? Then for other enabled_*/3 calls I would just reject events I don't need.

    Basically if you could shed light on the circumstances around
    trace_status that would help a lot for optimizing this. :-)


the check for trace_status call is made in various places in the vm code where the VM finds it convenient to do a check and see if the tracer is still alive. There are no specific rules about when it is called.

It sounds like the answer to my question is a yes. :-)

Answering myself.

I think what I was looking for can be found in this sentence of the documentation:

"It is called in multiple scenarios, but most significantly it is used when tracing is started using this tracer."

If correct, then this means trace_status is always called at least once before anything happens; and that's good enough for me. That would allow me to remove traces for the tracer processes immediately when receiving the trace_status, and not have to worry about that in enabled_*/3 calls.

It is not overly clear/correct in the docs. One purpose of trace_status was that it and only it should be able to remove tracers from the tracee. There are assertions in the code that prohibit trace nifs from returning 'remove' from any event other then trace_status. However, those are only triggered in debug builds. The current non-debug code and to some extent docs seems to allow enabled_*/3 calls to also remove tracers from tracees.

Writing clear and concise documentation is hard.

Lukas

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions