I am using Tokyo Cabinet for creating persistent storage database.
I am using void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp);
It gives segfault in tcbdb.h file on *sp = rec->vsiz;
.
Is there a bug in Tokyo Cabinet or am I missing something?
Because inserting the record works fine that means all the void pointers are perfectly getting inserted, just lookup has problem.
The insert function is this bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
.
It gives segfault in tcbdb.h file on
*sp = rec->vsiz;
Tokyo Cabinet (a.k.a TC) expects you pass a valid, non NULL pointer to store the size of the value when you call tcbdbget
, e.g:
int size;
char *buf = tcbdbget(bdb, kbuf, ksiz, &size);
Passing a NULL pointer could explain the segfault at this precise code section. Please find below a sample code that you can build with BUG = 1
to generate a segfault - with BUG = 0
everything works like a charm :)
#include <stdio.h>
#include <string.h>
#include <tcbdb.h>
#define BUG 0
int
main(void)
{
TCBDB *bdb = tcbdbnew();
if (!tcbdbopen(bdb, "store.db", BDBOWRITER | BDBOCREAT)) {
fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
}
char *key = "foo";
char *val = "bar";
if (!tcbdbput(bdb, key, strlen(key), val, strlen(val))) {
fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
}
int size;
#if BUG
char *buf = tcbdbget(bdb, key, strlen(key), NULL);
#else
char *buf = tcbdbget(bdb, key, strlen(key), &size);
#endif
if (!buf && tcbdbecode(bdb) != TCENOREC) {
fprintf(stderr, "error: %s\n", tcbdberrmsg(tcbdbecode(bdb)));
}
if (buf)
printf("%s -> %s\n", key, buf);
free(buf);
tcbdbdel(bdb);
return 0;
}
Note: since TC always append a trailing terminator
\0
, and since I know I've stored a character string I can safelyprintf
buf
with%s
.