From 6b9f17f2f7c46498431cc873aae954641e61725d Mon Sep 17 00:00:00 2001 From: danghvu Date: Fri, 8 Jul 2016 11:16:23 -0500 Subject: [PATCH] memleak: refactor unicorn_common.h, move stuff to uc_close --- qemu/unicorn_common.h | 57 +++++++------------------------------------ uc.c | 49 ++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h index c0cbe461..080d9202 100644 --- a/qemu/unicorn_common.h +++ b/qemu/unicorn_common.h @@ -2,6 +2,7 @@ #define UNICORN_COMMON_H_ #include "tcg.h" +#include // This header define common patterns/codes that will be included in all arch-sepcific // codes for unicorns purposes. @@ -19,23 +20,12 @@ static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr, return !cpu_physical_memory_rw(as, addr, (void *)buf, len, 1); } -static void free_table(gpointer key, gpointer value, gpointer data) -{ - TypeInfo *ti = (TypeInfo*) value; - g_free((void*) ti->class); - g_free((void*) ti->name); - g_free((void*) ti->parent); - g_free((void*) ti); -} - void tb_cleanup(struct uc_struct *uc); /** Freeing common resources */ static void release_common(void *t) { TCGContext *s = (TCGContext *)t; - struct uc_struct* uc = s->uc; - CPUState *cpu; #if TCG_TARGET_REG_BITS == 32 int i; #endif @@ -45,7 +35,9 @@ static void release_common(void *t) g_free(def->args_ct); g_free(def->sorted_args); g_free(s->tcg_op_defs); - g_free(s->code_gen_buffer); + if (s->code_gen_buffer) { + munmap(s->code_gen_buffer, s->code_gen_buffer_size); + } TCGPool *po, *to; for (po = s->pool_first; po; po = to) { @@ -55,36 +47,11 @@ static void release_common(void *t) tcg_pool_reset(s); g_hash_table_destroy(s->helpers); - // Clean memory. - phys_mem_clean(uc); - address_space_destroy(&(uc->as)); - memory_free(uc); - - // Clean CPU. - CPU_FOREACH(cpu) { - g_free(cpu->tcg_as_listener); - g_free(cpu->thread); - g_free(cpu->halt_cond); - } - - OBJECT(uc->machine_state->accelerator)->ref = 1; - OBJECT(uc->machine_state)->ref = 1; - OBJECT(uc->owner)->ref = 1; - OBJECT(uc->root)->ref = 1; - - object_unref(uc, OBJECT(uc->machine_state->accelerator)); - object_unref(uc, OBJECT(uc->machine_state)); - object_unref(uc, uc->cpu); - object_unref(uc, OBJECT(&uc->io_mem_notdirty)); - object_unref(uc, OBJECT(&uc->io_mem_unassigned)); - object_unref(uc, OBJECT(&uc->io_mem_rom)); - object_unref(uc, OBJECT(uc->root)); - g_hash_table_foreach(uc->type_table, free_table, uc); - - g_free(uc->system_memory); - - if (uc->qemu_thread_data) - free(uc->qemu_thread_data); + // TODO(danghvu): these function is not available outside qemu + // so we keep them here instead of outside uc_close. + phys_mem_clean(s->uc); + address_space_destroy(&(s->uc->as)); + memory_free(s->uc); #if TCG_TARGET_REG_BITS == 32 for(i = 0; i < s->nb_globals; i++) { @@ -97,12 +64,6 @@ static void release_common(void *t) } } #endif - - qemu_mutex_destroy(&uc->qemu_global_mutex); - qemu_cond_destroy(&uc->qemu_cpu_cond); - - // Clean cache. - tb_cleanup(uc); } static inline void uc_common_init(struct uc_struct* uc) diff --git a/uc.c b/uc.c index b9fe5654..f3346930 100644 --- a/uc.c +++ b/uc.c @@ -29,7 +29,16 @@ #include "qemu/target-sparc/unicorn.h" #include "qemu/include/hw/boards.h" +#include "qemu/include/qemu/queue.h" +static void free_table(gpointer key, gpointer value, gpointer data) +{ + TypeInfo *ti = (TypeInfo*) value; + g_free((void*) ti->class); + g_free((void*) ti->name); + g_free((void*) ti->parent); + g_free((void*) ti); +} UNICORN_EXPORT unsigned int uc_version(unsigned int *major, unsigned int *minor) @@ -283,19 +292,53 @@ uc_err uc_close(uc_engine *uc) int i; struct list_item *cur; struct hook *hook; + CPUState *cpu; + // Cleanup internally. if (uc->release) uc->release(uc->tcg_ctx); + g_free(uc->tcg_ctx); + // Cleanup CPU. + CPU_FOREACH(cpu) { + g_free(cpu->tcg_as_listener); + g_free(cpu->thread); + g_free(cpu->halt_cond); + } + + // Cleanup all objects. + OBJECT(uc->machine_state->accelerator)->ref = 1; + OBJECT(uc->machine_state)->ref = 1; + OBJECT(uc->owner)->ref = 1; + OBJECT(uc->root)->ref = 1; + + object_unref(uc, OBJECT(uc->machine_state->accelerator)); + object_unref(uc, OBJECT(uc->machine_state)); + object_unref(uc, uc->cpu); + object_unref(uc, OBJECT(&uc->io_mem_notdirty)); + object_unref(uc, OBJECT(&uc->io_mem_unassigned)); + object_unref(uc, OBJECT(&uc->io_mem_rom)); + object_unref(uc, OBJECT(uc->root)); + + // System memory. + g_free(uc->system_memory); + + // Thread relateds. + if (uc->qemu_thread_data) + free(uc->qemu_thread_data); + + qemu_mutex_destroy(&uc->qemu_global_mutex); + qemu_cond_destroy(&uc->qemu_cpu_cond); + + // Other auxilaries. free(uc->l1_map); if (uc->bounce.buffer) { free(uc->bounce.buffer); } - g_free(uc->tcg_ctx); - - g_hash_table_destroy(uc->type_table); + g_hash_table_foreach(uc->type_table, free_table, uc); + g_hash_table_unref(uc->type_table); for (i = 0; i < DIRTY_MEMORY_NUM; i++) { free(uc->ram_list.dirty_memory[i]);