2011-11-09 8 views
3

gdbを理解する上で問題があります。gdbが行をジャンプしています

私は主な機能を持っています、私は自分自身にこの主な機能を書いています。

このメインの行の中には、ライブラリ内のいくつかの関数を呼び出すものがあります。ライブラリ名は重要ではありませんが、tesseract-ocrです。

関数を呼び出すメインの私の行は、コンストラクタはここにある:

choiceItr = new tesseract::ChoiceIterator(itr); 

私は上記のライン上のgdbにブレークポイントを置いて、実行し、それがその行に停止したときに私はステップのコマンドを使用します機能に入る。ここで

が呼び出されるライブラリ関数である:

ChoiceIterator::ChoiceIterator(const ResultIterator& result_it) { 
    ASSERT_HOST(result_it.it_->word() != NULL); 
    tesseract_ = result_it.tesseract_; 
    PAGE_RES_IT res_it(*result_it.it_); 
    WERD_CHOICE* best_choice = res_it.word()->best_choice; 
    BLOB_CHOICE_LIST_CLIST* choices = best_choice->blob_choices(); 
    if (choices != NULL) { 
    BLOB_CHOICE_LIST_C_IT blob_choices_it(choices); 
    for (int blob = 0; blob < result_it.blob_index_; ++blob) 
     blob_choices_it.forward(); 
    choice_it_ = new BLOB_CHOICE_IT(blob_choices_it.data()); 
    choice_it_->mark_cycle_pt(); 
    } else { 
    choice_it_ = NULL; 
    } 
} 

その後、私は、関数の中を歩くためにGDBの「次」コマンドを使用します。ここ

は私のGDBコンソールです:

Breakpoint 1, pixsOfOneWord (langString=0x8049e7c "klm", 
    imageString=0x8049e71 "paket2.tif", outputData=0x8049c7b, 
    datapathString=0x8049e6f ".") at deneme234.cpp:161 
161 choiceItr = new tesseract::ChoiceIterator(itr); 
(gdb) step 
tesseract::ChoiceIterator::ChoiceIterator (this=0x819e6f0, result_it=...) 
    at resultiterator.cpp:234 
234  choice_it_ = new BLOB_CHOICE_IT(blob_choices_it.data()); 
(gdb) next 
225 ASSERT_HOST(result_it.it_->word() != NULL); 
(gdb) list 
220  return it_->word()->box_word->BlobPosition(blob_index_) == SP_DROPCAP; 
221 return false; 
222 } 
223 
224 ChoiceIterator::ChoiceIterator(const ResultIterator& result_it) { 
225 ASSERT_HOST(result_it.it_->word() != NULL); 
226 tesseract_ = result_it.tesseract_; 
227 PAGE_RES_IT res_it(*result_it.it_); 
228 WERD_CHOICE* best_choice = res_it.word()->best_choice; 
229 BLOB_CHOICE_LIST_CLIST* choices = best_choice->blob_choices(); 
(gdb) next 
278 } // namespace tesseract. 
(gdb) next 
226 tesseract_ = result_it.tesseract_; 
(gdb) next 
278 } // namespace tesseract. 
(gdb) next 
226 tesseract_ = result_it.tesseract_; 
(gdb) next 
230 if (choices != NULL) { 
(gdb) 

あなたが見ることができるように、

tesseract_ = result_it.tesseract_; 

行は、なぜ、2回呼ばれていますか?

PAGE_RES_IT res_it(*result_it.it_); 
WERD_CHOICE* best_choice = res_it.word()->best_choice; 
BLOB_CHOICE_LIST_CLIST* choices = best_choice->blob_choices(); 

また、上記の「次の」行が呼び出されなかった場合、なぜですか?

ありがとうございました。

+7

デバッグオプションで最適化せずにコンパイルしていますか? –

+0

@VJo、返信ありがとう、私はライブラリの(tesseract)ソースコードをコンパイルしなかったと私は告白する必要があります、私はプリコンパイルされたパッケージを使用しています。私はtesseract関数に入ることができると思うとき、私はそれがコンパイルで大丈夫だと思う。私は "-g"だけを持つメインを含む私のソースをコンパイルしています。私は最適化せずにメインをコンパイルするために検索します。しかし、あなたは最適化とデバッグオプションなしでtesseractをコンパイルするべきですか?もしデバッグオプションがあれば、 "-g"を意味しますか?事前に感謝します – merveotesi

+0

g ++を使用している場合は、デバッグシンボル –

答えて

9

あなたが踏み込んでいるライブラリは、最適化とデバッグシンボル(おそらく-g -O2、これはLinuxビルドのデフォルトです)でビルドされています。

デバッグ、コードを最適化など、制御フローの最適化は、「周りのジャンプ」するためのコードが発生すると、いくつかの変数は「<optimized out>」となって、やや難しいです

あなたはCXXFLAGS = -g -O0でライブラリを再構築することができ、またはあなたがすることを学ぶことができます最適化をオンにしてデバッグします。

後者は非常に便利なスキルです。多くの場合、あなたのプログラムはのみが最適化された状態でクラッシュするため、このモードではデバッグする必要があります。

+0

で最適化されていないコードを取得するために '-g -O0'を渡してください。返信いただきありがとうございます、ライブラリのコードディレクトリのルートにあるMakefileを変更しました。 O0、古いものをアンインストールしてください。その後、runautoconf、configure、make、make installを再度実行してください。しかし、gdbは上記のように動作します。 – merveotesi

+0

"ライブラリのコードディレクトリのルートにあるMakefileを変更しました"。あなたはそれが十分であると信じさせるものは何ですか?ビルドが実行するすべてのコマンドをログに記録し、 'resultiterator 'を確認してください。cpp'は実際には '-O2'ではなく' -O0'で構築されました。もしそれが '-O0'でビルドされていれば、ビルドしたばかりのライブラリは使用していません。 –

+0

ありがとうございます。@ロシア語を使用しました。 CFLAGS = -g -O0 CXXFLAGS = -g -O0をエクスポートし、runautoconf、configure、clean clean、make installを実行します。そして今、gdbはすべてのコードを1行ずつ順番に実行していますが、今は特にtesseractに関する他の質問があります。ありがとう。 – merveotesi

関連する問題