'\" t
.\" Title: libtraceevent
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 01/14/2024
.\" Manual: libtraceevent Manual
.\" Source: libtraceevent 1.8.2
.\" Language: English
.\"
.TH "LIBTRACEEVENT" "3" "01/14/2024" "libtraceevent 1\&.8\&.2" "libtraceevent Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
kbuffer_read_event, kbuffer_next_event, kbuffer_missed_events, kbuffer_event_size, kbuffer_curr_size, kbuffer_curr_offset, kbuffer_curr_index, kbuffer_read_buffer \- Functions to read through the kbuffer sub buffer\&.
.SH "SYNOPSIS"
.sp
.nf
\fB#include \fR
void *\fBkbuffer_read_event\fR(struct kbuffer *\fIkbuf\fR, unsigned long long *\fIts\fR);
void *\fBkbuffer_next_event\fR(struct kbuffer *\fIkbuf\fR, unsigned long long *\fIts\fR);
void *\fBkbuffer_read_at_offset\fR(struct kbuffer *\fIkbuf\fR, int \fIoffset\fR, unsigned long long *\fIts\fR);
int \fBkbuffer_missed_events\fR(struct kbuffer *\fIkbuf\fR);
int \fBkbuffer_event_size\fR(struct kbuffer *\fIkbuf\fR);
int \fBkbuffer_curr_size\fR(struct kbuffer *\fIkbuf\fR);
int \fBkbuffer_curr_offset\fR(struct kbuffer *\fIkbuf\fR);
int \fBkbuffer_curr_index\fR(struct kbuffer *\fIkbuf\fR);
int \fBkbuffer_read_buffer\fR(struct kbuffer *\fIkbuf\fR, void *\fIbuffer\fR, int \fIlen\fR);
.fi
.SH "DESCRIPTION"
.sp
The function \fBkbuffer_read_event()\fR reads the next event in the \fIkbuf\fR descriptor and if \fIts\fR is non NULL, will place its timestamp into it\&. This does not modify the \fIkbuf\fR descriptor, and calling this function mulitple times will return the same result\&.
.sp
The function \fBkbuffer_next_event()\fR will return the next event in the \fIkbuf\fR descriptor\&. It will also set the \fIts\fR to the timestamp of the returned event\&. NULL is returned if there are no more events and \fIts\fR will be undefined\&. Note, if this is called directly after a \fBkbuffer_load_subbuffer()\fR then it will likely give an unexpected result, as it will return the second event and not the first event\&. Usually this function is only used to move to the next event and to know if there\(cqs any more events to read, and \fBkbuffer_read_event()\fR is always called first\&.
.sp
The function \fBkbuffer_read_at_offset()\fR returns the event located at a given \fIoffset\fR from the beginning of the sub\-buffer\&. This offset can be retrieved by \fBkbuffer_curr_offset()\fR\&. If \fIts\fR points to an unsigned long long, then it will be set to the event at the given offset\(cqs timestamp\&.
.sp
If the sub\-buffer had missed events before it, then \fBkbuffer_missed_events()\fR will return the non zero\&. If it returns \-1, that means there were missed events, but the exact number of missed events is unknown\&. If it returns a positive number, then the number of missed events is the return value\&.
.sp
The \fBkbuffer_event_size()\fR function returns the size of the data portion of the current event (the one that would be returned by \fBkbuffer_read_event()\fR\&.
.sp
The \fBkbuffer_curr_size()\fR function returns the entire record size of the current event (the one that would be returned by \fBkbuffer_read_event()\fR\&. The difference here is that the return value includes the size of the event record meta data that is not part of what is returned by \fBkbuffer_read_event()\fR\&.
.sp
The \fBkbuffer_curr_offset()\fR function returns the offset from the beginning of the sub\-buffer of where the current event\(cqs meta data for the record begins\&. The first event will not be at offset zero\&. This offset can be used to retrieve the event with \fBkbuffer_read_at_offset()\fR\&.
.sp
The \fBkbuffer_curr_index()\fR function returns the index from the beginning of the data portion of the sub\-buffer where the current evnet\(cqs meta data is located\&. The first event will likely be zero, but may not be if there\(cqs a timestamp attached to it\&.
.sp
The \fBkbuffer_read_buffer()\fR function will fill the given \fIbuffer\fR from the \fIkbuf\fR the same way the kernel would do a read system call\&. That is, if the length \fIlen\fR is less than the sub buffer size, or the kbuffer current index is non\-zero, it will start copying from the \fIkbuf\fR current event and create \fIbuffer\fR as a new sub buffer (with a timestamp and commit header) with that event that was found and including all events after that can fit within \fIlen\fR\&. The \fIlen\fR must include the size of the sub buffer header as well as the events to include\&. That is, \fIlen\fR is the allocate size of \fIbuffer\fR that can be filled\&. The return from this function is the index of the end of the last event that was added\&. If there are no more events then zero is returned, and if the buffer can not copy any events because \fIlen\fR was too small, then \-1 is returned\&.
.SH "RETURN VALUE"
.sp
\fBkbuffer_read_event()\fR returns the event that the \fIkbuf\fR descriptor is currently at, or NULL if the last event was passed (by \fBkbuffer_next_event()\fR)\&.
.sp
\fBkbuffer_next_event()\fR returns the next event after the current event or NULL if there are no more events\&.
.sp
\fBkbuffer_read_at_offset()\fR returns the event at a given \fIoffset\fR from the start of the sub\-buffer stored in \fIkbuf\fR, or NULL if there exists no event\&. Note, \fIoffset\fR 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\&.
.sp
\fBkbuffer_missed_events()\fR returns 0 if there were no missed events before 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 will be returned\&.
.sp
\fBkbuffer_event_size()\fR returns the size of the data payload of the current event of \fIkbuf\fR\&.
.sp
\fBkbuffer_curr_size()\fR returns the size of the entire record of the current event of \fIkbuf\fR\&. This includes the size of the meta data for that record\&.
.sp
\fBkbuf_curr_offset()\fR returns the offset of the current record from the beginning of the \fIkbuf\fR sub\-buffer\&.
.sp
\fBkbuf_curr_index()\fR returns the index of the current record from the beginning of the \fIkbuf\fR data section\&.
.sp
\fBkbuf_read_buffer()\fR returns the index of the end of the last event that was filled in \fIbuffer\fR\&. If there are no more events to copy from \fIstart\fR then 0 is returned\&. If \fIlen\fR is not big enough to hold any events, then \-1 is returned\&.
.SH "EXAMPLE"
.sp
.if n \{\
.RS 4
.\}
.nf
#include
#include
#include
#include
#include
#include
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\en", argv[0]);
printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\en");
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\en",
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\en", ret);
else
printf("Missed unknown number of events before this buffer\en");
}
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\etrecord_size:%d size:%d\etindex:%d offset:%d\en",
i++, ts, record_size, size, index, offset);
event = kbuffer_next_event(kbuf, NULL);
}
} while (event);
if (!event)
printf("Finished sub buffer\en");
if (save_offset > 0) {
event = kbuffer_read_at_offset(kbuf, save_offset, &ts);
if (!event) {
fprintf(stderr, "Funny, can\*(Aqt find event 20 at offset %d\en", 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("\en saved event 20 ts:%lld\etrecord_size:%d size:%d\etindex:%d offset:%d\en\en",
ts, record_size, size, index, offset);
}
kbuffer_free(kbuf);
return 0;
}
.fi
.if n \{\
.RE
.\}
.SH "FILES"
.sp
.if n \{\
.RS 4
.\}
.nf
\fBevent\-parse\&.h\fR
Header file to include in order to have access to the library APIs\&.
\fB\-ltraceevent\fR
Linker switch to add when building a program that uses the library\&.
.fi
.if n \{\
.RE
.\}
.SH "SEE ALSO"
.sp
\fBlibtraceevent\fR(3), \fBtrace\-cmd\fR(1)
.SH "AUTHOR"
.sp
.if n \{\
.RS 4
.\}
.nf
\fBSteven Rostedt\fR <\m[blue]\fBrostedt@goodmis\&.org\fR\m[]\&\s-2\u[1]\d\s+2>, author of \fBlibtraceevent\fR\&.
.fi
.if n \{\
.RE
.\}
.SH "REPORTING BUGS"
.sp
Report bugs to <\m[blue]\fBlinux\-trace\-devel@vger\&.kernel\&.org\fR\m[]\&\s-2\u[2]\d\s+2>
.SH "LICENSE"
.sp
libtraceevent is Free Software licensed under the GNU LGPL 2\&.1
.SH "RESOURCES"
.sp
\m[blue]\fBhttps://git\&.kernel\&.org/pub/scm/libs/libtrace/libtraceevent\&.git/\fR\m[]
.SH "NOTES"
.IP " 1." 4
rostedt@goodmis.org
.RS 4
\%mailto:rostedt@goodmis.org
.RE
.IP " 2." 4
linux-trace-devel@vger.kernel.org
.RS 4
\%mailto:linux-trace-devel@vger.kernel.org
.RE