* Apply patch from @w_levin fixing lot of memory leaks - Thanks!

This commit is contained in:
pancake 2011-12-16 16:33:06 +01:00
parent 16cf2367b9
commit 997a6dbd14
24 changed files with 107 additions and 27 deletions

View File

@ -1,5 +1,5 @@
NAME=r_anal
DEPS=r_util r_lib r_reg r_syscall r_diff
DEPS=r_util r_lib r_reg r_syscall r_diff # r_core (commented as it would be recursive)
CFLAGS+=-DCORELIB -Iarch
include ../config.mk

View File

@ -4,6 +4,7 @@
#include <r_anal.h>
#include <r_util.h>
#include <r_list.h>
#include <r_io.h>
#include "../config.h"
static RAnalPlugin *anal_static_plugins[] =
@ -57,9 +58,16 @@ R_API RAnal *r_anal_new() {
R_API void r_anal_free(RAnal *anal) {
if (!anal) return;
/* TODO: Free anals here */
r_listrange_free (anal->fcnstore);
anal->fcns->free = r_anal_fcn_free;
r_list_free (anal->fcns);
// r_listrange_free (anal->fcnstore); // might provoke double frees since this is used in r_anal_fcn_insert()
r_list_free (anal->refs);
r_list_free (anal->vartypes);
r_list_free (anal->meta->data);
r_reg_free(anal->reg);
r_syscall_free(anal->syscall);
r_anal_op_free(anal->queued);
// r_io_free(anal->iob.io); // need r_core (but recursive problem to fix)
free (anal);
}

View File

@ -53,7 +53,6 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
bb->addr = addr;
len -= 16; // XXX: hack to avoid segfault by x86im
while (idx < len) {
r_anal_op_free (op);
if (!(op = r_anal_op_new ())) {
eprintf ("Error: new (op)\n");
return R_ANAL_RET_ERROR;
@ -77,6 +76,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
bb->type = R_ANAL_BB_TYPE_HEAD;
switch (op->type) {
case R_ANAL_OP_TYPE_CMP:
r_anal_cond_free(bb->cond);
bb->cond = r_anal_cond_new_from_op (op);
break;
case R_ANAL_OP_TYPE_CJMP:
@ -100,6 +100,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
bb->type |= R_ANAL_BB_TYPE_LAST;
goto beach;
}
r_anal_op_free (op);
}
return bb->size;
beach:

View File

@ -143,6 +143,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
return fcn->size;
}
// TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFcn *fcn);
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFcn *fcn) {
#if USE_NEW_FCN_STORE
r_listrange_add (anal->fcnstore, fcn);

View File

@ -5,6 +5,7 @@
// TODO: We need a standard struct named Surface1D {.addr, .size}, so we can
// simplify all this by just passing the offset of the field of the given ptr
// TODO: RListComparator does not supports *user
// TODO: RRef - reference counting
#define RANGEBITS 10
// 1024
@ -39,8 +40,9 @@ static inline ut64 r_listrange_next(ut64 addr) {
}
R_API void r_listrange_free(RListRange *s) {
if (!s) return;
r_hashtable64_free (s->h);
r_list_destroy (s->l);
r_list_free (s->l);
free (s);
}

View File

@ -22,6 +22,7 @@ R_API RAnalValue *r_anal_value_copy (RAnalValue *ov) {
// TODO: move into .h as #define free
R_API void r_anal_value_free(RAnalValue *value) {
/* TODO: free RRegItem objects? */
free (value);
}

View File

@ -134,6 +134,7 @@ R_API RAsm *r_asm_new() {
a->ofilter = NULL;
a->syntax = R_ASM_SYNTAX_INTEL;
a->plugins = r_list_new ();
a->plugins->free = free;
for (i=0; asm_static_plugins[i]; i++) {
static_plugin = R_NEW (RAsmPlugin);
memcpy (static_plugin, asm_static_plugins[i], sizeof (RAsmPlugin));
@ -175,6 +176,7 @@ R_API int r_asm_filter_output(RAsm *a, const char *f) {
}
R_API void r_asm_free(RAsm *a) {
if (!a) return;
// TODO: any memory leak here?
r_pair_free (a->pair);
r_list_free (a->plugins);

View File

@ -148,6 +148,7 @@ static void r_bin_free_items(RBin *bin) {
if (a->sections) r_list_free (a->sections);
if (a->strings) r_list_free (a->strings);
if (a->symbols) r_list_free (a->symbols);
if (a->classes) r_list_free (a->classes);
if (a->binsym)
for (i=0; i<R_BIN_SYM_LAST; i++)
free (a->binsym[i]);
@ -226,6 +227,9 @@ R_API void* r_bin_free(RBin *bin) {
r_bin_free_items (bin);
if (bin->curxtr && bin->curxtr->destroy)
bin->curxtr->destroy (bin);
r_list_free(bin->binxtrs);
r_list_free(bin->plugins);
free(bin->file);
free (bin);
return NULL;
}
@ -353,12 +357,14 @@ R_API RBin* r_bin_new() {
if (bin) {
memset (bin, 0, sizeof (RBin));
bin->plugins = r_list_new();
bin->plugins->free = free;
for (i=0; bin_static_plugins[i]; i++) {
static_plugin = R_NEW (RBinPlugin);
memcpy (static_plugin, bin_static_plugins[i], sizeof (RBinPlugin));
r_bin_add (bin, static_plugin);
}
bin->binxtrs = r_list_new();
bin->binxtrs->free = free;
for (i=0; bin_xtr_static_plugins[i]; i++) {
static_xtr_plugin = R_NEW (RBinXtrPlugin);
memcpy (static_xtr_plugin, bin_xtr_static_plugins[i], sizeof (RBinXtrPlugin));
@ -384,7 +390,6 @@ R_API int r_bin_use_arch(RBin *bin, const char *arch, int bits, const char *name
r_list_foreach(bin->plugins, it, plugin) {
if (!strcmp (name, plugin->name)) {
bin->curarch.curplugin = plugin;
// TODO: set bits and name
return R_TRUE;
}
}

View File

@ -19,6 +19,8 @@ R_API RCmd *r_cmd_new () {
}
R_API RCmd *r_cmd_free(RCmd *cmd) {
if (!cmd) return NULL;
r_list_free(cmd->plist);
free (cmd);
return NULL;
}

View File

@ -297,7 +297,7 @@ R_API RConfig *r_config_new(void *user) {
}
R_API int r_config_free(RConfig *cfg) {
// XXX: memory leak ! r_list_destroy (cfg->nodes);
if (!cfg) return 0;
r_list_free (cfg->nodes);
r_hashtable_free (cfg->ht);
free (cfg);

View File

@ -111,7 +111,7 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
struct r_anal_bb_t *bb = NULL, *bbi;
RListIter *iter;
ut64 jump, fail;
ut8 *buf;
ut8 *buf = NULL;
int ret = R_ANAL_RET_NEW, buflen, bblen = 0;
int split = core->anal->split;
@ -123,21 +123,17 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
ret = R_ANAL_RET_DUP;
}
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
r_anal_bb_free (bb);
return R_FALSE;
goto error;
} else if (ret == R_ANAL_RET_NEW) { /* New bb */
if (!(buf = malloc (core->blocksize)))
return R_FALSE;
goto error;
do {
if ((buflen = r_io_read_at (core->io, at+bblen, buf, core->blocksize)) != core->blocksize) {
r_anal_bb_free (bb);
return R_FALSE;
}
if ((buflen = r_io_read_at (core->io, at+bblen, buf, core->blocksize)) != core->blocksize)
goto error;
bblen = r_anal_bb (core->anal, bb, at+bblen, buf, buflen, head);
if (bblen == R_ANAL_RET_ERROR ||
(bblen == R_ANAL_RET_END && bb->size < 1)) { /* Error analyzing bb */
r_anal_bb_free (bb);
return R_FALSE;
goto error;
} else if (bblen == R_ANAL_RET_END) { /* bb analysis complete */
if (split)
ret = r_anal_fcn_overlap_bb (fcn, bb);
@ -152,9 +148,16 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
}
}
} while (bblen != R_ANAL_RET_END);
free (buf);
}
free(buf);
return R_TRUE;
error:
r_list_unlink(fcn->bbs, bb);
r_anal_bb_free(bb);
free(buf);
return R_FALSE;
}
R_API int r_core_anal_bb_seek(RCore *core, ut64 addr) {
@ -176,8 +179,8 @@ static int cmpaddr (void *_a, void *_b) {
R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth) {
RListIter *iter, *iter2;
int buflen, fcnlen = 0;
RAnalFcn *fcn, *fcni;
RAnalRef *ref, *refi;
RAnalFcn *fcn = NULL, *fcni;
RAnalRef *ref = NULL, *refi;
ut8 *buf;
if (depth < 0)
@ -206,17 +209,16 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
}
if (!(buf = malloc (core->blocksize))) {
eprintf ("Error: malloc (buf)\n");
return R_FALSE;
goto error;
}
do {
if ((buflen = r_io_read_at (core->io, at+fcnlen, buf, core->blocksize)) != core->blocksize)
return R_FALSE;
goto error;
fcnlen = r_anal_fcn (core->anal, fcn, at+fcnlen, buf, buflen, reftype);
if (fcnlen == R_ANAL_RET_ERROR ||
(fcnlen == R_ANAL_RET_END && fcn->size < 1)) { /* Error analyzing function */
r_anal_fcn_free (fcn);
return R_FALSE;
goto error;
} else if (fcnlen == R_ANAL_RET_END) { /* Function analysis complete */
RFlagItem *f = r_flag_get_i (core->flags, at);
if (f) { /* Check if it's already flagged */
@ -237,7 +239,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
if (from != -1) {
if (!(ref = r_anal_ref_new ())) {
eprintf ("Error: new (xref)\n");
return R_FALSE;
goto error;
}
ref->addr = from;
ref->at = at;
@ -249,11 +251,24 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
//r_list_append (core->anal->fcns, fcn);
r_list_foreach (fcn->refs, iter, refi)
if (refi->addr != -1)
// TODO: fix memleak here, fcn not freed even though it is
// added in core->anal->fcns which is freed in r_anal_free()
r_core_anal_fcn (core, refi->addr, refi->at, refi->type, depth-1);
}
} while (fcnlen != R_ANAL_RET_END);
free (buf);
return R_TRUE;
error:
free(buf);
// ugly hack to free fcn
if (fcn) {
// unlink from list to avoid double free later when we call r_anal_free()
r_list_unlink(core->anal->fcns, fcn);
if (core->anal->fcns->free == NULL)
r_anal_fcn_free (fcn);
}
return R_FALSE;
}
R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr) {

View File

@ -396,7 +396,25 @@ R_API int r_core_init(RCore *core) {
}
R_API RCore *r_core_free(RCore *c) {
if (!c) return NULL;
/* TODO: it leaks as shit */
r_io_free(c->io);
r_core_file_free(c->file);
r_list_free(c->files);
free(c->num);
r_lib_free(c->lib);
r_cmd_free(c->cmd);
r_anal_free(c->anal);
r_asm_free(c->assembler);
r_print_free(c->print);
r_bin_free(c->bin);
r_lang_free(c->lang);
r_debug_free(c->dbg);
r_flag_free(c->flags);
r_config_free(c->config);
r_search_free(c->search);
r_sign_free(c->sign);
r_fs_free(c->fs);
r_egg_free (c->egg);
free (c);
return NULL;

View File

@ -189,10 +189,14 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loa
}
R_API void r_core_file_free(RCoreFile *cf) {
if (!cf) return;
free (cf->uri);
cf->uri = NULL;
free (cf->filename);
cf->filename = NULL;
free(cf->map);
r_io_desc_free(cf->fd);
cf->fd = NULL;
}

View File

@ -58,6 +58,7 @@ R_API RDebug *r_debug_new(int hard) {
}
R_API struct r_debug_t *r_debug_free(struct r_debug_t *dbg) {
if (!dbg) return NULL;
// TODO: free it correctly.. we must ensure this is an instance and not a reference..
//r_bp_free(&dbg->bp);
//r_reg_free(&dbg->reg);

View File

@ -54,11 +54,15 @@ R_API char *r_egg_to_string (REgg *egg) {
}
R_API void r_egg_free (REgg *egg) {
if (!egg) return;
r_buf_free (egg->src);
r_buf_free (egg->buf);
r_buf_free (egg->bin);
r_list_free(egg->list);
r_asm_free (egg->rasm);
r_syscall_free (egg->syscall);
r_pair_free(egg->pair);
r_list_free (egg->plugins);
r_list_free (egg->patches);
free (egg);
}

View File

@ -60,6 +60,7 @@ R_API int r_flag_sort(RFlag *f, int namesort) {
}
R_API RFlag * r_flag_free(RFlag *f) {
if (!f) return NULL;
r_list_free (f->flags);
free (f);
return NULL;

View File

@ -17,6 +17,7 @@ R_API RFS *r_fs_new () {
fs->roots = r_list_new ();
fs->roots->free = (RListFree)r_fs_root_free;
fs->plugins = r_list_new ();
fs->plugins->free = free;
// XXX fs->roots->free = r_fs_plugin_free;
for (i=0; fs_static_plugins[i]; i++) {
static_plugin = R_NEW (RFSPlugin);
@ -38,6 +39,8 @@ R_API RFSPlugin *r_fs_plugin_get (RFS *fs, const char *name) {
}
R_API void r_fs_free (RFS* fs) {
if (!fs) return;
r_io_free(fs->iob.io);
r_list_free (fs->plugins);
r_list_free (fs->roots);
free (fs);

View File

@ -48,7 +48,13 @@ R_API int r_io_write_buf(struct r_io_t *io, struct r_buf_t *b) {
}
R_API struct r_io_t *r_io_free(struct r_io_t *io) {
if (!io) return NULL;
/* TODO: properly free inner nfo */
/* TODO: memory leaks */
r_io_desc_free(io->desc);
r_list_free(io->sections);
r_list_free(io->maps);
r_list_free(io->desc);
free (io);
return NULL;
}

View File

@ -19,6 +19,7 @@ R_API RLang *r_lang_new() {
}
R_API void *r_lang_free(RLang *lang) {
if (!lang) return NULL;
r_lang_undef (lang, NULL);
r_list_free (lang->langs);
r_list_free (lang->defs);

View File

@ -105,6 +105,7 @@ R_API RLib *r_lib_new(const char *symname) {
}
R_API RLib *r_lib_free(RLib *lib) {
if (!lib) return;
/* TODO: iterate over libraries and free them all */
/* TODO: iterate over handlers and free them all */
r_lib_close (lib, NULL);

View File

@ -27,6 +27,7 @@ R_API RPrint *r_print_new() {
}
R_API RPrint *r_print_free(RPrint *p) {
if (!p) return NULL;
if (p->zoom) {
free (p->zoom->buf);
free (p->zoom);

View File

@ -29,10 +29,12 @@ R_API RSearch *r_search_new(int mode) {
}
R_API RSearch *r_search_free(RSearch *s) {
if (!s) return NULL;
// TODO: it leaks
r_mem_pool_free (s->pool);
r_list_destroy (s->hits);
r_list_destroy (s->kws);
r_list_free (s->hits);
r_list_free (s->kws);
r_io_free(s->iob.io);
free (s);
return NULL;
}

View File

@ -114,6 +114,7 @@ R_API void r_sign_reset(RSign *sig) {
}
R_API RSign *r_sign_free(RSign *sig) {
if (!sig) return NULL;
r_list_free (sig->items);
free (sig);
return NULL;

View File

@ -1,4 +1,5 @@
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
// TODO: RRef - reference counting
#include "r_util.h"
@ -122,7 +123,6 @@ R_API void r_list_destroy (RList *list) {
R_API void r_list_free (RList *list) {
if (list) {
list->free = NULL;
r_list_destroy (list);
free (list);
}