diff options
Diffstat (limited to 'tests/plugin/syscall.c')
-rw-r--r-- | tests/plugin/syscall.c | 144 |
1 files changed, 0 insertions, 144 deletions
diff --git a/tests/plugin/syscall.c b/tests/plugin/syscall.c deleted file mode 100644 index 72e1a5b..0000000 --- a/tests/plugin/syscall.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2020, Matthias Weckbecker <matthias@weckbecker.name> - * - * License: GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ -#include <inttypes.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> -#include <glib.h> - -#include <qemu-plugin.h> - -QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; - -typedef struct { - int64_t num; - int64_t calls; - int64_t errors; -} SyscallStats; - -static GMutex lock; -static GHashTable *statistics; - -static SyscallStats *get_or_create_entry(int64_t num) -{ - SyscallStats *entry = - (SyscallStats *) g_hash_table_lookup(statistics, GINT_TO_POINTER(num)); - - if (!entry) { - entry = g_new0(SyscallStats, 1); - entry->num = num; - g_hash_table_insert(statistics, GINT_TO_POINTER(num), (gpointer) entry); - } - - return entry; -} - -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) -{ - if (statistics) { - SyscallStats *entry; - g_mutex_lock(&lock); - entry = get_or_create_entry(num); - entry->calls++; - g_mutex_unlock(&lock); - } 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 (statistics) { - SyscallStats *entry; - - g_mutex_lock(&lock); - /* Should always return an existent entry. */ - entry = get_or_create_entry(num); - if (ret < 0) { - entry->errors++; - } - g_mutex_unlock(&lock); - } else { - g_autofree gchar *out = g_strdup_printf( - "syscall #%" PRIi64 " returned -> %" PRIi64 "\n", num, ret); - qemu_plugin_outs(out); - } -} - -static void print_entry(gpointer val, gpointer user_data) -{ - SyscallStats *entry = (SyscallStats *) val; - int64_t syscall_num = entry->num; - g_autofree gchar *out = g_strdup_printf( - "%-13" PRIi64 "%-6" PRIi64 " %" PRIi64 "\n", - syscall_num, entry->calls, entry->errors); - qemu_plugin_outs(out); -} - -static gint comp_func(gconstpointer ea, gconstpointer eb) -{ - SyscallStats *ent_a = (SyscallStats *) ea; - SyscallStats *ent_b = (SyscallStats *) eb; - - return ent_a->calls > ent_b->calls ? -1 : 1; -} - -/* ************************************************************************* */ -static void plugin_exit(qemu_plugin_id_t id, void *p) -{ - if (!statistics) { - return; - } - - g_mutex_lock(&lock); - GList *entries = g_hash_table_get_values(statistics); - entries = g_list_sort(entries, comp_func); - qemu_plugin_outs("syscall no. calls errors\n"); - - g_list_foreach(entries, print_entry, NULL); - - g_list_free(entries); - g_hash_table_destroy(statistics); - g_mutex_unlock(&lock); -} - -QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, - const qemu_info_t *info, - int argc, char **argv) -{ - bool do_print = false; - - for (int i = 0; i < argc; i++) { - char *opt = argv[i]; - g_auto(GStrv) tokens = g_strsplit(opt, "=", 2); - - if (g_strcmp0(tokens[0], "print") == 0) { - if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_print)) { - fprintf(stderr, "boolean argument parsing failed: %s\n", opt); - } - } else { - fprintf(stderr, "unsupported argument: %s\n", argv[i]); - return -1; - } - } - - if (!do_print) { - statistics = g_hash_table_new_full(NULL, g_direct_equal, NULL, g_free); - } - - 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); - return 0; -} |