1libtraceevent(3) 2================ 3 4NAME 5---- 6kbuffer_read_event, kbuffer_next_event, kbuffer_missed_events, kbuffer_event_size, kbuffer_curr_size, 7kbuffer_curr_offset, kbuffer_curr_index, kbuffer_read_buffer - 8Functions to read through the kbuffer sub buffer. 9 10SYNOPSIS 11-------- 12[verse] 13-- 14*#include <kbuffer.h>* 15 16void pass:[*]*kbuffer_read_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); 17void pass:[*]*kbuffer_next_event*(struct kbuffer pass:[*]_kbuf_, unsigned long long pass:[*]_ts_); 18void pass:[*]*kbuffer_read_at_offset*(struct kbuffer pass:[*]_kbuf_, int _offset_, unsigned long long pass:[*]_ts_); 19int *kbuffer_missed_events*(struct kbuffer pass:[*]_kbuf_); 20int *kbuffer_event_size*(struct kbuffer pass:[*]_kbuf_); 21int *kbuffer_curr_size*(struct kbuffer pass:[*]_kbuf_); 22int *kbuffer_curr_offset*(struct kbuffer pass:[*]_kbuf_); 23int *kbuffer_curr_index*(struct kbuffer pass:[*]_kbuf_); 24int *kbuffer_read_buffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_buffer_, int _len_); 25-- 26 27DESCRIPTION 28----------- 29The function *kbuffer_read_event()* reads the next event in the _kbuf_ descriptor 30and if _ts_ is non NULL, will place its timestamp into it. This does not modify the _kbuf_ 31descriptor, and calling this function mulitple times will return the same result. 32 33The function *kbuffer_next_event()* will return the next event in the _kbuf_ descriptor. 34It will also set the _ts_ to the timestamp of the returned event. NULL is returned 35if there are no more events and _ts_ will be undefined. Note, if this is called directly 36after a *kbuffer_load_subbuffer()* then it will likely give an unexpected result, as it 37will return the second event and not the first event. Usually this function is only used 38to move to the next event and to know if there's any more events to read, and 39*kbuffer_read_event()* is always called first. 40 41The function *kbuffer_read_at_offset()* returns the event located at a given _offset_ from 42the beginning of the sub-buffer. This offset can be retrieved by *kbuffer_curr_offset()*. 43If _ts_ points to an unsigned long long, then it will be set to the event at the given 44offset's timestamp. 45 46If the sub-buffer had missed events before it, then *kbuffer_missed_events()* will return 47the non zero. If it returns -1, that means there were missed events, but the exact number 48of missed events is unknown. If it returns a positive number, then the number of missed events 49is the return value. 50 51The *kbuffer_event_size()* function returns the size of the data portion of the current event 52(the one that would be returned by *kbuffer_read_event()*. 53 54The *kbuffer_curr_size()* function returns the entire record size of the current event 55(the one that would be returned by *kbuffer_read_event()*. The difference here is that the 56return value includes the size of the event record meta data that is not part of what 57is returned by *kbuffer_read_event()*. 58 59The *kbuffer_curr_offset()* function returns the offset from the beginning of the sub-buffer 60of where the current event's meta data for the record begins. The first event will 61not be at offset zero. This offset can be used to retrieve the event with 62*kbuffer_read_at_offset()*. 63 64The *kbuffer_curr_index()* function returns the index from the beginning of the data 65portion of the sub-buffer where the current evnet's meta data is located. 66The first event will likely be zero, but may not be if there's a timestamp attached to it. 67 68The *kbuffer_read_buffer()* function will fill the given _buffer_ from the _kbuf_ the same 69way the kernel would do a read system call. That is, if the length _len_ is less than the 70sub buffer size, or the kbuffer current index is non-zero, it will start copying from the 71_kbuf_ current event and create _buffer_ as a new sub buffer (with a timestamp 72and commit header) with that event that was found and including all events after that can 73fit within _len_. The _len_ must include the size of the sub buffer header as well as the 74events to include. That is, _len_ is the allocate size of _buffer_ that can be filled. 75The return from this function is the index of the end of the last event that was added. 76If there are no more events then zero is returned, and if the buffer can not 77copy any events because _len_ was too small, then -1 is returned. 78 79 80RETURN VALUE 81------------ 82*kbuffer_read_event()* returns the event that the _kbuf_ descriptor is currently at, 83or NULL if the last event was passed (by *kbuffer_next_event()*). 84 85*kbuffer_next_event()* returns the next event after the current event or NULL if there 86are no more events. 87 88*kbuffer_read_at_offset()* returns the event at a given _offset_ from the start of 89the sub-buffer stored in _kbuf_, or NULL if there exists no event. Note, _offset_ 90only needs to be an offset that lands on the record, or is at the start of it. It does 91not need to be exactly at the beginning of the record. 92 93*kbuffer_missed_events()* returns 0 if there were no missed events before loaded sub-buffer. 94Returns -1 if there were an unknown number of missed events, or if the number of missed events 95is known, that number will be returned. 96 97*kbuffer_event_size()* returns the size of the data payload of the current event of _kbuf_. 98 99*kbuffer_curr_size()* returns the size of the entire record of the current event of _kbuf_. 100This includes the size of the meta data for that record. 101 102*kbuf_curr_offset()* returns the offset of the current record from the beginning of the _kbuf_ 103sub-buffer. 104 105*kbuf_curr_index()* returns the index of the current record from the beginning of the _kbuf_ 106data section. 107 108*kbuf_read_buffer()* returns the index of the end of the last event that was filled in 109_buffer_. If there are no more events to copy from _start_ then 0 is returned. If _len_ 110is not big enough to hold any events, then -1 is returned. 111 112EXAMPLE 113------- 114[source,c] 115-- 116#include <stdio.h> 117#include <stdlib.h> 118#include <fcntl.h> 119#include <unistd.h> 120#include <sys/stat.h> 121 122#include <kbuffer.h> 123 124int main (int argc, char **argv) 125{ 126 unsigned long long ts; 127 struct kbuffer *kbuf; 128 struct stat st; 129 char *buf; 130 void *event; 131 int save_offset = -1; 132 int record_size; 133 int offset; 134 int index; 135 int size; 136 int ret; 137 int fd; 138 int i = 0; 139 140 if (argc < 2) { 141 printf("usage: %s raw-subbuffer-page\n", argv[0]); 142 printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); 143 exit(0); 144 } 145 146 if (stat(argv[1], &st) < 0) { 147 perror("stat"); 148 exit(-1); 149 } 150 151 buf = malloc(st.st_size); 152 if (!buf) { 153 perror("Allocating buffer"); 154 exit(-1); 155 } 156 157 fd = open(argv[1], O_RDONLY); 158 if (fd < 0) { 159 perror(argv[1]); 160 exit(-1); 161 } 162 163 ret = read(fd, buf, st.st_size); 164 if (ret < 0) { 165 perror("Reading buffer"); 166 exit(-1); 167 } 168 close(fd); 169 170 kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, 171 KBUFFER_LSIZE_SAME_AS_HOST); 172 if (!kbuf) { 173 perror("Creating kbuffer"); 174 exit(-1); 175 } 176 ret = kbuffer_load_subbuffer(kbuf, buf); 177 if (ret < 0) { 178 perror("Loading sub bufer"); 179 exit(-1); 180 } 181 182 if (kbuffer_subbuffer_size(kbuf) > st.st_size) { 183 fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", 184 kbuffer_subbuffer_size(kbuf), st.st_size); 185 exit(-1); 186 } 187 188 ret = kbuffer_missed_events(kbuf); 189 if (ret) { 190 if (ret > 0) 191 printf("Missed %d events before this buffer\n", ret); 192 else 193 printf("Missed unknown number of events before this buffer\n"); 194 } 195 do { 196 event = kbuffer_read_event(kbuf, &ts); 197 if (event) { 198 record_size = kbuffer_curr_size(kbuf); 199 offset = kbuffer_curr_offset(kbuf); 200 index = kbuffer_curr_index(kbuf); 201 size = kbuffer_event_size(kbuf); 202 203 if (i == 20) 204 save_offset = offset; 205 printf(" event %3d ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n", 206 i++, ts, record_size, size, index, offset); 207 event = kbuffer_next_event(kbuf, NULL); 208 } 209 } while (event); 210 211 if (!event) 212 printf("Finished sub buffer\n"); 213 214 if (save_offset > 0) { 215 event = kbuffer_read_at_offset(kbuf, save_offset, &ts); 216 if (!event) { 217 fprintf(stderr, "Funny, can't find event 20 at offset %d\n", save_offset); 218 exit(-1); 219 } 220 record_size = kbuffer_curr_size(kbuf); 221 offset = kbuffer_curr_offset(kbuf); 222 index = kbuffer_curr_index(kbuf); 223 size = kbuffer_event_size(kbuf); 224 225 printf("\n saved event 20 ts:%lld\trecord_size:%d size:%d\tindex:%d offset:%d\n\n", 226 ts, record_size, size, index, offset); 227 } 228 kbuffer_free(kbuf); 229 230 return 0; 231} 232-- 233FILES 234----- 235[verse] 236-- 237*event-parse.h* 238 Header file to include in order to have access to the library APIs. 239*-ltraceevent* 240 Linker switch to add when building a program that uses the library. 241-- 242 243SEE ALSO 244-------- 245*libtraceevent*(3), *trace-cmd*(1) 246 247AUTHOR 248------ 249[verse] 250-- 251*Steven Rostedt* <[email protected]>, author of *libtraceevent*. 252-- 253REPORTING BUGS 254-------------- 255Report bugs to <[email protected]> 256 257LICENSE 258------- 259libtraceevent is Free Software licensed under the GNU LGPL 2.1 260 261RESOURCES 262--------- 263https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ 264