LIBTRACEEVENT(3)

πŸ’– LIBTRACEEVENT β€” kbuffer_timestamp, kbuffer_subbuf_timestamp πŸ’–

okay bestie, welcome to the libtraceevent manual, section 3 πŸŽ€ this one is all about the kbuffer functions that read various data of a kbuffer descriptor. yes it says "timestamp" up in the NAME and then the page rambles into a whole other friend group, we don't question it, we just vibe πŸ¦‹


✨ NAME ✨

kbuffer_timestamp, kbuffer_subbuf_timestamp β€” Functions that read various data of a kbuffer descriptor 🌸


✨ SYNOPSIS ✨

#include <kbuffer.h>

unsigned long long kbuffer_timestamp(struct kbuffer *kbuf);
unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf);

✨ DESCRIPTION ✨

so, the function kbuffer_timestamp() returns the timestamp of the current event of kbuf. that's it. that's the whole job. she's simple, she's reliable, we love her πŸ’…

the function kbuffer_subbuf_timestamp() returns the timestamp for the sub-buffer that was loaded in kbuf. and like, usually that's the timestamp of the first event on the sub-buffer β€” but no cap, it is NOT guaranteed to be, so don't come for me if it's something else πŸ™ˆ

the function kbuffer_start_of_data() returns the offset of where the delta

πŸ’€ and that's literally where the sentence ends in the source, bestie. the delta WHAT. we may never know. i'm not making anything up to fill the gap, i'm just relaying it exactly as it stands, and the vibes are immaculate.

✨ RETURN VALUE ✨

  • kbuffer_read_event() β€” returns the event that the kbuf descriptor is currently at πŸ‘‘ or NULL if the last event was already passed (by kbuffer_next_event()). like, you missed it, it's gone, bye 🫢
  • kbuffer_next_event() β€” returns the next event after the current event, or NULL if there are no more events. that NULL is your little "the end, bestie" signal 🌈
  • kbuffer_read_at_offset() β€” returns the event at a given offset from the start of the sub-buffer stored in kbuf, or NULL if there exists no event. note: the offset only needs to be an offset that lands on the record, or is at the start of it β€” it does not need to be exactly at the beginning of the record. so don't stress about pixel-perfect aim, you're fine πŸ’–
  • kbuffer_missed_events() β€” returns 0 if there were no missed events before the loaded sub-buffer. returns -1 if there were an unknown number of missed events β€” or, if the number of missed events is known, that number gets returned. mystery quantities get the -1 treatment, that's just how she communicates 😭
  • kbuffer_event_size() β€” returns the size of the data payload of the current event of kbuf. the payload only, bestie. we're talking about the contents, not the packaging ✨
  • kbuffer_curr_size() β€” returns the size of the entire record of the current event of kbuf. this includes the size of the meta data for that record. so, payload plus the meta data, the whole fit πŸ’…
  • kbuf_curr_offset() β€” returns the offset of the current record from the beginning of the kbuf sub-buffer. where are we, on the map πŸ“
  • kbuf_curr_index() β€” returns the index of the current record from the beginning of the kbuf data section. which one are we, in the lineup πŸ”’

✨ EXAMPLE ✨

