tracefs_iterate_raw_events(3) — Linux manual page

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUE | EXAMPLE | FILES | SEE ALSO | AUTHOR | REPORTING BUGS | LICENSE | RESOURCES | COPYING | NOTES | COLOPHON

LIBTRACEFS(3)               libtracefs Manual               LIBTRACEFS(3)

NAME         top

       tracefs_iterate_raw_events, tracefs_iterate_stop,
       tracefs_follow_event, tracefs_follow_missed_events,
       tracefs_follow_event_clear, tracefs_follow_missed_events_clear,
       tracefs_iterate_snapshot_events - Iterate over events in the ring
       buffer

SYNOPSIS         top

       #include <tracefs.h>

       int tracefs_iterate_raw_events(struct tep_handle *tep, struct tracefs_instance *instance,
                                        cpu_set_t *cpus, int cpu_size,
                                        int (*callback)(struct tep_event *, struct tep_record *, int, void *),
                                        void *callback_context);
       void tracefs_iterate_stop(struct tracefs_instance *instance);

       int tracefs_follow_event(struct tep_handle *tep, struct tracefs_instance *instance,
                                 const char *system, const char *event_name,
                                 int (*callback)(struct tep_event *,
                                                 struct tep_record *,
                                                 int, void *),
                                 void *callback_data);
       int tracefs_follow_missed_events(struct tracefs_instance *instance,
                                 int (*callback)(struct tep_event *,
                                                 struct tep_record *,
                                                 int, void *),
                                 void *callback_data);

       int tracefs_follow_event_clear(struct tracefs_instance *instance,
                                 const char *system, const char *event_name);
       int tracefs_follow_missed_events_clear(struct tracefs_instance *instance);

       int tracefs_iterate_snapshot_events(struct tep_handle *tep, struct tracefs_instance *instance,
                                        cpu_set_t *cpus, int cpu_size,
                                        int (*callback)(struct tep_event *, struct tep_record *, int, void *),
                                        void *callback_context);

DESCRIPTION         top

       Trace iterator over raw events.

       The tracefs_iterate_raw_events() function will read the tracefs
       raw data buffers and call the specified callback function for
       every event it encounters. Events are iterated in sorted order:
       oldest first. An initialized tep handler is required (See
       tracefs_local_events(3)). If instance is NULL, then the toplevel
       tracefs buffer is used, otherwise the buffer for the corresponding
       instance is read. To filter only on a subset of CPUs, cpus and
       cpu_size may be set to only call callback with events that
       occurred on the CPUs specified, otherwise if cpus is NULL then the
       callback function will be called for all events, and cpu_size is
       ignored. The callback function will be called with the following
       parameters: A pointer to a struct tep_event that corresponds to
       the type of event the record is; The record representing the
       event; The CPU that the event occurred on; and a pointer to user
       specified callback_context. If the callback returns non-zero, the
       iteration stops.

       The tracefs_iterate_snapshot_events() works the same as
       tracefs_iterate_raw_events() except that it works on the snapshot
       buffer.

       Use tracefs_iterate_stop() to force a executing
       tracefs_iterate_raw_events() to halt. This can be called from
       either a callback that is called by the iterator (even though a
       return of non-zero will stop it), or from another thread.

       The tracefs_follow_event() is used with
       tracefs_iterate_raw_events() but intead of the callback being
       called for every event, it is only called for the specified system
       / event_name given to the function. The callback is the same as
       for tracefs_iterate_raw_events(), and the passed in
       callback_context will be passed to the callback as well. Note, if
       it returns something other than 0, it will stop the loop before
       the callback of tracefs_iterate_raw_events() is called.

       The tracefs_follow_missed_events() will call the callback when
       missed events are detected. It will set the record parameter of
       the callback to the record that came after the missed events and
       event will be of the type of event record is. cpu will be set to
       the CPU that missed the events, and callback_data will be the
       content that was passed in to the function.

       The tracefs_follow_event_clear() will remove followers from
       instance that match system and event_name. If system and
       event_name are both NULL, then it will remove all event followers
       associated to instance. If just system is NULL, then it will
       remove all followers that follow events that match event_name. If
       just event_name is NULL, then it will remove all followers that
       are attached to events that are apart of a system that matches
       system.

       The tracefs_follow_missed_events_clear() will remove all followers
       for missed events.

RETURN VALUE         top

       The tracefs_iterate_raw_events() function returns -1 in case of an
       error or 0 otherwise.

       Both tracefs_follow_event_clear() and
       tracefs_follow_missed_events_clear() return 0 on success and -1 on
       error, or if it found no followers that match and should be
       removed.

