• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1libtracefs(3)
2=============
3
4NAME
5----
6tracefs_iterate_raw_events, tracefs_iterate_stop, tracefs_follow_event, tracefs_follow_missed_events,
7tracefs_follow_event_clear, tracefs_follow_missed_events_clear, tracefs_iterate_snapshot_events - Iterate over events in the ring buffer
8
9SYNOPSIS
10--------
11[verse]
12--
13*#include <tracefs.h>*
14
15int *tracefs_iterate_raw_events*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_,
16				 cpu_set_t pass:[*]_cpus_, int _cpu_size_,
17				 int (pass:[*]_callback_)(struct tep_event pass:[*], struct tep_record pass:[*], int, void pass:[*]),
18				 void pass:[*]_callback_context_);
19void *tracefs_iterate_stop*(struct tracefs_instance pass:[*]_instance_);
20
21int *tracefs_follow_event*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_,
22			  const char pass:[*]_system_, const char pass:[*]_event_name_,
23			  int (pass:[*]_callback_)(struct tep_event pass:[*],
24					  struct tep_record pass:[*],
25					  int, void pass:[*]),
26			  void pass:[*]_callback_data_);
27int *tracefs_follow_missed_events*(struct tracefs_instance pass:[*]_instance_,
28			  int (pass:[*]_callback_)(struct tep_event pass:[*],
29					  struct tep_record pass:[*],
30					  int, void pass:[*]),
31			  void pass:[*]_callback_data_);
32
33int *tracefs_follow_event_clear*(struct tracefs_instance pass:[*]_instance_,
34			  const char pass:[*]_system_, const char pass:[*]_event_name_);
35int *tracefs_follow_missed_events_clear*(struct tracefs_instance pass:[*]_instance_);
36
37int *tracefs_iterate_snapshot_events*(struct tep_handle pass:[*]_tep_, struct tracefs_instance pass:[*]_instance_,
38				 cpu_set_t pass:[*]_cpus_, int _cpu_size_,
39				 int (pass:[*]_callback_)(struct tep_event pass:[*], struct tep_record pass:[*], int, void pass:[*]),
40				 void pass:[*]_callback_context_);
41--
42
43DESCRIPTION
44-----------
45Trace iterator over raw events.
46
47The *tracefs_iterate_raw_events()* function will read the tracefs raw
48data buffers and call the specified _callback_ function for every event it
49encounters. Events are iterated in sorted order: oldest first. An initialized
50_tep_ handler is required (See *tracefs_local_events*(3)). If _instance_ is
51NULL, then the toplevel tracefs buffer is used, otherwise the buffer for
52the corresponding _instance_ is read. To filter only on a subset of CPUs,
53_cpus_ and _cpu_size_ may be set to only call _callback_ with events that
54occurred on the CPUs specified, otherwise if _cpus_ is NULL then the _callback_
55function will be called for all events, and _cpu_size_ is ignored. The
56_callback_ function will be called with the following parameters: A
57pointer to a struct tep_event that corresponds to the type of event the
58record is; The record representing the event; The CPU that the event
59occurred on; and a pointer to user specified _callback_context_. If the _callback_
60returns non-zero, the iteration stops.
61
62The *tracefs_iterate_snapshot_events()* works the same as *tracefs_iterate_raw_events()*
63except that it works on the snapshot buffer.
64
65Use *tracefs_iterate_stop()* to force a executing *tracefs_iterate_raw_events()*
66to halt. This can be called from either a callback that is called by
67the iterator (even though a return of non-zero will stop it), or from another
68thread.
69
70The *tracefs_follow_event()* is used with *tracefs_iterate_raw_events()* but
71intead of the callback being called for every event, it is only called for the
72specified _system_ / _event_name_ given to the function. The _callback_ is the
73same as for *tracefs_iterate_raw_events()*, and the passed in _callback_context_
74will be passed to the _callback_ as well. Note, if it returns something other
75than 0, it will stop the loop before the _callback_ of *tracefs_iterate_raw_events()*
76is called.
77
78The *tracefs_follow_missed_events()* will call the _callback_ when missed
79events are detected. It will set the _record_ parameter of the callback to the
80record that came after the missed events and _event_ will be of the type of
81event _record_ is. _cpu_ will be set to the CPU that missed the events, and
82_callback_data_ will be the content that was passed in to the function.
83
84The *tracefs_follow_event_clear()* will remove followers from _instance_ that
85match _system_ and _event_name_. If _system_ and _event_name_ are both NULL,
86then it will remove all event followers associated to _instance_. If just _system_
87is NULL, then it will remove all followers that follow events that match _event_name_. If just _event_name_
88is NULL, then it will remove all followers that are attached to events that are
89apart of a system that matches _system_.
90
91The *tracefs_follow_missed_events_clear()* will remove all followers for missed
92events.
93
94RETURN VALUE
95------------
96The *tracefs_iterate_raw_events()* function returns -1 in case of an error or
970 otherwise.
98
99Both *tracefs_follow_event_clear()* and *tracefs_follow_missed_events_clear()* return
1000 on success and -1 on error, or if it found no followers that match and should be removed.
101
102EXAMPLE
103-------
104[source,c]
105--
106#include <unistd.h>
107#include <tracefs.h>
108#include <stdbool.h>
109#include <signal.h>
110
111struct my_struct {
112	bool		stopped;
113};
114
115#define MAX_COUNT 500000
116static int counter;
117
118static int callback(struct tep_event *event, struct tep_record *record,
119		    int cpu, void *data)
120{
121	struct my_struct *my_data = data;
122	static struct trace_seq seq;
123
124	if (counter++ > MAX_COUNT) {
125		my_data->stopped = true;
126		return 1;
127	}
128
129	if (!seq.buffer)
130		trace_seq_init(&seq);
131
132	tep_print_event(event->tep, &seq, record, "%16s-%-5d [%03d] %6.1000d %s: %s\n",
133			TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU,
134			TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO);
135	trace_seq_terminate(&seq);
136	trace_seq_do_printf(&seq);
137	trace_seq_reset(&seq);
138	return 0;
139}
140
141static int sched_callback(struct tep_event *event, struct tep_record *record,
142			  int cpu, void *data)
143{
144	static struct tep_format_field *prev_pid;
145	static struct tep_format_field *next_pid;
146	unsigned long long pid;
147	int this_pid = *(int *)data;
148
149	if (!prev_pid) {
150		prev_pid = tep_find_field(event, "prev_pid");
151		next_pid = tep_find_field(event, "next_pid");
152		if (!prev_pid || !next_pid) {
153			fprintf(stderr, "No pid fields??\n");
154			return -1;
155		}
156	}
157
158	tep_read_number_field(prev_pid, record->data, &pid);
159	if (pid == this_pid)
160		printf("WE ARE LEAVING!\n");
161	tep_read_number_field(next_pid, record->data, &pid);
162	if (pid == this_pid)
163		printf("WE ARE ARRIVING!\n");
164	return 0;
165}
166
167static int missed_callback(struct tep_event *event, struct tep_record *record,
168			   int cpu, void *data)
169{
170	printf("OOPS! cpu %d dropped ", cpu);
171	if (record->missed_events > 0)
172		printf("%lld ", record->missed_events);
173	printf("events\n");
174	return 0;
175}
176
177static struct tracefs_instance *instance;
178static struct my_struct my_data;
179
180static void sig(int s)
181{
182	tracefs_iterate_stop(instance);
183	my_data.stopped = true;
184}
185
186int main (int argc, char **argv, char **env)
187{
188	struct tep_handle *tep;
189	int this_pid = getpid();
190
191	instance = tracefs_instance_create("my-buffer");
192	if (!instance)
193		return -1;
194
195	signal(SIGINT, sig);
196
197	tracefs_event_enable(instance, NULL, NULL);
198	sleep(1);
199	tracefs_event_disable(instance, NULL, NULL);
200	tep = tracefs_local_events(NULL);
201	tep_load_plugins(tep);
202	tracefs_follow_missed_events(instance, missed_callback, NULL);
203	tracefs_follow_event(tep, instance, "sched", "sched_switch", sched_callback, &this_pid);
204	tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, &my_data);
205
206	/* Note, the clear here is to show how to clear all followers
207	 * in case tracefs_iterate_raw_events() is called again, but
208	 * does not want to include the followers. It's not needed
209	 * here because tracefs_instance_free() will clean them up.
210	 */
211	tracefs_follow_event_clear(instance, NULL, NULL);
212	tracefs_follow_missed_events_clear(instance);
213
214	tracefs_instance_destroy(instance);
215	tracefs_instance_free(instance);
216
217	if (my_data.stopped) {
218		if (counter > MAX_COUNT)
219			printf("Finished max count\n");
220		else
221			printf("Finished via signal\n");
222	}
223
224	return 0;
225}
226--
227FILES
228-----
229[verse]
230--
231*tracefs.h*
232	Header file to include in order to have access to the library APIs.
233*-ltracefs*
234	Linker switch to add when building a program that uses the library.
235--
236
237SEE ALSO
238--------
239*libtracefs*(3),
240*libtraceevent*(3),
241*trace-cmd*(1)
242
243AUTHOR
244------
245[verse]
246--
247*Steven Rostedt* <rostedt@goodmis.org>
248*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>
249--
250REPORTING BUGS
251--------------
252Report bugs to  <linux-trace-devel@vger.kernel.org>
253
254LICENSE
255-------
256libtracefs is Free Software licensed under the GNU LGPL 2.1
257
258RESOURCES
259---------
260https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
261
262COPYING
263-------
264Copyright \(C) 2020 VMware, Inc. Free use of this software is granted under
265the terms of the GNU Public License (GPL).
266