here's the whole entire program, verbatim, no edits, she's iconic and we're not touching a single character:

           #include <stdio.h>
           #include <stdlib.h>
           #include <fcntl.h>
           #include <unistd.h>
           #include <sys/stat.h>

           #include <kbuffer.h>

           int main (int argc, char **argv)
           {
                   unsigned long long ts;
                   struct kbuffer *kbuf;
                   struct stat st;
                   char *buf;
                   void *event;
                   int save_offset = -1;
                   int record_size;
                   int offset;
                   int index;
                   int size;
                   int ret;
                   int fd;
                   int i = 0;

                   if (argc < 2) {
                           printf("usage: %s raw-subbuffer-page\n", argv[0]);
                           printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n");
                           exit(0);
                   }

                   if (stat(argv[1], &st) < 0) {
                           perror("stat");
                           exit(-1);
                   }

                   buf = malloc(st.st_size);
                   if (!buf) {
                           perror("Allocating buffer");
                           exit(-1);
                   }

                   fd = open(argv[1], O_RDONLY);
                   if (fd < 0) {
                           perror(argv[1]);
                           exit(-1);
                   }

                   ret = read(fd, buf, st.st_size);
                   if (ret < 0) {
                           perror("Reading buffer");
                           exit(-1);
                   }
                   close(fd);

                   kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST,
                                        KBUFFER_LSIZE_SAME_AS_HOST);
                   if (!kbuf) {
                           perror("Creating kbuffer");
                           exit(-1);
                   }
                   ret = kbuffer_load_subbuffer(kbuf, buf);
                   if (ret < 0) {
                           perror("Loading sub bufer");
                           exit(-1);
                   }

                   if (kbuffer_subbuffer_size(kbuf) > st.st_size) {
                           fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n",
                                   kbuffer_subbuffer_size(kbuf), st.st_size);
                           exit(-1);
                   }

                   ret = kbuffer_missed_events(kbuf);
                   if (ret) {
                           if (ret > 0)
                                   printf("Missed %d events before this buffer\n", ret);
                           else
                                   printf("Missed unknown number of events before this buffer\n");
                   }
                   do {
                           event = kbuffer_read_event(kbuf, &ts);
                           if (event) {
                                   record_size = kbuffer_curr_size(kbuf);
                                   offset = kbuffer_curr_offset(kbuf);
                                   index = kbuffer_curr_index(kbuf);
                                   size = kbuffer_event_size(kbuf);

                                   if (i == 20)
                                           save_offset = offset;
                                   printf(" event %3d ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n",
                                          i++, ts, record_size, size, index, offset);
                                   event = kbuffer_next_event(kbuf, NULL);
                           }
                   } while (event);

                   if (!event)
                           printf("Finished sub buffer\n");

                   if (save_offset > 0) {
                           event = kbuffer_read_at_offset(kbuf, save_offset, &ts);
                           if (!event) {
                                   fprintf(stderr, "Funny, can't find event 20 at offset %d\n", save_offset);
                                   exit(-1);
                           }
                           record_size = kbuffer_curr_size(kbuf);
                           offset = kbuffer_curr_offset(kbuf);
                           index = kbuffer_curr_index(kbuf);
                           size = kbuffer_event_size(kbuf);

                           printf("\n saved event 20 ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n\n",
                                  ts, record_size, size, index, offset);
                   }
                   kbuffer_free(kbuf);

                   return 0;
           }

no fr, that's the entire thing, typos preserved with love 🫢 (yes, Loading sub bufer. we respect the lore.)


✨ FILES ✨

  • event-parse.h β€” Header file to include in order to have access to the library APIs.
  • -ltraceevent β€” Linker switch to add when building a program that uses the library. πŸŽ€

✨ SEE ALSO ✨

libtraceevent(3), trace-cmd(1) β€” go read those too, bestie, they're the rest of the lore πŸ’œ


✨ AUTHOR ✨

Steven Rostedt <rostedt@goodmis.org[1]>, author of libtraceevent. πŸ‘‘ (yes THAT Steven Rostedt. the whole author of libtraceevent. show some respect.)


✨ REPORTING BUGS ✨

Report bugs to <linux-trace-devel@vger.kernel.org[2]> πŸ™ˆ


✨ LICENSE ✨

libtraceevent is Free Software licensed under the GNU LGPL 2.1 πŸ“œ slay, freedom, love that for us


✨ RESOURCES ✨

https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ πŸ¦‹


✨ NOTES ✨

  1. rostedt@goodmis.org β€” mailto:rostedt@goodmis.org
  2. linux-trace-devel@vger.kernel.org β€” mailto:linux-trace-devel@vger.kernel.org

okay periodt, that's the whole page πŸŽ€ stay hydrated, close your fds, and remember: this was libtraceevent 1.9.0, dated 06/15/2026, and it was LIBTRACEEVENT(3) in the libtraceevent Manual β€” mwah πŸ’–βœ¨

πŸ“¦ where this page comes from