Workaround doublefrees until we get refcounting in Sdb

This commit is contained in:
pancake 2014-04-01 04:03:48 +02:00
parent 494e329d92
commit 5c32779d52
8 changed files with 64 additions and 34 deletions

View File

@ -111,9 +111,13 @@ R_API void r_anal_free(RAnal *a) {
r_list_free (a->refs);
r_list_free (a->types);
r_reg_free(a->reg);
r_syscall_free (a->syscall);
r_anal_op_free (a->queued);
a->sdb = NULL;
// DBLFREEd coz freed from core.. this must be fixed somehow..
// sdb_ns api should support refcounting, pointer invalidation or
#if 0
//r_syscall_free (a->syscall);
sdb_free (a->sdb_meta);
sdb_free (a->sdb_vars);
sdb_free (a->sdb_xrefs);
@ -123,6 +127,7 @@ R_API void r_anal_free(RAnal *a) {
//sdb_free (a->sdb_locals);
sdb_free (a->sdb_types);
sdb_free (a->sdb);
#endif
// r_io_free(anal->iob.io); // need r_core (but recursive problem to fix)
free (a);
}

View File

@ -467,6 +467,7 @@ static int __disasm(void *_core, ut64 addr) {
}
static void update_sdb(RCore *core) {
// TODO: Use refcounting for Sdb! to avoid dblfrees and so
// TODO: sdb_hook should work across namespaces?
// HOOK!
sdb_ns_set (core->sdb, "anal", core->anal->sdb);
@ -606,6 +607,7 @@ R_API int r_core_init(RCore *core) {
R_API RCore *r_core_fini(RCore *c) {
if (!c) return NULL;
/* TODO: it leaks as shit */
update_sdb (c);
r_io_free (c->io);
// TODO: sync or not? sdb_sync (c->sdb);
// TODO: sync all dbs?

View File

@ -27,6 +27,7 @@ R_API RSyscall* r_syscall_new() {
R_API void r_syscall_free(RSyscall *s) {
sdb_free (s->db);
memset (s, 0, sizeof (RSyscall));
free (s);
}

View File

@ -92,6 +92,7 @@ int cdb_findnext(struct cdb *c, ut32 u, const char *key, unsigned int len) {
ut32 pos;
int m;
c->hslots = 0;
if (!c->loop) {
if (!cdb_read (c, buf, 8, (u << 3) & 2047))
return -1;

View File

@ -93,19 +93,21 @@ static const struct {
* modified by the user.
*/
SdbHashEntry* ht_search(SdbHash *ht, ut32 hash) {
ut32 double_hash, hash_address = hash % ht->size;
if (ht && ht->entries)
do {
SdbHashEntry *entry = ht->table + hash_address;
if (entry_is_free (entry))
return NULL;
if (entry_is_present (entry) && entry->hash == hash)
return entry;
double_hash = hash % ht->rehash;
if (double_hash == 0)
double_hash = 1;
hash_address = (hash_address + double_hash) % ht->size;
} while (hash_address != hash % ht->size);
ut32 double_hash, hash_address;
if (ht && ht->entries) {
hash_address = hash % ht->size;
do {
SdbHashEntry *entry = ht->table + hash_address;
if (entry_is_free (entry))
return NULL;
if (entry_is_present (entry) && entry->hash == hash)
return entry;
double_hash = hash % ht->rehash;
if (double_hash == 0)
double_hash = 1;
hash_address = (hash_address + double_hash) % ht->size;
} while (hash_address != hash % ht->size);
}
return NULL;
}

View File

@ -186,9 +186,12 @@ SDB_API const char *sdb_json_format(SdbJsonString* s, const char *fmt, ...) {
if (!x) return NULL;\
s->buf = x;\
}
if (!s) return NULL;
if (!s->buf) {
s->blen = 1024;
s->buf = malloc (s->blen);
if (!s->buf)
return NULL;
*s->buf = 0;
}
if (!fmt || !*fmt) return s->buf;

View File

@ -97,23 +97,26 @@ SDB_API char *sdb_querys (Sdb *r, char *buf, size_t len, const char *cmd) {
Sdb *s = r;
ut64 n;
if (!s) return NULL;
if (!len || !buf) {
bufset = 1;
buf = malloc ((len=64));
}
if (cmd == NULL) {
if (!buf)
return NULL;
cmd = buf;
buf = NULL;
} else {
if (len<1 || !buf) {
bufset = 1;
buf = malloc ((len=64));
}
}
// if cmd is null, we take buf as cmd
next = NULL;
repeat:
s = r;
p = cmd;
eq = NULL;
quot = NULL;
json = NULL;
encode = 0;
is_ref = 0;
p = cmd;
quot = NULL;
json = NULL;
if (next) *next = ';';
if (*p=='%') {
encode = 1;
@ -286,11 +289,16 @@ next_quote:
if (cmd[1]=='?') {
// if (!eq) ...
alength = sdb_array_length (s, p);
if (!buf) {
buf = malloc (len+1);
bufset = 1;
}
w = snprintf (buf, len, "%d", alength);
if (w<0 || (size_t)w>len) {
buf = malloc (32);
snprintf (buf, 31, "%d", alength);
free (buf);
buf = malloc (64);
bufset = 1;
snprintf (buf, 63, "%d", alength);
}
out_concat (buf);
} else

View File

@ -38,14 +38,16 @@ SDB_API Sdb* sdb_new (const char *path, const char *name, int lock) {
} else s->dir = strdup (name);
if (lock && !sdb_lock (sdb_lockfile (s->dir)))
goto fail;
if (stat (s->dir, &st)!=-1)
if ((S_IFREG & st.st_mode)!=S_IFREG)
goto fail;
s->fd = open (s->dir, O_RDONLY|O_BINARY);
// if (s->fd == -1) // must fail if we cant open for write in sync
if (s->fd != -1)
if (s->fd != -1) {
if (fstat (s->fd, &st) != -1)
if ((S_IFREG & st.st_mode)!=S_IFREG)
goto fail;
s->last = st.st_mtime;
else s->last = sdb_now ();
} else {
s->last = sdb_now ();
// TODO: must fail if we cant open for write in sync
}
s->name = strdup (name);
s->path = path? strdup (path): NULL;
} else {
@ -189,7 +191,7 @@ SDB_API char *sdb_get (Sdb* s, const char *key, /*OUT*/ut32 *cas) {
cdb_findstart (&s->db);
if (!cdb_findnext (&s->db, hash, key, keylen))
return NULL;
if (!(len = cdb_datalen (&s->db)))
if ((len = cdb_datalen (&s->db))<1)
return NULL;
if (!(buf = malloc (len+1))) // XXX too many mallocs
return NULL;
@ -450,6 +452,13 @@ SDB_API int sdb_dump_dupnext (Sdb* s, char **key, char **value) {
*value = 0;
if (vlen>0) {
*value = malloc (vlen+10);
if (!*value) {
if (key) {
free (*key);
*key = NULL;
}
return 0;
}
if (getbytes (s, *value, vlen)==-1) {
if (key) {
free (*key);
@ -462,7 +471,7 @@ SDB_API int sdb_dump_dupnext (Sdb* s, char **key, char **value) {
(*value)[vlen] = 0;
}
}
s->pos += 4; // XXX no
s->pos += 4; // XXX no.
return 1;
}
@ -496,9 +505,8 @@ SDB_API int sdb_expire_set(Sdb* s, const char *key, ut64 expire) {
return 0;
pos = cdb_datapos (&s->db);
len = cdb_datalen (&s->db);
if (len == UT32_MAX || !len) {
if (len <1 || len == UT32_MAX)
return 0;
}
if (!(buf = malloc (len+1)))
return 0;
cdb_read (&s->db, buf, len, pos);