ctokyo-cabinet

Tokyo Cabinet gives segmentation fault in tcbdb.h on *sp = rec->vsiz;


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);.


Solution

  • 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.