From 5fd4c8719d59785177b44e8f4a3674d3ddf5841a Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Sat, 28 May 2016 16:02:12 -0700 Subject: [PATCH] improve go binding memory leaks --- bindings/go/unicorn/hook.go | 7 +++---- bindings/go/unicorn/unicorn.go | 7 ++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bindings/go/unicorn/hook.go b/bindings/go/unicorn/hook.go index 0a1a7d6f..1a5477cf 100644 --- a/bindings/go/unicorn/hook.go +++ b/bindings/go/unicorn/hook.go @@ -18,7 +18,6 @@ type HookData struct { type Hook uint64 -var hookToUintptr = make(map[Hook]uintptr) var hookDataMap = make(map[uintptr]*HookData) //export hookCode @@ -105,13 +104,13 @@ func (u *uc) HookAdd(htype int, cb interface{}, begin, end uint64, extra ...int) C.uc_hook_add_wrap(u.handle, &h2, C.uc_hook_type(htype), callback, C.uintptr_t(uptr), C.uint64_t(begin), C.uint64_t(end)) } hookDataMap[uptr] = data - hookToUintptr[Hook(h2)] = uptr + u.hooks[Hook(h2)] = uptr return Hook(h2), nil } func (u *uc) HookDel(hook Hook) error { - if uptr, ok := hookToUintptr[hook]; ok { - delete(hookToUintptr, hook) + if uptr, ok := u.hooks[hook]; ok { + delete(u.hooks, hook) delete(hookDataMap, uptr) } return errReturn(C.uc_hook_del(u.handle, C.uc_hook(hook))) diff --git a/bindings/go/unicorn/unicorn.go b/bindings/go/unicorn/unicorn.go index 06c2c237..59ad50e5 100644 --- a/bindings/go/unicorn/unicorn.go +++ b/bindings/go/unicorn/unicorn.go @@ -60,6 +60,7 @@ type Unicorn interface { type uc struct { handle *C.uc_engine final sync.Once + hooks map[Hook]uintptr } type UcOptions struct { @@ -81,7 +82,7 @@ func NewUnicorn(arch, mode int) (Unicorn, error) { if ucerr := C.uc_open(C.uc_arch(arch), C.uc_mode(mode), &handle); ucerr != ERR_OK { return nil, UcError(ucerr) } - u := &uc{handle: handle} + u := &uc{handle: handle, hooks: make(map[Hook]uintptr)} runtime.SetFinalizer(u, func(u *uc) { u.Close() }) return u, nil } @@ -89,6 +90,10 @@ func NewUnicorn(arch, mode int) (Unicorn, error) { func (u *uc) Close() (err error) { u.final.Do(func() { if u.handle != nil { + for _, uptr := range u.hooks { + delete(hookDataMap, uptr) + } + u.hooks = nil err = errReturn(C.uc_close(u.handle)) u.handle = nil }