tracefs_dynevent_create(3) — Linux manual page

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

LIBTRACEFS(3)               libtracefs Manual              LIBTRACEFS(3)

NAME         top

       tracefs_dynevent_create, tracefs_dynevent_destroy,
       tracefs_dynevent_destroy_all, tracefs_dynevent_free,
       tracefs_dynevent_list_free, tracefs_dynevent_get,
       tracefs_dynevent_get_all, tracefs_dynevent_info,
       tracefs_dynevent_get_event - Create, destroy, free and get
       dynamic events.

SYNOPSIS         top

       #include <tracefs.h>

       struct tracefs_dynevent;
       enum tracefs_dynevent_type;
       int tracefs_dynevent_create(struct tracefs_dynevent *devent);
       int tracefs_dynevent_destroy(struct tracefs_dynevent *devent, bool force);
       int tracefs_dynevent_destroy_all(unsigned int types, bool force);
       void tracefs_dynevent_free(struct tracefs_dynevent *devent);
       void tracefs_dynevent_list_free(struct tracefs_dynevent **events);
       struct tracefs_dynevent *tracefs_dynevent_get(enum tracefs_dynevent_type type, const char *system, const char *event);
       struct tracefs_dynevent **tracefs_dynevent_get_all(unsigned int types, const char *system);
       enum tracefs_dynevent_type tracefs_dynevent_info(struct tracefs_dynevent *dynevent, char **system, char **event, char **prefix, char **addr, char **format);
       struct tep_event *tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dynevent);

DESCRIPTION         top

       The tracefs_dynevent_create() function creates dynamic event
       devent in the system.

       The tracefs_dynevent_destroy() function removes dynamic event
       devent from the system. If force is true, the function will
       attempt to disable all events in all trace instances, before
       removing the dynamic event. The devent context is not freed, use
       tracefs_dynevent_free() to free it.

       The tracefs_dynevent_destroy_all() function removes all dynamic
       events of given types from the system. The types parameter is a
       type of specific dynamic event, or a bitmask of dynamic events
       types tracefs_dynevent_type, that will be removed. If types is 0,
       dynamic events from all types will be removed. If force is true,
       the function will attempt to disable all events in all trace
       instances, before removing the dynamic events.

       The tracefs_dynevent_get() function allocates and returns a
       single instance of a dynamic event that matches the given type,
       system and event that is passed to it. NULL is returned if there
       is no match. The returned event is what is found in the system,
       and must be freed with tracefs_dynevent_free(). If system is
       NULL, then the first event of any system of the given type that
       has the name of event will be returned.

       The tracefs_dynevent_get_all() function allocates and returns an
       array of pointers to dynamic events of given types that exist in
       the system. The last element of the array is a NULL pointer. The
       array must be freed with tracefs_dynevent_list_free(). If there
       are no events a NULL pointer is returned. The types parameter is
       a type of specific dynamic event, or a bitmask of dynamic events
       types tracefs_dynevent_type, that will be retrieved. If types is
       0, dynamic events from all types will be retrieved.

       The tracefs_dynevent_free() function frees a dynamic event
       context devent.

       The tracefs_dynevent_list_free() function frees an array of
       pointers to dynamic event, returned by tracefs_dynevent_get_all()
       API.

       The tracefs_dynevent_info() function returns the type and
       information of a given dynamic event dynevent. If any of the
       system, event, prefix, addr or format arguments are not NULL,
       then strings are allocated and returned back via these arguments.
       The system and event holds the system and the name of the dynamic
       event. If prefix is non NULL, then it will hold an allocated
       string that holds the prefix portion of the dynamic event (the
       content up to the ":", exluding it). If addr is non NULL, it will
       hold the address or function that the dynamic event is attached
       to, if relevant for this event type. If format is non NULL, it
       will hold the format string of the dynamic event. Note, that the
       content in group, event, prefix, addr, and format must be freed
       with free(3) if they are set.

       The tracefs_dynevent_get_event() function returns a tep event,
       describing the given dynamic event. The API detects any newly
       created or removed dynamic events. The returned pointer to tep
       event is controlled by @tep and must not be freed.

RETURN VALUE         top

       tracefs_dynevent_create() returns 0 on success, or -1 on error.
       If a parsing error occurs then tracefs_error_last(3) may be used
       to retrieve the error message explaining the parsing issue.

       tracefs_dynevent_destroy() and tracefs_dynevent_destroy_all()
       return 0 on success, or -1 on error. If force is enabled, the
       functions may fail on disabling the events.

       tracefs_dynevent_get() function returns an allocated dynamic
       event from the system that matches the type, system and event
       given.

       tracefs_dynevent_get_all() function returns allocated array of
       pointers to dynamic events, or NULL in case of an error or in
       case there are no events in the system. That array must be freed
       by tracefs_dynevent_list_free().

       tracefs_dynevent_info() returns the type of the given dynamic
       event or TRACEFS_DYNEVENT_UNKNOWN on error. If system, event,
       prefix, addr, or format are non NULL, they will contain allocated
       strings that must be freed by free(3).

       The tracefs_dynevent_get_event() function returns a pointer to a
       tep event or NULL in case of an error or if the requested dynamic
       event is missing. The returned pointer to tep event is controlled
       by @tep and must not be freed.

