Movatterモバイル変換


[0]ホーム

URL:


man7.org > Linux >man-pages

Linux/UNIX system programming training


tep_plugin_kvm_get_func(3) — Linux manual page

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

LIBTRACEEVENT(3)           libtraceevent ManualLIBTRACEEVENT(3)

NAME        top

       tep_plugin_kvm_get_func, tep_plugin_kvm_put_func - Add function       name for instruction pointer of kvm plugin

SYNOPSIS        top

#include <event-parse.h>       const char *tep_plugin_kvm_get_func(struct tep_event *event,                                           struct tep_record *record,                                           unsigned long long *paddr);       voidtep_plugin_kvm_put_func(const char *func);

DESCRIPTION        top

       The functionstep_plugin_kvm_get_func()andtep_plugin_kvm_put_func()are not to be called by an application,       but instead are to be defined by an application.       Certain events (like kvm_exit and kvm_entry) have the instruction       pointer of where in the guest the context changed from guest to       host. As the host only knows the instruction pointer and does not       have information about what function in the guest that instruction       pointer belongs to, it can only print the address.       But the application may have more information about the guest, and       know where the guest was when the exit occurred, and also even       know the function name of that address.       The KVM plugin for libtraceevent is called on these events, and       then callstep_plugin_kvm_get_func()to see if that function can       resolve the instruction pointer address to a real function name.       If the return is non NULL, it will print the function in the       output for that event.       These functions are currently defined as weak functions within the       plugin, as to not require them to be defined elsewhere. For an       application to override the weak function, it will need to define       the function in a file that gets compiled with-rdynamic. That       will tell the dynamic linker to examine that object file and use       function names to resolve weak functions in other shared objects       (in this case the KVM plugin shared object).       If the application definestep_plugin_kvm_get_func(), it must use       the above prototype. Theevent will hold the KVM event that has       the instruction pointer field. Therecord will be the instance of       that event. The application’s function does not need to use these       parameters, but they may be useful for finding the function name       for the address. Thepaddr is a pointer to a 64 bit value (where       only 32 bits may be used on 32 bit machines). This value is the       instruction pointer to look up. If the application knows the start       address of the function as well, it can setpaddr to that address,       and the KVM plugin will also append a "+offset" to the function       name where the offset is the original value inpaddr minus the       value inpaddr when it is called. Finally, the application should       return the function name as a nul terminated string if one is       found.       If the returned string oftep_plugin_kvm_get_func()was allocated,       the KVM plugin will calltep_plugin_kvm_put_func()when it is       through with it, passing the value returned bytep_plugin_kvm_get_func()asfunc. This allows the application to       free it if necessary.

RETURN VALUE        top

       Thetep_plugin_kvm_get_func()is not to be called by the       application but instead is to be defined by the application. It       should return a nul terminated string representing the function       for the given instruction pointer passed to it by reference inpaddr. It can then optionally update thepaddr to a value that       holds the start of the function. The string returned may be freed       by thetep_plugin_kvm_put_func()that the application should       define to clean up the string.       The below example needs to be compiled with the-rdynamicflag so       that the dynamic linker can resolve thetep_plugin_kvm_get_func()       andtep_plugin_kvm_put_func()functions.       When run against a trace.dat file produced bytrace-cmd(1)       recording the kvm_exit and kvm_entry events on a guest, and then       the guest’s /proc/kallsyms file is passed as the second parameter,       the output produced will look something like:           CPU 0/KVM-20407 83156.177626 [000] kvm_exit     reason APIC_ACCESS rip 0xffffffffb0056ee2 exit native_apic_mem_write+0x2 info 10b0 0           CPU 0/KVM-20407 83156.177632 [000] kvm_entry     vcpu 0 rip 0xffffffffb0056ee8 enter native_apic_mem_write+0x8       But without those callbacks, it would look like:           CPU 0/KVM-20407 83156.177626 [000] kvm_exit     reason APIC_ACCESS rip 0xffffffffb0056ee2 info 10b0 0           CPU 0/KVM-20407 83156.177632 [000] kvm_entry     vcpu 0 rip 0xffffffffb0056ee8