EXAMPLE         top

           #include <unistd.h>
           #include <tracefs.h>
           #include <stdbool.h>
           #include <signal.h>

           struct my_struct {
                   bool            stopped;
           };

           #define MAX_COUNT 500000
           static int counter;

           static int callback(struct tep_event *event, struct tep_record *record,
                               int cpu, void *data)
           {
                   struct my_struct *my_data = data;
                   static struct trace_seq seq;

                   if (counter++ > MAX_COUNT) {
                           my_data->stopped = true;
                           return 1;
                   }

                   if (!seq.buffer)
                           trace_seq_init(&seq);

                   tep_print_event(event->tep, &seq, record, "%16s-%-5d [%03d] %6.1000d %s: %s\n",
                                   TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU,
                                   TEP_PRINT_TIME, TEP_PRINT_NAME, TEP_PRINT_INFO);
                   trace_seq_terminate(&seq);
                   trace_seq_do_printf(&seq);
                   trace_seq_reset(&seq);
                   return 0;
           }

           static int sched_callback(struct tep_event *event, struct tep_record *record,
                                     int cpu, void *data)
           {
                   static struct tep_format_field *prev_pid;
                   static struct tep_format_field *next_pid;
                   unsigned long long pid;
                   int this_pid = *(int *)data;

                   if (!prev_pid) {
                           prev_pid = tep_find_field(event, "prev_pid");
                           next_pid = tep_find_field(event, "next_pid");
                           if (!prev_pid || !next_pid) {
                                   fprintf(stderr, "No pid fields??\n");
                                   return -1;
                           }
                   }

                   tep_read_number_field(prev_pid, record->data, &pid);
                   if (pid == this_pid)
                           printf("WE ARE LEAVING!\n");
                   tep_read_number_field(next_pid, record->data, &pid);
                   if (pid == this_pid)
                           printf("WE ARE ARRIVING!\n");
                   return 0;
           }

           static int missed_callback(struct tep_event *event, struct tep_record *record,
                                      int cpu, void *data)
           {
                   printf("OOPS! cpu %d dropped ", cpu);
                   if (record->missed_events > 0)
                           printf("%lld ", record->missed_events);
                   printf("events\n");
                   return 0;
           }

           static struct tracefs_instance *instance;
           static struct my_struct my_data;

           static void sig(int s)
           {
                   tracefs_iterate_stop(instance);
                   my_data.stopped = true;
           }

           int main (int argc, char **argv, char **env)
           {
                   struct tep_handle *tep;
                   int this_pid = getpid();

                   instance = tracefs_instance_create("my-buffer");
                   if (!instance)
                           return -1;

                   signal(SIGINT, sig);

                   tracefs_event_enable(instance, NULL, NULL);
                   sleep(1);
                   tracefs_event_disable(instance, NULL, NULL);
                   tep = tracefs_local_events(NULL);
                   tep_load_plugins(tep);
                   tracefs_follow_missed_events(instance, missed_callback, NULL);
                   tracefs_follow_event(tep, instance, "sched", "sched_switch", sched_callback, &this_pid);
                   tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, &my_data);

                   /* Note, the clear here is to show how to clear all followers
                    * in case tracefs_iterate_raw_events() is called again, but
                    * does not want to include the followers. It's not needed
                    * here because tracefs_instance_free() will clean them up.
                    */
                   tracefs_follow_event_clear(instance, NULL, NULL);
                   tracefs_follow_missed_events_clear(instance);

                   tracefs_instance_destroy(instance);
                   tracefs_instance_free(instance);

                   if (my_data.stopped) {
                           if (counter > MAX_COUNT)
                                   printf("Finished max count\n");
                           else
                                   printf("Finished via signal\n");
                   }

                   return 0;
           }

FILES         top

           tracefs.h
                   Header file to include in order to have access to the library APIs.
           -ltracefs
                   Linker switch to add when building a program that uses the library.

SEE ALSO         top

       libtracefs(3), libtraceevent(3), trace-cmd(1)

AUTHOR         top

           Steven Rostedt <rostedt@goodmis.org[1]>
           Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>

REPORTING BUGS         top

       Report bugs to <linux-trace-devel@vger.kernel.org[3]>

LICENSE         top

       libtracefs is Free Software licensed under the GNU LGPL 2.1

RESOURCES         top

       https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 

COPYING         top

       Copyright (C) 2020 VMware, Inc. Free use of this software is
       granted under the terms of the GNU Public License (GPL).

NOTES         top

        1. rostedt@goodmis.org
           mailto:rostedt@goodmis.org

        2. tz.stoyanov@gmail.com
           mailto:tz.stoyanov@gmail.com

        3. linux-trace-devel@vger.kernel.org
           mailto:linux-trace-devel@vger.kernel.org

COLOPHON         top

       This page is part of the libtracefs (Linux kernel trace file
       system library) project.  Information about the project can be
       found at ⟨https://www.trace-cmd.org/⟩.  If you have a bug report
       for this manual page, see ⟨https://www.trace-cmd.org/⟩.  This page
       was obtained from the project's upstream Git repository
       ⟨https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git⟩ on
       2025-02-02.  (At that time, the date of the most recent commit
       that was found in the repository was 2024-11-22.)  If you discover
       any rendering problems in this HTML version of the page, or you
       believe there is a better or more up-to-date source for the page,
       or you have corrections or improvements to the information in this
       COLOPHON (which is not part of the original manual page), send a
       mail to man-pages@man7.org

libtracefs 1.8.1                01/02/2025                  LIBTRACEFS(3)

Pages that refer to this page: tracefs_snapshot_snap(3)