ERRORS         top

       The following errors are for all the above calls:

       ENODEV dynamic events of requested type are not configured for
       the running kernel.

       ENOMEM Memory allocation error.

       tracefs_dynevent_create() can fail with the following errors:

       EINVAL Most likely a parsing error occurred (use
       tracefs_error_last(3) to possibly see what that error was).

       Other errors may also happen caused by internal system calls.

EXAMPLE         top

           #include <stdlib.h>
           #include <unistd.h>
           #include <sys/wait.h>

           #include <tracefs.h>

           static struct tep_event *open_event;
           static struct tep_format_field *file_field;

           static struct tep_event *openret_event;
           static struct tep_format_field *ret_field;

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

                   trace_seq_init(&seq);
                   tep_print_event(event->tep, &seq, record, "%d-%s: ", TEP_PRINT_PID, TEP_PRINT_COMM);

                   if (event->id == open_event->id) {
                           trace_seq_puts(&seq, "open file='");
                           tep_print_field(&seq, record->data, file_field);
                           trace_seq_puts(&seq, "'\n");
                   } else if (event->id == openret_event->id) {
                           unsigned long long ret;
                           tep_read_number_field(ret_field, record->data, &ret);
                           trace_seq_printf(&seq, "open ret=%lld\n", ret);
                   } else {
                           goto out;
                   }

                   trace_seq_terminate(&seq);
                   trace_seq_do_printf(&seq);
           out:
                   trace_seq_destroy(&seq);

                   return 0;
           }

           static pid_t run_exec(char **argv, char **env)
           {
                   pid_t pid;

                   pid = fork();
                   if (pid)
                           return pid;

                   execve(argv[0], argv, env);
                   perror("exec");
                   exit(-1);
           }

           const char *mykprobe = "my_kprobes";

           int main (int argc, char **argv, char **env)
           {
                   struct tracefs_dynevent *kprobe, *kretprobe;
                   const char *sysnames[] = { mykprobe, NULL };
                   struct tracefs_instance *instance;
                   struct tep_handle *tep;
                   pid_t pid;

                   if (argc < 2) {
                           printf("usage: %s command\n", argv[0]);
                           exit(-1);
                   }

                   instance = tracefs_instance_create("exec_open");
                   if (!instance) {
                           perror("creating instance");
                           exit(-1);
                   }

                   tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);

                   kprobe = tracefs_kprobe_alloc(mykprobe, "open", "do_sys_openat2",
                                                 "file=+0($arg2):ustring flags=+0($arg3):x64 mode=+8($arg3):x64\n");
                   kretprobe = tracefs_kretprobe_alloc(mykprobe, "openret", "do_sys_openat2", "ret=%ax", 0);
                   if (!kprobe || !kretprobe) {
                           perror("allocating dynamic events");
                           exit(-1);
                   }

                   if (tracefs_dynevent_create(kprobe) || tracefs_dynevent_create(kretprobe)){
                           char *err = tracefs_error_last(NULL);
                           perror("Failed to create kprobes:");
                           if (err && strlen(err))
                                   fprintf(stderr, "%s\n", err);
                           exit(-1);
                   }

                   tep = tracefs_local_events_system(NULL, sysnames);
                   if (!tep) {
                           perror("reading events");
                           exit(-1);
                   }
                   open_event = tep_find_event_by_name(tep, mykprobe, "open");
                   file_field = tep_find_field(open_event, "file");

                   openret_event = tep_find_event_by_name(tep, mykprobe, "openret");
                   ret_field = tep_find_field(openret_event, "ret");

                   tracefs_event_enable(instance, mykprobe, NULL);
                   pid = run_exec(&argv[1], env);

                   /* Let the child start to run */
                   sched_yield();

                   do {
                           tracefs_load_cmdlines(NULL, tep);
                           tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, NULL);
                   } while (waitpid(pid, NULL, WNOHANG) != pid);

                   /* Will disable the events */
                   tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
                   tracefs_dynevent_free(kprobe);
                   tracefs_dynevent_free(kretprobe);
                   tracefs_instance_destroy(instance);
                   tep_free(tep);

                   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]>
           Yordan Karadzhov <y.karadz@gmail.com[3]>

REPORTING BUGS         top

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

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) 2021 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. y.karadz@gmail.com
           mailto:y.karadz@gmail.com

        4. 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
       2023-12-22.  (At that time, the date of the most recent commit
       that was found in the repository was 2023-07-05.)  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.7.0               12/22/2023                  LIBTRACEFS(3)

Pages that refer to this page: tracefs_eprobe_alloc(3)tracefs_kprobe_alloc(3)tracefs_uprobe_alloc(3)