LIBTRACEEVENT(3)

okay bestie, welcome to libtraceevent(3) β€” this is the page about all the parsing functions that load up your mappings into the tep handler. it's giving "library plumbing but make it glam" πŸ’…. buckle up, we're going through all five functions, no skips.


✨ NAME ✨

tep_parse_saved_cmdlines, tep_parse_printk_formats, tep_parse_kallsyms, tep_parse_last_boot_info, tep_load_modules β€” the parsing girlies that load your mappings πŸŽ€


🌸 SYNOPSIS 🌸

#include <event-parse.h>

int tep_parse_saved_cmdlines(struct tep_handle *tep, const char *buf);
int tep_parse_printk_formats(struct tep_handle *tep, const char *buf);
int tep_parse_kallsyms(struct tep_handle *tep, const char *buf);
int tep_parse_last_boot_info(struct tep_handle *tep, const char *lbi);
int tep_load_modules(struct tep_handle *tep, char *modules, size_t size);

like yes that's five whole functions and they're all here, not skipping a single one πŸ¦‹


πŸ’– DESCRIPTION πŸ’–

so here's the tea, one function at a time:

tep_parse_saved_cmdlines() is the helper that parses the content of the "saved_cmdlines" file over in the tracefs file system β€” the content being stored in a string buffer that you pass in through buf β€” and it loads the mapping of process IDs (pid) to the comm names into the tep handler. the events themselves only store the pid, so this mapping is literally what lets you actually show the process names that go with those process ids. it parses the string buf which holds the content of saved_cmdlines, and that string ends with a nul character (\0). periodt.

tep_parse_printk_formats() is the helper that parses the content of the "printk_formats" file in the tracefs file system (again, stored in a string buffer passed in as buf) and loads the mapping of addresses of strings that the events might be referencing. bc bestie, events only store the address of constant strings in the kernel, and the mapping from that address to the actual string is exported to user space via the printk_formats file. it parses the string buf holding the content of printk_formats, and yeah, it ends with a nul character (\0). 🫢

tep_parse_kallsyms() is the helper that parses the Linux kernel /proc/kallsyms format (stored in a string buffer passed in as buf) and loads those functions into the tep handler, so that function IP addresses can get mapped to their name when events are parsed with %pS in the print format field. it parses the string buf holding the content of /proc/kallsyms, and β€” you guessed it β€” it ends with a nul character (\0). 😭 consistent queen

tep_parse_last_boot_info() loads information from the last_boot_info file of a persistent ring buffer instance. here's the situation: if a tracefs instance is declared as a persistent ring buffer and it contains data from a previous boot, then the last_boot_info file will have the addresses of the kernel as well as the modules. it takes that info and uses it to base the function offsets in the binary buffer so they match the function offsets in the kallsyms (the ones loaded by tep_parse_kallsyms()) inside the tep handler. lbi is a nul terminated string holding the content of the last_boot_info file from the persistent ring buffer instance. πŸ”₯

tep_load_modules() loads the contents of the file /proc/modules into the tep handler. this gets used to match the modules found in the last_boot_info (loaded by tep_parse_last_boot_info()) so you can match the offsets of the binary data in a persistent ring buffer β€” matching the address of a module from the previous boot to a module address found in modules. the modules parameter does not need to be nul terminated, but size is used to denote the size of the modules string.

⚠️ heads up: this function is useless if tep_parse_last_boot_info() isnt used. like genuinely, don't bother. πŸ’€

πŸ’… RETURN VALUE πŸ’…

everything here is a simple girl, it's giving 0 or -1:

  • tep_parse_saved_cmdlines() returns 0 in case of success, or -1 in case of an error.
  • tep_parse_printk_formats() returns 0 in case of success, or -1 in case of an error.
  • tep_parse_kallsyms() returns 0 in case of success, or -1 in case of an error.
  • tep_parse_last_boot_info() retuns 0 in case of success, or -1 in case of error.
  • tep_load_modules() returns 0 in case of success, or -1 in case of error.

