前提
HH-suiteという、タンパク質配列のデータベースを検索するプログラムをインストールしたのですが、
いざ検索を実行しようとするとsegmentation faultで停止してしまいます。
自分なりに原因を解明しようとしたところ、
どうやらfgetsやfgetcでデータベースのファイルの内容を読み取ろうとするとsegmentation faultしているみたいなのです。
ただ、自分はプログラミング初心者で、そのsegmentation faultが何を原因に起こっているかが理解できません。
fgetsやfgetcでsegmentation faultが起こる要因として何が考えられるでしょうか。
あと、重要な点として
サイズが小さいデータベース(全体で50GB)だとsegmentation faultが起こらず正常に作動するのです。
80GBぐらいのサイズが大きいデータベースに検索をかけようとするとsegmentation faultが起こります。
なので、巨大なファイルに対してfgetcをしたことが要因でsegmentation faultになっていると思うのですが……。
発生している問題・エラーメッセージ
- 16:46:58.159 INFO: Search results will be written to seq.fasta - 16:47:03.370 INFO: Searching 15161831 column state sequences. - 16:47:03.430 INFO: seq.fasta is in A2M, A3M or FASTA format - 16:47:03.431 INFO: Iteration 1 - 16:47:03.593 INFO: Prefiltering database - 16:49:45.411 INFO: HMMs passed 1st prefilter (gapless profile-profile alignment) : 314026 - 16:49:48.220 INFO: HMMs passed 2nd prefilter (gapped profile-profile alignment) : 2066 - 16:49:48.221 INFO: HMMs passed 2nd prefilter and not found in previous iterations : 2066 - 16:49:48.221 INFO: Scoring 2066 HMMs using HMM-HMM Viterbi alignment - 16:49:48.284 INFO: Alternative alignment: 0 Segmentation fault (core dumped)
該当のソースコード
プログラムが膨大すぎて貼ることができませんが、segmentation faultを起こすfgetsはここにあります。
C++
1// Emulates the ifstream::getline method; similar to fgets(str,maxlen,FILE*), 2// but removes the newline at the end and returns NULL if at end of file or read error 3inline char* fgetline(char str[], const int maxlen, FILE* file) { 4 if (!fgets(str, maxlen, file)) 5 return NULL; 6 if (chomp(str) + 1 >= maxlen) // if line is cut after maxlen characters... 7 while (fgetc(file) != '\n') 8 ; // ... read in rest of line 9 10 return (str); 11}
関数を呼び出している側はこうなってます。
C++
1char line[LINELEN]; 2if (!fgetline(line, LINELEN, dbf)) { 3 //TODO: throw error 4 HH_LOG(ERROR) << "In " << __FILE__ << ":" << __LINE__ << ": " << __func__ << ":" << std::endl; 5 HH_LOG(ERROR) << "\tThis should not happen!" << std::endl; 6}
ここでsegmentation faultする前に、 fgetc(dbf)と書いてみたところ、その段階でsegmentation faultしたのでdbf(FILE型)が問題になってます。
問題のdbfがどうやって得られたかは、あまりにもソースコードが膨大すぎてさっぱりわかりません。データベースから得られたのは明らかですが……。
試したこと
元々のプログラムは作成者のgitからcloneしたあと、自分でコンパイルしたものだったのですが、
condaというパッケージ管理ソフトから、コンパイル済みのものがインストールできたので、そちらも試しましたが同じく駄目でした。
データベース側のファイルは、ネットからダウンロードしたものをそのまま使っているので破損したりはしていないはずです。
補足情報(FW/ツールのバージョンなど)
windows10から、WSLでUbuntu 18.04を使っています。
プログラムはこちらからダウンロードしました。
https://github.com/soedinglab/hh-suite
追加情報
gdbというものを実行したうえでプログラムを走らせたところ、
Thread 1 "hhblits" received signal SIGSEGV, Segmentation fault. __strnlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:62 62 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory. (gdb) where #0 __strnlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:62 #1 0x00007ffffeac9fa1 in __old_fmemopen (buf=0xfdec293c1, len=6001, mode=0x80c229c "r") at oldfmemopen.c:245 #2 0x000000000807c5ce in HHDatabaseEntry::getTemplateHMM(Parameters&, char, float, int&, float*, float const (*) [20], float const (*) [20], HMM*) () #3 0x000000000808ede3 in ViterbiRunner::alignment(Parameters&, HMMSimd*, std::vector<HHEntry*, std::allocator<HHEntry*> >, float, float*, float const (*) [20], float const (*) [20], float const (*) [20], int, float const (*) [4][11], float const (*) [11][4][11], float const (*) [11][8]) [clone ._omp_fn.0] () #4 0x00007fffff63ce92 in GOMP_parallel ( fn=0x808eb80 <ViterbiRunner::alignment(Parameters&, HMMSimd*, std::vector<HHEntry*, std::allocator<HHEntry*> >, float, float*, float const (*) [20], float const (*) [20], float const (*) [20], int, float const (*) [4][11], float const (*) [11][4][11], float const (*) [11][8]) [clone ._omp_fn.0]>, data=0x7ffffff5bb80, num_threads=2, flags=0) at /home/nwani/m3/conda-bld/compilers_linux-64_1560109574129/work/.build/x86_64-conda_cos6-linux-gnu/src/gcc/libgomp/parallel.c:171 #5 0x000000000808fc5e in ViterbiRunner::alignment(Parameters&, HMMSimd*, std::vector<HHEntry*, std::allocator<HHEntry*> >, float, float*, float const (*) [20], float const (*) [20], float const (*) [20], int, float const (*) [4][11], float const (*) [11][4][11], float const (*) [11][8]) () #6 0x00000000080205fc in HHblits::run(_IO_FILE*, char*) () #7 0x0000000008012160 in main ()
と出ました。核心をついているような気もしますが、解読が出来ません・・・。
もしかしてstrlen-avx2.Sとやらを用意しておけばそれでオッケーってことなんですかね?
グーグルで調べてもあまり何のファイルなのかわかりませんが