improve go binding memory leaks

This commit is contained in:
Ryan Hileman 2016-05-28 16:02:12 -07:00
parent 1038e639f6
commit 5fd4c8719d
2 changed files with 9 additions and 5 deletions

View file

@ -18,7 +18,6 @@ type HookData struct {
type Hook uint64 type Hook uint64
var hookToUintptr = make(map[Hook]uintptr)
var hookDataMap = make(map[uintptr]*HookData) var hookDataMap = make(map[uintptr]*HookData)
//export hookCode //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)) 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 hookDataMap[uptr] = data
hookToUintptr[Hook(h2)] = uptr u.hooks[Hook(h2)] = uptr
return Hook(h2), nil return Hook(h2), nil
} }
func (u *uc) HookDel(hook Hook) error { func (u *uc) HookDel(hook Hook) error {
if uptr, ok := hookToUintptr[hook]; ok { if uptr, ok := u.hooks[hook]; ok {
delete(hookToUintptr, hook) delete(u.hooks, hook)
delete(hookDataMap, uptr) delete(hookDataMap, uptr)
} }
return errReturn(C.uc_hook_del(u.handle, C.uc_hook(hook))) return errReturn(C.uc_hook_del(u.handle, C.uc_hook(hook)))

View file

@ -60,6 +60,7 @@ type Unicorn interface {
type uc struct { type uc struct {
handle *C.uc_engine handle *C.uc_engine
final sync.Once final sync.Once
hooks map[Hook]uintptr
} }
type UcOptions struct { 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 { if ucerr := C.uc_open(C.uc_arch(arch), C.uc_mode(mode), &handle); ucerr != ERR_OK {
return nil, UcError(ucerr) 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() }) runtime.SetFinalizer(u, func(u *uc) { u.Close() })
return u, nil return u, nil
} }
@ -89,6 +90,10 @@ func NewUnicorn(arch, mode int) (Unicorn, error) {
func (u *uc) Close() (err error) { func (u *uc) Close() (err error) {
u.final.Do(func() { u.final.Do(func() {
if u.handle != nil { if u.handle != nil {
for _, uptr := range u.hooks {
delete(hookDataMap, uptr)
}
u.hooks = nil
err = errReturn(C.uc_close(u.handle)) err = errReturn(C.uc_close(u.handle))
u.handle = nil u.handle = nil
} }