単純なプログラムで BDB を使用しようとしていますが、segfault の問題が発生しています。
Program received signal SIGSEGV, Segmentation fault.
__bamc_put (dbc=0x60e7f0, key=0x0, data=0x60b240, flags=6337152, pgnop=0x0)
at ../src/btree/bt_cursor.c:2077
2077 ../src/btree/bt_cursor.c: No such file or directory.
gdb バックトレース:
#0 __bamc_put (dbc=0x60e7f0, key=0x0, data=0x60b240, flags=6337152, pgnop=0x0)
at ../src/btree/bt_cursor.c:2077
#1 0x0000000000404152 in bzing_inv_add (hnd=0x60c010, hash=..., data=80)
at /atlas/www/libbzing/src/bzing.c:189
#2 0x00000000004041fa in bzing_block_add (hnd=0x60c010,
data=0x7fffb0d7d000 "\001", max_len=1163428803, actual_len=0x7fffffffe458)
at /atlas/www/libbzing/src/bzing.c:217
#3 0x00000000004044d4 in bzing_index_regen (hnd=0x60c010,
data=0x7fffb0d7d000 "\001", len=1163428803)
at /atlas/www/libbzing/src/bzing.c:269
#4 0x000000000040301c in main (argc=1, argv=0x7fffffffe628)
at /atlas/www/libbzing/test/bzing_test.c:75
valgrind memcheck で実行すると、segfault がなくなり、プログラムは valgrind からの警告なしで正常に完了します。
gdb によると、__bamc_put にキー パラメータとして NULL ポインタが渡されることに注意してください。これは、セグメンテーション違反を引き起こす明らかな原因のようです。DB->put の 2 番目のパラメーターは、実際にはトランザクションまたは非トランザクション挿入の NULL であると想定されています。
これが私のコードです:
DBT bdb_key, bdb_data;
memset(&bdb_key, 0, sizeof(DBT));
memset(&bdb_data, 0, sizeof(DBT));
bdb_key.data = hash.d8;
bdb_key.size = 32;
bdb_data.data = (char *) &data;
bdb_data.size = 8;
result = hnd->bdb_inv->put(hnd->bdb_inv, NULL, &bdb_key, &bdb_data, 0);
から: https://github.com/justmoon/bzing/blob/master/src/bzing.c
これは、ドキュメントと私が見つけたすべての例に表示されている署名です。
DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags);
http://docs.oracle.com/cd/E17076_02/html/api_reference/C/dbput.htmlを参照してください。
gdb が示す署名 (DB_TXN パラメーターを省略) を使用しようとすると、コンパイラーはドキュメントに従って正しい署名を使用するため、コンパイラーの警告が表示されます。
それで、間違ったライブラリにリンクしているのではないかと思いましたか?しかし:
$ ldd build/test/bzing_test | grep libdb
libdb-5.1.so => /usr/lib/x86_64-linux-gnu/libdb-5.1.so (0x00007f28dd7ec000)
$ dpkg -L libdb5.1-dev
/.
/usr
/usr/share
/usr/share/doc
/usr/include
/usr/include/db.h
/usr/include/db_185.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libdb-5.1.a
/usr/share/doc/libdb5.1-dev
/usr/lib/x86_64-linux-gnu/libdb.a
/usr/lib/x86_64-linux-gnu/libdb.so
$ dpkg -L libdb5.1
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libdb5.1
/usr/share/doc/libdb5.1/build_signature_amd64.txt
/usr/share/doc/libdb5.1/copyright
/usr/share/doc/libdb5.1/changelog.Debian.gz
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libdb5.1
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libdb-5.1.so
コンパイラは間違いなく使用/usr/include/db.h
しており、ヘッダーとライブラリの両方が Ubuntu パッケージの元のファイルです。Ubuntu 11.10 で最初に問題に遭遇し、Ubuntu 12.04 にアップグレードした後も問題は解決しませんでした。
私はCMakeとこれらのフラグでコンパイルしています:
cd /atlas/www/libbzing/build/src && /usr/bin/gcc -DBZING_BUILD -Wall -fvisibility=hidden -std=c99 -pedantic -DDEBUG -g -I/atlas/www/libbzing/build/src/../bzing-0.1.0/include/bzing/.. -o CMakeFiles/bzing_s.dir/bzing.c.o -c /atlas/www/libbzing/src/bzing.c
...
/usr/bin/ar cr ../bzing-0.1.0/lib/libbzing_s.a CMakeFiles/bzing_s.dir/bzing.c.o CMakeFiles/bzing_s.dir/bzing_parser.c.o CMakeFiles/bzing_s.dir/util.c.o
/usr/bin/ranlib ../bzing-0.1.0/lib/libbzing_s.a
...
/usr/bin/gcc -Wall -fvisibility=hidden -std=c99 -pedantic -DDEBUG -g CMakeFiles/bzing_test.dir/bzing_test.c.o -o bzing_test -rdynamic -L/atlas/www/libbzing/build/test/../bzing-0.1.0/lib ../bzing-0.1.0/lib/libbzing_s.a -llmc -lpthread -lrt -lcrypto -ltokyocabinet -ldb -Wl,-rpath,/atlas/www/libbzing/build/test/../bzing-0.1.0/lib
同じプログラムを実行してハッシュ テーブル データベース タイプを選択すると、代わりに __hamc_put で同じ問題が発生します。
Program received signal SIGSEGV, Segmentation fault.
__hamc_put (dbc=0x60e7f0, key=0x0, data=0x60b240, flags=6337152, pgnop=0x0)
at ../src/hash/hash.c:1068
を試してみ-fPIC
ましたが、同じ結果になりました。
どんな助けでも大歓迎です。たぶん私は間違った方向に進んでいて、何らかの理由で gdb が間違った署名を表示しているだけですが、問題は別の場所にありますか?
アップデート:
->put ポインタが間違っているようです。__db_put_pp を指す必要があります。
dbp->put = __db_put_pp;
(db_method.c 行 248)
ただし、代わりに__bamc_put
/を指します。__hamc_put
Breakpoint 3, bzing_inv_add (hnd=0x60c010, hash=..., data=80)
at /atlas/www/libbzing/src/bzing.c:189
189 result = hnd->bdb_inv->put(hnd->bdb_inv, NULL, &bdb_key, &bdb_data, 0);
(gdb) print hnd->bdb_inv->put
$1 = (int (*)(DB *, DB_TXN *, DBT *, DBT *,
u_int32_t)) 0x7ffff7034d00 <__hamc_put>