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 safely printf buf with %s.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top