Message ID | 20210415151849.26740-1-ma.mandourr@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | plugins/syscall: Added a table-like summary output | expand |
On Thu, Apr 15, 2021 at 5:20 PM Mahmoud Mandour <ma.mandourr@gmail.com> wrote: > Added a table-like output which contains the total number of calls > for each used syscall along with the number of errors that occurred. > > Per-call tracing is still available through supplying the argument > ``print`` to the plugin. > > Signed-off-by: Mahmoud Mandour <ma.mandourr@gmail.com> > --- > tests/plugin/syscall.c | 94 +++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 88 insertions(+), 6 deletions(-) > > diff --git a/tests/plugin/syscall.c b/tests/plugin/syscall.c > index 53ee2ab6c4..b92340c636 100644 > --- a/tests/plugin/syscall.c > +++ b/tests/plugin/syscall.c > @@ -16,32 +16,114 @@ > > QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; > > +typedef struct { > + int64_t calls; > + int64_t errors; > +} SyscallStats; > + > +static GHashTable *syscalls_statistics; > + > +static bool percall_print; > + > static void vcpu_syscall(qemu_plugin_id_t id, unsigned int vcpu_index, > int64_t num, uint64_t a1, uint64_t a2, > uint64_t a3, uint64_t a4, uint64_t a5, > uint64_t a6, uint64_t a7, uint64_t a8) > { > - g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", > num); > - qemu_plugin_outs(out); > + if (!percall_print) { > + SyscallStats *syscall_entry; > + > + syscall_entry = > + (SyscallStats *) g_hash_table_lookup(syscalls_statistics, > + GINT_TO_POINTER(num)); > + > + if (!syscall_entry) { > + syscall_entry = g_new(SyscallStats, 1); > + syscall_entry->calls = 1; > + syscall_entry->errors = 0; > + > + g_hash_table_insert(syscalls_statistics, GINT_TO_POINTER(num), > + (gpointer) syscall_entry); > + } else { > + syscall_entry->calls++; > + } > + } else { > + g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", > num); > + qemu_plugin_outs(out); > + } > } > > static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx, > int64_t num, int64_t ret) > +{ > + if (!percall_print) { > + SyscallStats *syscall_entry; > + > + syscall_entry = > + (SyscallStats *) g_hash_table_lookup(syscalls_statistics, > + GINT_TO_POINTER(num)); > + if (!syscall_entry) { > + qemu_plugin_outs(g_strdup_printf("%" PRIi64 "\n", num)); > + } > + if (ret < 0) { > + syscall_entry->errors++; > + } > + } else { > + g_autofree gchar *out; > + out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 > "\n", > + num, ret); > + qemu_plugin_outs(out); > + } > +} > + > +/* > ************************************************************************* */ > + > +void print_entry(gpointer key, gpointer val, gpointer user_data) > { > g_autofree gchar *out; > - out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 > "\n", > - num, ret); > + int64_t syscall_num = (int64_t) key; > + SyscallStats *syscall_entry = (SyscallStats *) val; > + out = g_strdup_printf( > + "%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n", > + syscall_num, syscall_entry->calls, syscall_entry->errors); > qemu_plugin_outs(out); > } > > -/* > ************************************************************************* */ > +static void plugin_exit(qemu_plugin_id_t id, void *p) > +{ > + if (!percall_print) { > + qemu_plugin_outs("syscall no. calls errors\n"); > + g_hash_table_foreach(syscalls_statistics, &print_entry, NULL); > + } > +} > > -static void plugin_exit(qemu_plugin_id_t id, void *p) {} > +void free_entry(gpointer entry) > +{ > + g_free(entry); > +} > > QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, > const qemu_info_t *info, > int argc, char **argv) > { > + int i; > + > + for (i = 0; i < argc; i++) { > + char *opt = argv[i]; > + if (g_strcmp0(opt, "print") == 0) { > + percall_print = true; > + } else { > + fprintf(stderr, "unsupported argument: %s\n", opt); > + return -1; > + } > + } > + > + if (!percall_print) { > + syscalls_statistics = > + g_hash_table_new_full(g_direct_hash, g_direct_equal, > + NULL, &free_entry); > + } > + > qemu_plugin_register_vcpu_syscall_cb(id, vcpu_syscall); > qemu_plugin_register_vcpu_syscall_ret_cb(id, vcpu_syscall_ret); > qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); > -- > 2.25.1 > > Hello. I just realized that this hunk: static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx, > int64_t num, int64_t ret) > +{ > + // ...... > + if (!syscall_entry) { > + qemu_plugin_outs(g_strdup_printf("%" PRIi64 "\n", num)); > + } > Is completely superfluous. I think I had it for debugging purposes. Should I resend without it or can you omit it from the patch? Yours, Mahmoud
On Fri, Apr 16, 2021 at 8:54 AM Mahmoud Mandour <ma.mandourr@gmail.com> wrote: > On Thu, Apr 15, 2021 at 5:20 PM Mahmoud Mandour <ma.mandourr@gmail.com> > wrote: > >> >> Hello. I just realized that this hunk: > > static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx, >> int64_t num, int64_t ret) >> +{ >> + // ...... >> + if (!syscall_entry) { >> + qemu_plugin_outs(g_strdup_printf("%" PRIi64 "\n", num)); >> + } >> > > Is completely superfluous. I think I had it for debugging purposes. > Should I resend without it or can you omit it from the patch? > > Nevermind, I sent a v2 patch. Yours, Mahmoud
diff --git a/tests/plugin/syscall.c b/tests/plugin/syscall.c index 53ee2ab6c4..b92340c636 100644 --- a/tests/plugin/syscall.c +++ b/tests/plugin/syscall.c @@ -16,32 +16,114 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; +typedef struct { + int64_t calls; + int64_t errors; +} SyscallStats; + +static GHashTable *syscalls_statistics; + +static bool percall_print; + static void vcpu_syscall(qemu_plugin_id_t id, unsigned int vcpu_index, int64_t num, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6, uint64_t a7, uint64_t a8) { - g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", num); - qemu_plugin_outs(out); + if (!percall_print) { + SyscallStats *syscall_entry; + + syscall_entry = + (SyscallStats *) g_hash_table_lookup(syscalls_statistics, + GINT_TO_POINTER(num)); + + if (!syscall_entry) { + syscall_entry = g_new(SyscallStats, 1); + syscall_entry->calls = 1; + syscall_entry->errors = 0; + + g_hash_table_insert(syscalls_statistics, GINT_TO_POINTER(num), + (gpointer) syscall_entry); + } else { + syscall_entry->calls++; + } + } else { + g_autofree gchar *out = g_strdup_printf("syscall #%" PRIi64 "\n", num); + qemu_plugin_outs(out); + } } static void vcpu_syscall_ret(qemu_plugin_id_t id, unsigned int vcpu_idx, int64_t num, int64_t ret) +{ + if (!percall_print) { + SyscallStats *syscall_entry; + + syscall_entry = + (SyscallStats *) g_hash_table_lookup(syscalls_statistics, + GINT_TO_POINTER(num)); + if (!syscall_entry) { + qemu_plugin_outs(g_strdup_printf("%" PRIi64 "\n", num)); + } + if (ret < 0) { + syscall_entry->errors++; + } + } else { + g_autofree gchar *out; + out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 "\n", + num, ret); + qemu_plugin_outs(out); + } +} + +/* ************************************************************************* */ + +void print_entry(gpointer key, gpointer val, gpointer user_data) { g_autofree gchar *out; - out = g_strdup_printf("syscall #%" PRIi64 " returned -> %" PRIi64 "\n", - num, ret); + int64_t syscall_num = (int64_t) key; + SyscallStats *syscall_entry = (SyscallStats *) val; + out = g_strdup_printf( + "%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n", + syscall_num, syscall_entry->calls, syscall_entry->errors); qemu_plugin_outs(out); } -/* ************************************************************************* */ +static void plugin_exit(qemu_plugin_id_t id, void *p) +{ + if (!percall_print) { + qemu_plugin_outs("syscall no. calls errors\n"); + g_hash_table_foreach(syscalls_statistics, &print_entry, NULL); + } +} -static void plugin_exit(qemu_plugin_id_t id, void *p) {} +void free_entry(gpointer entry) +{ + g_free(entry); +} QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info, int argc, char **argv) { + int i; + + for (i = 0; i < argc; i++) { + char *opt = argv[i]; + if (g_strcmp0(opt, "print") == 0) { + percall_print = true; + } else { + fprintf(stderr, "unsupported argument: %s\n", opt); + return -1; + } + } + + if (!percall_print) { + syscalls_statistics = + g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, &free_entry); + } + qemu_plugin_register_vcpu_syscall_cb(id, vcpu_syscall); qemu_plugin_register_vcpu_syscall_ret_cb(id, vcpu_syscall_ret); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
Added a table-like output which contains the total number of calls for each used syscall along with the number of errors that occurred. Per-call tracing is still available through supplying the argument ``print`` to the plugin. Signed-off-by: Mahmoud Mandour <ma.mandourr@gmail.com> --- tests/plugin/syscall.c | 94 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 6 deletions(-)