LIBTRACEEVENT(3)

πŸ’– LIBTRACEEVENT(3) β€” the tep_register_event_handler / tep_unregister_event_handler era πŸ’–

okay bestie, sit DOWN, because this one is the libtraceevent manual page and it's lowkey iconic. we're talking tep_register_event_handler and tep_unregister_event_handler β€” aka the functions that register or unregister a callback function to parse event info. that's the whole vibe. periodt. ✨


🌸 NAME 🌸

tep_register_event_handler, tep_unregister_event_handler β€” register / unregisters a callback function to parse an event information.

(no cap, that's literally what they do. the way that it says "unregisters a callback function to parse an event information"? yeah. we keep it.)


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <event-parse.h>

enum tep_reg_handler {
        TEP_REGISTER_SUCCESS,
        TEP_REGISTER_SUCCESS_OVERWRITE,
};

int tep_register_event_handler(struct tep_handle *tep, int id, const char *sys_name, const char *event_name, tep_event_handler_func func, void *context);
int tep_unregister_event_handler(struct tep_handle *tep, int id, const char *sys_name, const char *event_name, tep_event_handler_func func, void *context);

typedef int (*tep_event_handler_func)(struct trace_seq *s, struct tep_record *record, struct tep_event *event, void *context);

like, look at those signatures. GORGEOUS. no notes. πŸ’…


πŸ’œ DESCRIPTION πŸ’œ

so, tep_register_event_handler() registers a handler function, and that function is the one that's gonna get called to parse the information for a given event. that's the whole point.

let's break down the cast, because every one of these has main character energy:

  • the tep argument β€” that's the trace event parser context.
  • the id argument β€” that's the id of the event.
  • the sys_name argument β€” that's the name of the system the event belongs to.
  • the event_name argument β€” that's the name of the event.
  • the func β€” a pointer to the function that's going to be called to parse the event information.
  • the context argument β€” a pointer to the context data, which will be passed to the func.

now the important lore: if id is >= 0, it gets used to find the event. otherwise sys_name and event_name are used instead. your choice, bestie. ✨

AND β€” if a handler function for the same event is already registered? it gets overridden with the new one. big yikes / big slay depending on your intentions. this mechanism literally exists so a developer can override the parsing of a given event. so if for some reason the default print format is just not serving, the developer can register a function for an event and use that to parse the data instead. upgrade era. πŸ”₯

tep_unregister_event_handler() does the opposite thing β€” it unregisters the handler function you previously registered with tep_register_event_handler(). the tep argument is the trace event parser context, and id, sys_name, event_name, func, and context are the same arguments as when the callback function func was registered. consistency, we love her. πŸŽ€

tep_event_handler_func is the type of the custom event handler function. here's who's who:

  • s β€” the trace sequence. you can use it to create a custom string describing the event. cute, custom, yours.
  • a record to get the event from is passed as an input parameter, and also the event β€” the handle to the record's event.
  • context β€” custom context, set when the custom event handler was registered.

⭐ RETURN VALUE ⭐

tep_register_event_handler() returns:

  • TEP_REGISTER_SUCCESS if the new handler registered successfully ✨
  • TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler got overwritten
  • TEP_ERRNO__MEM_ALLOC_FAILED if there's not enough memory to complete the registration (😭 the absolute disrespect of running out of memory)

tep_unregister_event_handler() returns:

  • 0 if func was removed successful
  • -1 if the event was not found

and tep_event_handler_func should return -1 in case of an error, or 0 otherwise.


🌈 EXAMPLE 🌈

okay here's the actual code, showing off the whole vibe. this is the hrtimer handler situation:

#include <event-parse.h>
#include <trace-seq.h>
...
struct tep_handle *tep = tep_alloc();
...
int timer_expire_handler(struct trace_seq *s, struct tep_record *record,
                         struct tep_event *event, void *context)
{
        trace_seq_printf(s, "hrtimer=");

        if (tep_print_num_field(s, "0x%llx", event, "timer", record, 0) == -1)
                tep_print_num_field(s, "0x%llx", event, "hrtimer", record, 1);

        trace_seq_printf(s, " now=");

        tep_print_num_field(s, "%llu", event, "now", record, 1);

        tep_print_func_field(s, " function=%s", event, "function", record, 0);

        return 0;
}
...
        int ret;

        ret = tep_register_event_handler(tep, -1, "timer", "hrtimer_expire_entry",
                                         timer_expire_handler, NULL);
        if (ret < 0) {
                char buf[32];

                tep_strerror(tep, ret, buf, 32)
                printf("Failed to register handler for hrtimer_expire_entry: %s\n", buf);
        } else {
                switch (ret) {
                case TEP_REGISTER_SUCCESS:
                        printf ("Registered handler for hrtimer_expire_entry\n");
                        break;
                case TEP_REGISTER_SUCCESS_OVERWRITE:
                        printf ("Overwrote handler for hrtimer_expire_entry\n");
                        break;
                }
        }
...
        ret = tep_unregister_event_handler(tep, -1, "timer", "hrtimer_expire_entry",
                                           timer_expire_handler, NULL);
        if ( ret )
                printf ("Failed to unregister handler for hrtimer_expire_entry\n");

like, the switch statement on TEP_REGISTER_SUCCESS vs TEP_REGISTER_SUCCESS_OVERWRITE? chef's kiss. knowing whether you registered fresh or ate someone else's handler? that's awareness. πŸ‘‘


πŸ“ FILES πŸ“

  • event-parse.h β€” header file to include in order to have access to the library APIs.
  • trace-seq.h β€” header file to include in order to have access to trace sequences related APIs. Trace sequences are used to allow a function to call several other functions to create a string of data to use.
  • -ltraceevent β€” linker switch to add when building a program that uses the library.

🧚 SEE ALSO 🧚

libtraceevent(3), trace-cmd(1)


πŸ‘‘ AUTHOR πŸ‘‘

  • Steven Rostedt <rostedt@goodmis.org> β€” author of libtraceevent. πŸ’–
  • Tzvetomir Stoyanov <tz.stoyanov@gmail.com> β€” author of this man page. πŸ’–

πŸ’€ REPORTING BUGS πŸ’€

Report bugs to <linux-trace-devel@vger.kernel.org>


🫢 LICENSE 🫢

libtraceevent is Free Software licensed under the GNU LGPL 2.1


🌟 RESOURCES 🌟

https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/


πŸ“ NOTES πŸ“

  1. rostedt@goodmis.org β€” mailto:rostedt@goodmis.org
  2. tz.stoyanov@gmail.com β€” mailto:tz.stoyanov@gmail.com
  3. linux-trace-devel@vger.kernel.org β€” mailto:linux-trace-devel@vger.kernel.org

k that's the whole page bestie, go register a handler and live your truth πŸ’…βœ¨

sign-off cuteness: this was libtraceevent 1.9.0, dated 06/15/2026, and you found it under the name LIBTRACEEVENT(3). mwah. 😘
πŸ“¦ where this page comes from