'\" t .\" Title: libtraceevent .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 01/13/2024 .\" Manual: libtraceevent Manual .\" Source: libtraceevent .\" Language: English .\" .TH "LIBTRACEEVENT" "3" "01/13/2024" "libtraceevent" "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_alloc, kbuffer_dup, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer, kbuffer_refresh, kbuffer_subbuffer_size, kbuffer_start_of_data \- Creating of kbuffer element to parse the Linux kernel tracing ring buffer .SH "SYNOPSIS" .sp .nf \fB#include \fR enum kbuffer_endian { KBUFFER_ENDIAN_BIG, KBUFFER_ENDIAN_LITTLE, KBUFFER_ENDIAN_SAME_AS_HOST, }; enum kbuffer_long_size { KBUFFER_LSIZE_4, KBUFFER_LSIZE_8, KBUFFER_LSIZE_SAME_AS_HOST, }; struct kbuffer; struct tep_handle; struct kbuffer *\fBkbuffer_alloc\fR(enum kbuffer_long_size \fIsize\fR, enum kbuffer_endian \fIendian\fR); struct kbuffer *\fBkbuffer_dup\fR(struct kbuffer *\fIkbuf\fR); void \fBkbuffer_free\fR(struct kbuffer *\fIkbuf\fR); int \fBkbuffer_load_subbuffer\fR(struct kbuffer *\fIkbuf\fR, void *\fIsubbuffer\fR); int \fBkbuffer_subbuffer_size\fR(struct kbuffer *\fIkbuf\fR); int \fBkbuffer_refresh\fR(struct kbuffer *\fIkbuf\fR); int \fBkbuffer_start_of_data\fR(struct kbuffer *\fIkbuf\fR); void *\fBkbuffer_subbuffer\fR(struct kbuffer *_kbuf); .fi .SH "DESCRIPTION" .sp These functions create a \fIkbuffer\fR handle that can be used to parse the raw sub buffers of the Linux kernel tracing ring buffer\&. The ring buffer is found in the tracefs directory, and can be retrieved by \fBtracefs_instance_get_file(3)\fR at \fBper_cpu/cpuX/trace_pipe_raw\fR where \fBX\fR is replaced by the per CPU number of the specified ring buffer\&. The ring buffer inside the kernel is split up per CPU, such that the raw ring buffer must be retrieved per CPU as well\&. .sp The \fBkbuffer_alloc()\fR will create a descriptor that can be used to manage a sub buffer read by the ring buffer\&. The \fIsize\fR parameter denotes what the word size is for the given buffer (note, this works from reading raw data from machines other than the machine that is calling this function)\&. The \fIendian\fR denotes the endian for the machine\&. .sp If \fIendian\fR is set to \fIKBUFFER_ENDIAN_SAME_AS_HOST\fR the endian will be set to the same as the host endianess, which is useful when the application is reading the ring buffer data directly from the same machine it is running on\&. .sp If \fIsize\fR is set to \fIKBUFFER_LSIZE_SAME_AS_HOST\fR, if the word size is 8, it will set the kbuffer descriptor to long size of 8\&. But if the size is 4, then it will then perform a \fBuname(2)\fR call, and if the \fImachine\fR field has the string "64" in it, it will be set to 8 byte long size and not 4 byte\&. This is because the ring buffer long size is dependent on the kernel and not user space\&. .sp The \fBkbuffer_dup()\fR function will duplicate an existing kbuffer structure with an allocated new one\&. It will have all the properties of the passed in \fIkbuf\fR, including pointing to the same subbuffer that was loaded in the \fIkbuf\fR\&. It must be freed with \fBkbuffer_free()\fR\&. .sp The \fBkbuffer_free()\fR function will free the resources created by \fBkbuffer_alloc()\fR\&. .sp The \fBkbuffer_load_subbuffer()\fR will take a \fIsubbuffer\fR which is a raw data blob from the tracefs \fBtrace_pipe_raw\fR file\&. The Linux tracing ring buffer is broken up into sub buffers\&. Each sub buffer is as stand alone data segment that has all the information to split out the individual events and time stamps\&. This sub buffer is what kbuffer uses to walk the events\&. .sp The \fBkbuffer_subbuffer_size()\fR returns the location of the end of the last event on the sub\-buffer\&. It does not return the size of the sub\-buffer itself\&. .sp The \fBkbuffer_refresh()\fR is to be used if more writes were done on the loaded kbuffer where the size of the kbuffer needs to be refreshed to be able to read the new events that were written since the last \fBkbuffer_load_subbuffer()\fR was called on it\&. .sp Note, no memory barriers are implemented with this function and any synchronization with the writer is the responsibility of the application\&. .sp The \fBkbuffer_start_of_data()\fR function returns the offset of where the actual data load of the sub\-buffer begins\&. .sp The \fBkbuffer_subbuffer()\fR function returns the pointer to the currently loaded subbuffer\&. That is, the last subbuffer that was loaded by \fBkbuffer_load_subbuffer()\fR\&. If no subbuffer was loaded NULL is returned\&. .SH "RETURN VALUE" .sp \fBkbuffer_alloc()\fR returns an allocated kbuffer descriptor or NULL on error\&. The returned descriptor must be freed with \fBkbuffer_free()\fR .sp \fBkbuffer_load_subbuffer()\fR returns 0 on success and \-1 on error\&. .sp \fBkbuffer_subbuffer_size()\fR returns the index on the subbuffer where the end of the last event is located\&. .sp \fBkbuffer_start_of_data()\fR returns the offset of where the data begins on the sub\-buffer loaded in \fIkbuf\fR\&. .sp \fBkbuffer_subbuffer()\fR returns the last loaded subbuffer to \fIkbuf\fR that was loaded by \fBkbuffer_load_subbuffer()\fR or NULL if none was loaded\&. .sp \fBkbuffer_refresh()\fR returns 0 on success and \-1 if \fIkbuf\fR is NULL or it does not have a subbuffer loaded via \fBkbuffer_load_subbuffer()\fR\&. .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 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); } printf("Kbuffer data starts at %d\en", kbuffer_start_of_data(kbuf)); do { event = kbuffer_read_event(kbuf, &ts); if (event) { printf(" event %3d ts:%lld\en", i++, ts); event = kbuffer_next_event(kbuf, NULL); } } while (event); if (!event) printf("Finished sub buffer\en"); 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