2012-05-01 6 views
0

간단한 프로그램에서 BDB를 사용하려하지만 segfault 문제가 발생합니다.Berkeley DB segfault - __bamc_put 매개 변수의 정렬이 잘못 되었습니까?

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 사라지고 프로그램은 Valgrind의에서 경고없이 정상적으로 완료됩니다.

gdb에 따라 __bamc_put이 키 매개 변수로 NULL 포인터를 전달하는 방법에 유의하십시오. 이것은 segfault를 야기한 분명한 범인처럼 보입니다. 하지만 여기에 DB-> put에 대한 두 번째 매개 변수가 실제로 트랜잭션이라고 가정되거나 비 트랜잭션 삽입의 경우 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

이 서명입니다

여기 내 코드입니다. 내가 GDB가 표시되는지합니다 (DB_TXN 매개 변수를 생략) 서명을 사용하는 컴파일러의 설명서에 따라 올바른 서명을 사용하기 때문에 난 그냥 컴파일러 경고를 취득하려고하면

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를 참조하십시오.

그래서 내가 잘못된 라이브러리와 연결하고 있다고 생각 했습니까? 그러나 :

$ 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을 사용하고 헤더와 라이브러리 모두 우분투 패키지에서 원본 파일입니다. 처음에는 우분투 11.10에서 문제가 발생했고 우분투 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가 어떤 이유로 든 잘못된 서명을 표시하고 있지만 문제는 다른 곳에 있습니까?

업데이트 :

그것은처럼 보이는 -> 넣어 포인터가 잘못된 것입니다. __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> 

답변

1

시간에 의해 당신이 __bamc_put (또는 __hamc_put)에 도착하기 때문에 "실종"매개 변수이며, 트랜잭션이 dbc로 이동되었습니다 매개 변수. (이것은 "DB 커서"입니다.) 내가 실제로 얻지 못하는 이유는 __bamc_put 위에 프레임이 없기 때문입니다. 다른 레이어 (실제로는 2 : __db_put_pp__db_put)를 통해 호출 되었기 때문입니다.

특히 valgrind와 함께 작동하고 그것없이 실패하면 이상합니다.

+0

고마워요! 이것은 올바른 방향으로 나를 가리켰다. 문제는 데이터베이스를 여는 방식과 관련이 있다는 것이 밝혀졌습니다. [4d5ac14]에서 수정 됨 (https://github.com/justmoon/bzing/commit/4d5ac14c6f0331a60404634a798bd127f7f113be) – justmoon