xref: /aosp_15_r20/external/libtraceevent/Documentation/libtraceevent-kbuffer-read.txt (revision 436bf2bcd5202612ffffe471bbcc1f277cc8d28e)
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