1libtraceevent(3) 2================ 3 4NAME 5---- 6kbuffer_alloc, kbuffer_dup, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer, 7kbuffer_refresh, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer element to parse 8the Linux kernel tracing ring buffer 9 10SYNOPSIS 11-------- 12[verse] 13-- 14*#include <kbuffer.h>* 15 16enum kbuffer_endian { 17 KBUFFER_ENDIAN_BIG, 18 KBUFFER_ENDIAN_LITTLE, 19 KBUFFER_ENDIAN_SAME_AS_HOST, 20}; 21 22enum kbuffer_long_size { 23 KBUFFER_LSIZE_4, 24 KBUFFER_LSIZE_8, 25 KBUFFER_LSIZE_SAME_AS_HOST, 26}; 27 28struct kbuffer; 29struct tep_handle; 30 31struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); 32struct kbuffer pass:[*]*kbuffer_dup*(struct kbuffer pass:[*]_kbuf_); 33void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); 34int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); 35int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf_); 36int *kbuffer_refresh*(struct kbuffer pass:[*]_kbuf_); 37int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); 38void pass:[*]*kbuffer_subbuffer*(struct kbuffer pass:[*]_kbuf); 39-- 40 41DESCRIPTION 42----------- 43These functions create a _kbuffer_ handle that can be used to parse the raw sub buffers 44of the Linux kernel tracing ring buffer. The ring buffer is found in the tracefs 45directory, and can be retrieved by *tracefs_instance_get_file(3)* at 46*per_cpu/cpuX/trace_pipe_raw* where *X* is replaced by the per CPU number of 47the specified ring buffer. The ring buffer inside the kernel is split up per 48CPU, such that the raw ring buffer must be retrieved per CPU as well. 49 50The *kbuffer_alloc()* will create a descriptor that can be used to manage a sub buffer 51read by the ring buffer. The _size_ parameter denotes what the word size is 52for the given buffer (note, this works from reading raw data from machines other 53than the machine that is calling this function). The _endian_ denotes the endian 54for the machine. 55 56If _endian_ is set to _KBUFFER_ENDIAN_SAME_AS_HOST_ the endian will be set to the same 57as the host endianess, which is useful when the application is reading the 58ring buffer data directly from the same machine it is running on. 59 60If _size_ is set to _KBUFFER_LSIZE_SAME_AS_HOST_, if the word size is 8, it will 61set the kbuffer descriptor to long size of 8. But if the size is 4, then it 62will then perform a *uname(2)* call, and if the _machine_ field has the string "64" 63in it, it will be set to 8 byte long size and not 4 byte. This is because the 64ring buffer long size is dependent on the kernel and not user space. 65 66The *kbuffer_dup()* function will duplicate an existing kbuffer structure with 67an allocated new one. It will have all the properties of the passed in _kbuf_, 68including pointing to the same subbuffer that was loaded in the _kbuf_. 69It must be freed with *kbuffer_free()*. 70 71The *kbuffer_free()* function will free the resources created by *kbuffer_alloc()*. 72 73The *kbuffer_load_subbuffer()* will take a _subbuffer_ which is a raw data blob 74from the tracefs *trace_pipe_raw* file. The Linux tracing ring buffer is broken up 75into sub buffers. Each sub buffer is as stand alone data segment that has all the 76information to split out the individual events and time stamps. This sub buffer 77is what kbuffer uses to walk the events. 78 79The *kbuffer_subbuffer_size()* returns the location of the end of the last event 80on the sub-buffer. It does not return the size of the sub-buffer itself. 81 82The *kbuffer_refresh()* is to be used if more writes were done on the loaded kbuffer 83where the size of the kbuffer needs to be refreshed to be able to read the new 84events that were written since the last *kbuffer_load_subbuffer()* was called on it. 85 86Note, no memory barriers are implemented with this function and any synchronization 87with the writer is the responsibility of the application. 88 89The *kbuffer_start_of_data()* function returns the offset of where the actual 90data load of the sub-buffer begins. 91 92The *kbuffer_subbuffer()* function returns the pointer to the currently loaded 93subbuffer. That is, the last subbuffer that was loaded by *kbuffer_load_subbuffer()*. 94If no subbuffer was loaded NULL is returned. 95 96RETURN VALUE 97------------ 98*kbuffer_alloc()* returns an allocated kbuffer descriptor or NULL on error. 99The returned descriptor must be freed with *kbuffer_free()* 100 101*kbuffer_load_subbuffer()* returns 0 on success and -1 on error. 102 103*kbuffer_subbuffer_size()* returns the index on the subbuffer where the end 104of the last event is located. 105 106*kbuffer_start_of_data()* returns the offset of where the data begins on the 107sub-buffer loaded in _kbuf_. 108 109*kbuffer_subbuffer()* returns the last loaded subbuffer to _kbuf_ that was loaded 110by *kbuffer_load_subbuffer()* or NULL if none was loaded. 111 112*kbuffer_refresh()* returns 0 on success and -1 if _kbuf_ is NULL or it does not 113have a subbuffer loaded via *kbuffer_load_subbuffer()*. 114 115EXAMPLE 116------- 117[source,c] 118-- 119#include <stdio.h> 120#include <stdlib.h> 121#include <fcntl.h> 122#include <unistd.h> 123#include <sys/stat.h> 124 125#include <kbuffer.h> 126 127int main (int argc, char **argv) 128{ 129 unsigned long long ts; 130 struct kbuffer *kbuf; 131 struct stat st; 132 char *buf; 133 void *event; 134 int ret; 135 int fd; 136 int i = 0; 137 138 if (argc < 2) { 139 printf("usage: %s raw-subbuffer-page\n", argv[0]); 140 printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); 141 exit(0); 142 } 143 144 if (stat(argv[1], &st) < 0) { 145 perror("stat"); 146 exit(-1); 147 } 148 149 buf = malloc(st.st_size); 150 if (!buf) { 151 perror("Allocating buffer"); 152 exit(-1); 153 } 154 155 fd = open(argv[1], O_RDONLY); 156 if (fd < 0) { 157 perror(argv[1]); 158 exit(-1); 159 } 160 161 ret = read(fd, buf, st.st_size); 162 if (ret < 0) { 163 perror("Reading buffer"); 164 exit(-1); 165 } 166 close(fd); 167 168 kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, 169 KBUFFER_LSIZE_SAME_AS_HOST); 170 if (!kbuf) { 171 perror("Creating kbuffer"); 172 exit(-1); 173 } 174 ret = kbuffer_load_subbuffer(kbuf, buf); 175 if (ret < 0) { 176 perror("Loading sub bufer"); 177 exit(-1); 178 } 179 180 if (kbuffer_subbuffer_size(kbuf) > st.st_size) { 181 fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", 182 kbuffer_subbuffer_size(kbuf), st.st_size); 183 exit(-1); 184 } 185 186 printf("Kbuffer data starts at %d\n", kbuffer_start_of_data(kbuf)); 187 do { 188 event = kbuffer_read_event(kbuf, &ts); 189 if (event) { 190 printf(" event %3d ts:%lld\n", i++, ts); 191 event = kbuffer_next_event(kbuf, NULL); 192 } 193 } while (event); 194 195 if (!event) 196 printf("Finished sub buffer\n"); 197 198 kbuffer_free(kbuf); 199 200 return 0; 201} 202-- 203FILES 204----- 205[verse] 206-- 207*event-parse.h* 208 Header file to include in order to have access to the library APIs. 209*-ltraceevent* 210 Linker switch to add when building a program that uses the library. 211-- 212 213SEE ALSO 214-------- 215*libtraceevent*(3), *trace-cmd*(1) 216 217AUTHOR 218------ 219[verse] 220-- 221*Steven Rostedt* <[email protected]>, author of *libtraceevent*. 222-- 223REPORTING BUGS 224-------------- 225Report bugs to <[email protected]> 226 227LICENSE 228------- 229libtraceevent is Free Software licensed under the GNU LGPL 2.1 230 231RESOURCES 232--------- 233https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ 234