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