Re: libtraceevent | API clarifications needed

"MOESSBAUER, Felix" <[email protected]> Wed, 3 Dec 2025 11:20:34 +0000
Newsgroups org.kernel.vger.linux-trace-devel
Message-ID <[email protected]>
On Tue, 2025-12-02 at 11:25 -0500, Steven Rostedt wrote:
> On Mon, 1 Dec 2025 15:38:32 +0000
> "MOESSBAUER, Felix" <[email protected]> wrote:
> 
> > Dear tracers,
> > 
> > while continuing the development of the ftrace-to-ctf converter [1], I
> > noticed the following in the traceevent API that needs some
> > clarification:
> > 
> > half-length signed integers
> > 
> > What is the recommended way to read a field value that is a half-length
> > (i.e. 32 bit) or smaller signed integer? Currently, I'm using the
> > tep_get_field_val which returns the value as unsigned long long
> > (usually 8 byte). This value contains the raw bits (endian-corrected),
> > hence a int32_t (-1) is represented as FFFF FFFF. I'm currently
> > manually converting this, but I'm wondering if there is a better way of
> > doing it.
> 
> First I'll say that I absolutely hate the libtraceevent interface.
> Unfortunately, it was ported over to perf before it was "sanitized". But oh
> well, I have to live with it. I would love to come up with a new interface
> that would make all this easier.

No need for excuses. The library is great and tremendously simplifies
working with trace events. Thank you!

> 
> Yes, the caller of tep_get_field_val() needs to know the sign and handle
> the result. Hmm, I wonder if we did look at the field to determine if it is
> signed or not and sign extend if it is, if that would break any
> applications :-/

The information is at least parsed as the field flag
TEP_FIELD_IS_SIGNED is set.

> 
> 
> 
> > 
> > 
> > arrays of integers
> > 
> > The only API I found to read int[x] types (arrays of integers) is
> > tep_get_field_raw. However, this just gives me the raw bytes of the
> > trace buffer. Does it mean I need to take care of endian correctness?
> > Are trace buffers always little-endian, or is this an implementation
> > detail?
> 
> Correct, it's simply a pointer to the raw value in the data record. The
> caller is responsible for handling endianess. The endianess of the source
> can be found with: tep->file_bigendian;
> 
> If tep->file_bigendian != tep_is_bigendian() then a swap is needed.

Ok, but I just found the tep_read_number() interface which I'm now
using as following:

data_raw=tep_get_field_raw(NULL, trace_event, field->name, rec, &len,
0);
item_size=len / field->arraylen;
val=tep_read_number(field->event->tep, &data_raw[i * item_size], len);

This should also do the job, as tep_read_number() takes care of the
endianess handling.

> 
> > 
> > unbounded arrays
> > 
> > These arrays have both their size= and arraylen= attributes set to 0.
> > How do I know how wide the types are? Especially given that the type
> > names (e.g. unsigned long) are platform specific? An example event is
> > "funcgraph_entry" with format ... "field:unsigned long args[];    
> > offset:24;      size:0; signed:0;"
> 
> Note, the unbounded arrays are only for ftrace manually defined events.
> They are not available for normal trace events (event created by the
> TRACE_EVENT() macro). They do need to be manually handled.

Ok, thanks for the clarification.

> 
> > 
> > symbolic fields
> > 
> > How to get the symbolic representation of fields that are marked
> > TEP_FIELD_IS_SYMBOLIC (example: softirq_entry->vec)? I tried
> > tep_print_field_content, but this converts the data to a string integer
> > instead of the symbolic representation (e.g. I get a "0" instead of a 
> > "HI").
> 
> This is something I even wanted, but there's not really a good way to do
> it. Although, I wanted a generic way, but if a field is marked symbolic, we
> could use that. That is, we would need to parse the print_fmt array itself,
> and find the:
> 
>  "__print_symbolic(REC->vec, { 0, "HI" }, { 1, "TIMER" }, { 2, "NET_TX" }, { 3, "NET_RX" }, { 4, "BLOCK" }, { 5, "IRQ_POLL" }, { 6, "TASKLET" }, { 7, "SCHED" }, { 8, "HRTIMER" }, { 9, "RCU" })"
> 
> That is, look for the "__print_symbolic(REC->[FIELD-NAME], ..." and parse that.

The trace-cmd report seems to be able to symbolize this, as well as
symbolizing instruction pointers (e.g. the caller field of the ftrace
kernel_stack). Not that I currently need this, but I'm wondering how
trace-cmd is able to do this. Probably need to check the sources.

Best regards,
Felix

> 
> Hmm,
> 
> -- Steve
> 

-- 
Siemens AG
Linux Expert Center
Friedrich-Ludwig-Bauer-Str. 3
85748 Garching, Germany