0

永続ストレージ データベースの作成に Tokyo Cabinet を使用しています。

私が使用しvoid *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp); ている tcbdb.h ファイルで segfault が発生します*sp = rec->vsiz;

Tokyo Cabinetにバグがありますか、それとも何か不足していますか?

レコードの挿入は正常に機能するため、すべての void ポインターが完全に挿入されているため、ルックアップだけで問題が発生します。挿入機能はこれbool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);です。

4

1 に答える 1

0

tcbdb.h ファイルで segfault が発生します。*sp = rec->vsiz;

Tokyo Cabinet (別名 TC) は、 を呼び出すときに値のサイズを格納するために、有効な非 NULL ポインタを渡すことを期待していますtcbdbget。たとえば、次のようになります。

int size;
char *buf = tcbdbget(bdb, kbuf, ksiz, &size);

NULL ポインターを渡すと、この正確なコード セクションでセグメンテーション違反が説明される可能性があります。BUG = 1segfault を生成するためにビルドできるサンプル コードを以下に示します。BUG = 0すべてが魅力的に機能します :)

#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;
}

注: TC は常に末尾の terminator を追加するため\0、文字列を保存したことを知っているので、安全に使用できprintf bufます%s

于 2013-10-31T09:24:12.637 に答える