(and yes, "retuns" β€” that's how the original spells it, i'm not fixing it, it's iconic πŸŽ€)


🌈 EXAMPLE 🌈

here's the whole thing, verbatim, take notes πŸ“:

...
#include <event-parse.h>
#include <tracefs.h>
#include <stdlib.h>

int load_cmdlines(struct tep_handle *tep)
{
        char *buf = NULL;
        int r;

        buf = tracefs_instance_file_read(NULL, "saved_cmdlines", NULL);
        if (!buf)
                return -1;
        r = tep_parse_saved_cmdlines(tep, buf);
        free(buf);
        return r;
}

int load_print_strings(struct tep_handle *tep)
{
        char *buf = NULL;
        int r;

        buf = tracefs_instance_file_read(NULL, "printk_formats", NULL);
        if (!buf)
                return -1;
        r = tep_parse_printk_formats(tep, buf);
        free(buf);
        return r;
}

static char *read_file(const char *file, size_t *size)
{
        FILE *fp;
        char *line = NULL;
        char *buf = NULL;
        size_t sz = 0;
        size_t len = 0;
        int r;

        fp = fopen(file, "r");
        while ((r = getline(&line, &sz, fp)) >= 0) {
                buf = realloc(buf, len + r + 1);
                memcpy(buf + len, line, r);
                len += r;
        }
        free(line);
        fclose(fp);
        if (!buf)
                return NULL;
        buf[len] = 0;
        *size = len;
        return buf;
}

int load_kallsyms(struct tep_handle *tep)
{
        char *buf;
        size_t sz;
        int r;

        buf = read_file("/proc/kallsyms", &sz);
        if (!buf)
                return -1;
        r = tep_parse_kallsyms(tep, buf);
        free(buf);
        return r;
}

int load_last_boot(struct tep_handle *tep, struct tracefs_instance *instance)
{
        char *buf;
        size_t sz;
        int r;

        buf = tracefs_instance_file_read(instance, "last_boot_info", NULL);
        if (!buf)
                return 0;

        r = tep_parse_last_boot_info(tep, buf);
        free(buf);
        if (r < 0)
                return r;

        buf = read_file("/proc/modules", &sz);
        if (!buf)
                return -1;
        r = tep_parse_kallsyms(tep, buf);
        free(buf);
        return r;
}
...

πŸ¦‹ FILES πŸ¦‹

  • event-parse.h β€” the header file you include to get access to the library APIs, obviously πŸ’–
  • -ltraceevent β€” the linker switch you add when building a program that uses the library. don't forget it, she's necessary ✨

πŸ‘‘ SEE ALSO πŸ‘‘

go read these next, bestie, they're all part of the lore:

libtraceevent(3), trace-cmd(1), tep_register_comm(3), tep_register_function(3), tep_register_print_string(3)


πŸ’œ AUTHOR πŸ’œ

  • Steven Rostedt <rostedt@goodmis.org[1]>, author of libtraceevent πŸ‘‘
  • Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>, coauthor of libtraceevent 🌟

😭 REPORTING BUGS 😭

found something cursed? report bugs to <linux-trace-devel@vger.kernel.org[3]> 🫢


πŸŽ€ LICENSE πŸŽ€

libtraceevent is Free Software licensed under the GNU LGPL 2.1 β€” slay, free software rights πŸ’…


🌟 RESOURCES 🌟

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

(the link is right there, i'm just holding it for you 🧚)


πŸ“Ž 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

and that's the whole page, no cap πŸ’– this was libtraceevent version 1.9.0, dated 06/15/2026 β€” and the manual itself is LIBTRACEEVENT(3), so now you know exactly what you've been reading this whole time. go load some mappings, main character πŸ¦‹βœ¨

πŸ“¦ where this page comes from