[lttng-dev] Test if tracepoint is enabled

David Bryant david.bryant at quantum.com
Wed Dec 5 20:19:16 EST 2012


On 05/12/12 20:49, Mathieu Desnoyers wrote:
> * David Bryant (david.bryant at quantum.com) wrote:
>> So, building on your example:
>>
>> #define tracepoint_cond(provider, name, pre, post, ...) \
>>      do { \
>>          if (caa_unlikely(__tracepoint_##provider##___##name.state)) { \
>>              pre \
>>              __tracepoint_cb_##provider##___##name(__VA_ARGS__); \
>>              post \
>>          } \
>>      } \
>>      while (0)
>>
>> And a contrived example:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int main() {
>>      char * a;
>>      tracepoint_cond(provider, name,
>>                      { printf("pre\n");  a = malloc(16); },
>>                      { printf("post\n"); free(a);        }
>>                     );
>>      return 0;
>> }
>>
>> This is ok. But more work with the macro handling would be required to
>> get the pre/post code fragments through as parameters. The example only
>> compiles because its pre/post arguments don't contain any commas.
>>
>> What do you think?
> I'm not sure what parameters would cause issues with commas. If they are
> between parenthesis or brackets, it should be fine. Do you have an
> example perhaps ?
Ok, I've just learnt what 'statement-expressions' are 
(http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html). Would this be 
the first use of these in lttng-ust? If so, I'm wary of making lttng-ust 
dependent on this gcc extension. Would it be dependent on this? It is up 
to the user to decide what to pass to the macro, but the macro may 
impose constraints by way of how the arguments are employed within the 
macro...

As it happens, we compile with -pedantic which won't allow 
statement-expressions. (As an aside, -pedantic doesn't like tracepoint 
that don't take any arguments because it expects the "..." to have at 
least one argument).

My example above (that doesn't use statement-expressions - I removed the 
round brackets) compiles correctly. But it you introduce a comma then 
the compiler seems to interpret this as an argument separator. So this 
works:

   #include <stdio.h>
   #include <stdlib.h>

   #define tracepoint_cond(provider, name, cond, pre, post, ...) \
       do { \
           if (caa_unlikely(__tracepoint_##provider##___##name.state)) { \
               if (cond) { \
                   pre \
__tracepoint_cb_##provider##___##name(__VA_ARGS__); \
                   post \
               } \
           } \
       } \
       while (0)

   int main() {
       int i = 1, j = 1;

       char * a;
       tracepoint_cond(provider, name,
                       i == j,  /* condition */
                       {   /* pre */
                       a = malloc(16);
                       memset(a, 0, 16);
                       },
                       {   /* post */
                       free(a);
                       int dummy1;
                       },
                       a
                      );
       return 0;
   }

But changing tracepoint_cond to this breaks it:

       tracepoint_cond(provider, name,
                       i == j,  /* condition */
                       {   /* pre */
                       a = malloc(16);
                       memset(a, 0, 16);
                       },
                       {   /* post */
                       free(a);
                       int dummy1, dummy2;  /* XXX */
                       },
                       a
                      );

Examining the pre-processed code reveals that the comma causes dummy2 to 
become a subsequent argument to the macro and land in the "..." region, 
and hell breaks loose.

Do you think we could come up with a scheme that doesn't impose the use 
of statement-expressions, but supports them if they are provided? In my 
example, I simply provide 'i == j' as the condition, but a 
statement-expression would also work. Are we conflating separate ideas - 
the idea of user conditions and the idea of setup/cleanup?

> While we are there, it would be good to make the "pre" handler test a
> condition. For your use-case, you would just have to pass a pre :
>
>   { printf("pre\n");  a = malloc(16); 1; }
>
> So we could do:
>
>     if (pre)
>          __tracepoint_cb_##provider##___##name(__VA_ARGS__);
>     (post)
>
> and therefore support not only to setup something, but also to add an
> extra check on whether tracing should be skipped or not. If someone
> passes "1" as end of the compound statement, it will always evaluate to
> 1, and therefore the compiler will remove any extra branch in -O2.
>
> One question stands though: how would we integrate this with sdt.h
> STAP_PROVEV() ?
I'm yet to look at this.

Thanks,
Dave

----------------------------------------------------------------------
The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt.



More information about the lttng-dev mailing list