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