EXAMPLE        top

           #include <stdio.h>           #include <stdlib.h>           #include <event-parse.h>           #include <trace-cmd.h>           #include <sys/stat.h>           static struct tep_handle *tep;           const char *tep_plugin_kvm_get_func(struct tep_event *event, struct tep_record *record,                                               unsigned long long *paddr)           {                   const char *func;                   char *event_func;                   char *ename;                   func = tep_find_function(tep, *paddr);                   if (!func)                           return NULL;                   if (strcmp(event->name, "kvm_exit") == 0)                           ename = "exit";                   else                           ename = "enter";                   /*                    * Normally, passing back func directly is sufficient and then                    * tep_plugin_kvm_put_func() would not be required. But this example                    * is showing how to handle allocation of the returned string.                    */                   event_func = malloc(strlen(ename) + strlen(func) + 2);                   if (!event_func)                           return NULL;                   sprintf(event_func, "%s %s", ename, func);                   *paddr = tep_find_function_address(tep, *paddr);                   return event_func;           }           void tep_plugin_kvm_put_func(const char *func)           {                   char *f = (char *)func;                   free(f);           }           static int show_event(struct tracecmd_input *handle, struct tep_event *event,                                 struct tep_record *record, int cpu, void *data)           {                   static struct trace_seq seq;                   tep = data;                   if (!seq.buffer)                           trace_seq_init(&seq);                   trace_seq_reset(&seq);                   tep_print_event(tracecmd_get_tep(handle), &seq, record,                                   "%s-%d\t%6.1000d [%03d] %s\t%s\n",                                   TEP_PRINT_COMM, TEP_PRINT_PID,                                   TEP_PRINT_TIME, TEP_PRINT_CPU,                                   TEP_PRINT_NAME, TEP_PRINT_INFO);                   trace_seq_terminate(&seq);                   trace_seq_do_printf(&seq);                   return 0;           }           int main(int argc, char **argv)           {                   struct tracecmd_input *handle;                   struct tep_handle *guest_tep;                   struct stat st;                   FILE *fp;                   char *buf;                   if (argc < 3) {                           printf("usage: trace.dat guest_kallsyms_file\n");                           exit(-1);                   }                   handle = tracecmd_open(argv[1], 0);                   if (!handle) {                           perror(argv[1]);                           exit(-1);                   }                   /* Just for kallsyms parsing */                   guest_tep = tep_alloc();                   if (!guest_tep)                           exit(-1);                   if (stat(argv[2], &st) < 0) {                           perror(argv[2]);                           exit(-1);                   }                   buf = malloc(st.st_size + 1);                   if (!buf)                           exit(-1);                   fp = fopen(argv[2], "r");                   if (!fp) {                           perror(argv[2]);                           exit(-1);                   }                   if (fread(buf, st.st_size, 1, fp) < 0) {                           perror(argv[2]);                           exit(-1);                   }                   buf[st.st_size] = '\0';                   if (tep_parse_kallsyms(guest_tep, buf) < 0) {                           printf("Failed to parse %s\n", argv[2]);                           exit(-1);                   }                   free(buf);                   tracecmd_follow_event(handle, "kvm", "kvm_exit", show_event, guest_tep);                   tracecmd_follow_event(handle, "kvm", "kvm_entry", show_event, guest_tep);                   tracecmd_iterate_events(handle, NULL, 0, NULL, NULL);                   tep_free(guest_tep);                   tracecmd_close(handle);           }

FILES        top

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

SEE ALSO        top

libtraceevent(3),trace-cmd(1)

REPORTING BUGS        top

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

LICENSE        top

       libtraceevent is Free Software licensed under the GNU LGPL 2.1

RESOURCES        top

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

NOTES        top

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

COLOPHON        top

       This page is part of thelibtraceevent (Linux kernel trace event       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/libtraceevent.git⟩       on 2025-08-11.  (At that time, the date of the most recent commit       that was found in the repository was 2025-05-30.)  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 isnot part of the original manual page), send a       mail to man-pages@man7.orglibtraceevent 1.7.3             09/24/2023LIBTRACEEVENT(3)


HTML rendering created 2025-09-06 byMichael Kerrisk, author ofThe Linux Programming Interface.

For details of in-depthLinux/UNIX system programming training courses that I teach, lookhere.

Hosting byjambit GmbH.

Cover of TLPI


[8]ページ先頭

©2009-2025 Movatter.jp