今回は大きなプログラムをデバッグしてみましょう。
ここでは rosegarden をデバッグしてみることにします。
デバッグシンボルの生成
gcc に渡すだけなら、-g でよかったのですが、make を使うものは make が gcc などを呼び出すので少々厄介です。
プログラムによっていくつかのパターンがあります。
cmake の場合
rosegarden のトップディレクトリを見ると、
[lugia@lugia-castle rosegarden-1.7.2]$ ls AUTHORS CMakeLists.txt Doxyfile README cmake_admin data rosegarden.lsm src CMakeCache.txt CMakeLists.txt.optflags INSTALL RGbuild cmake_install.cmake docs rosegarden.spec version.txt CMakeFiles COPYING Makefile TRANSLATORS cmake_uninstall.cmake po rosegarden.spec.in
のように CMakeLists.txt のあるものは cmake でビルドするものです。
デバッグシンボルの生成をするには、
$ cmake -DCMAKE_BUILD_TYPE=Debug . $ make $ sudo make install
でできます。
autotools の場合
トップディレクトリを見て configure または configure.in と言う名前の実行ファイル(正確にはスクリプト)がある場合。
$ aclocal $ autoconf $ automake $ ./configure --enable-debug [その他のオプション] $ make $ sudo make install
Momonga Linux のパッケージ
${TOPDIR} は .OmoiKondara のあるディレクトリ。
$ cd ${TOPDIR} $ ../tools/OmoiKondara -G -fi rosegarden
相対パスは適宜修正のこと。
rosegarden はパッケージ名。
f を忘れない。SKIP になってしまう。
どれにも当てはまらない場合
$ (Makefile がなければ生成) $ export CFLAGS=-g && make $ sudo make install
使用言語が C++ なら CXXFLAGS=-g に変える。
さあ、デバッグ開始だ。
パスが通っているプログラムをデバッグする場合は、プログラム名だけ指定するでは自動的に探してくれる。
[lugia@lugia-castle pkgs]$ gdb rosegarden GNU gdb Momonga Linux 5 (6.8-8m.mo5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-momonga-linux"... (gdb)
さあ、開始。
(gdb) run Starting program: /usr/bin/rosegarden warning: linux_test_for_tracefork: unexpected result from waitpid (15827, status 0x57f) Detaching after fork from child process 15829. kbuildsycoca running... Reusing existing ksycoca Program exited normally. (gdb) PluginFactory::instance(dssi): creating new DSSIPluginFactory LADSPAPluginFactory::discoverPlugins - discovering plugins; path is [/home/lugia/.dssi] [/usr/local/lib/dssi] [/usr/lib/dssi] ...(後略)...
おや? 途中でプログラムが終了してますね。見えますか?
これではデバッグできませんね。
help を表示してみましょう。
(gdb) run --help Starting program: /usr/bin/rosegarden --help 使用法: rosegarden [Qt-オプション] [KDE-オプション] [オプション] [File] Rosegarden - シーケンサと譜面エディタ 一般的なオプション: --help オプションに関するヘルプを表示 --help-qt Qt に特有なオプションを表示 --help-kde KDE に特有なオプションを表示 --help-all すべてのオプションを表示 --author 著作者情報 -v, --version バージョン情報を表示 --license ライセンス情報を表示 -- オプションの最後 オプション: --nosequencer シーケンサは使えません (編集のみサポート) --nosplash スプラッシュスクリーンを表示しない --nofork バックグラウンドで自動的に起動しない --existingsequencer もしも見付かれば、シーケンサプロセスに接続 --ignoreversion インストールされたバージョンを無視 - 開発者のみ 引数: File ファイルをオープン Program exited with code 0376. (gdb)
ということなので、今回デバッグするところはシーケンサでは無いので、--nosequencer も付けて
(gdb) run --nosequencer --nofork --nosplash Starting program: /usr/bin/rosegarden --nosequencer --nofork --nosplash kbuildsycoca running... Composition::getTrackById(0) - WARNING - track id not found, this is probably a BUG /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/base/Composition.cpp:1533 Available track ids are: RosegardenGUIApp::awaitDialogClearance: entering RosegardenGUIApp::awaitDialogClearance: exiting TrackButtons::slotUpdateTracks WARNING: Unstable LilyPond version detected, selecting next language version up
はい。ここでメインウィンドウがでてきて止まります。
とりあえず、落ちてしまう操作をやってみましょう。今回やった操作は
WARNING: please edit ~/.scim/global and change /DefaultConfigModule to kconfig Program received signal SIGABRT, Aborted. 0x00110416 in __kernel_vsyscall () (gdb)
この操作をやると、SIGABRT を発行しているということですね。
さて、では bt の出番がやって参りました。
(gdb) bt #0 0x00110416 in __kernel_vsyscall () #1 0x00c85440 in raise () from /lib/libc.so.6 #2 0x00c86e08 in abort () from /lib/libc.so.6 #3 0x00cc93e3 in ?? () from /lib/libc.so.6 #4 0x00ccb305 in free () from /lib/libc.so.6 #5 0x0032a281 in operator delete () from /usr/lib/libstdc++.so.6 #6 0x0868f4ba in ~HSpinBox (this=0xa61be50) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/gui/widgets/HSpinBox.h:32 #7 0x028617c7 in QWidget::~QWidget () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #8 0x02b783f5 in QFrame::~QFrame () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #9 0x028617c7 in QWidget::~QWidget () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #10 0x028e280b in QGroupBox::~QGroupBox () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #11 0x028617c7 in QWidget::~QWidget () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #12 0x02b8d7b5 in QVBox::~QVBox () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #13 0x028617c7 in QWidget::~QWidget () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #14 0x029bbd78 in QDialog::~QDialog () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #15 0x0414cc84 in KDialogBase::~KDialogBase () from /usr/lib/libkdeui.so.4 #16 0x08439694 in ~TempoDialog (this=0xbfffe1f8) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/gui/dialogs/TempoDialog.cpp:189 #17 0x08592035 in Rosegarden::TempoView::slotPopupEditor (this=0x8e06180, qitem=0x91323c8) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/gui/editors/tempo/TempoView.cpp:793 #18 0x0859546d in Rosegarden::TempoView::qt_invoke (this=0x8e06180, _id=109, _o=0xbfffe524) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/RGbuild/TempoView.moc:167 #19 0x028270ca in QObject::activate_signal () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #20 0x02b80401 in QListView::doubleClicked () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #21 0x04127925 in KListView::contentsMouseDoubleClickEvent () from /usr/lib/libkdeui.so.4 #22 0x029459e0 in QScrollView::viewportMouseDoubleClickEvent () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #23 0x02944561 in QScrollView::eventFilter () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #24 0x029107e6 in QListView::eventFilter () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #25 0x02827183 in QObject::activate_filters () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #26 0x028271eb in QObject::event () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #27 0x028618fc in QWidget::event () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #28 0x027c156d in QApplication::internalNotify () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #29 0x027c2774 in QApplication::notify () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #30 0x039eff72 in KApplication::notify () from /usr/lib/libkdecore.so.4 #31 0x0275ad5e in QApplication::sendSpontaneousEvent () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #32 0x02757d08 in QETWidget::translateMouseEvent () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #33 0x02756fbe in QApplication::x11ProcessEvent () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #34 0x0276acf4 in QEventLoop::processEvents () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #35 0x027d9de0 in QEventLoop::enterLoop () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #36 0x027d9c76 in QEventLoop::exec () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #37 0x027c1bff in QApplication::exec () from /usr/lib/qt-3.3.7/lib/libqt-mt.so.3 #38 0x083808ec in main (argc=4, argv=0xbffff284) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/gui/application/main.cpp:733
上から順に見ていきましょ。
上の方は libc と qt ですから、今回のデバッグの対象ではありません。それをわけると、#6 の ~HSpinBox と #16 の ~TempoDialog が rosegarden の関数ですね。ですから、ここに breakpoint を置きたいのですが、C++ のコンストラクタとデストラクタにブレークポイントを設定することができません。
なので、そのもうひとつ上の Rosegarden::TempoView::slotPopupEditor をブレークポイントに設定しましょう。
(gdb) run Starting program: /usr/bin/rosegarden --nosplash --nosequencer --nofork kbuildsycoca running... Composition::getTrackById(0) - WARNING - track id not found, this is probably a BUG /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/base/Composition.cpp:1533 Available track ids are: RosegardenGUIApp::awaitDialogClearance: entering RosegardenGUIApp::awaitDialogClearance: exiting Comparing current version "1.7.2" with latest version "1.7.2" WARNING: Unstable LilyPond version detected, selecting next language version up
2回目以降の run は前回の引数がそのまま使われます。
便利ですね。
Breakpoint 1, Rosegarden::TempoView::slotPopupEditor (this=0x910dc70, qitem=0x9149920) at /home/lugia/Momonga/pkgs/rosegarden/BUILD/rosegarden-1.7.2/src/gui/editors/tempo/TempoView.cpp:768 768 TempoListItem *item = dynamic_cast<TempoListItem *>(qitem); (gdb) u 769 if (!item) (gdb) 772 timeT time = item->getTime(); (gdb) 774 switch (item->getType()) { (gdb) 778 TempoDialog dialog(this, getDocument(), true); (gdb) 779 dialog.setTempoPosition(time); (gdb) 787 SIGNAL(changeTempo(timeT, (gdb) 792 dialog.exec(); (gdb)
コマンド | 省略形 |
---|---|
until | u |
continue | c |
step | s |
覚えておくと良いかもしれません。
目的のダイアログがでてきました。
OKを押すと
Program received signal SIGABRT, Aborted. 0x00110416 in __kernel_vsyscall () (gdb)
となってしまいますので、step-in したいのですが、相手は GUI なので、難しいところです。
やってみれば判ります。ここでは省略(コラ
ということで何とかして #3 に設定したいところですね。できますよ。
関数名として指定できないだけですので(ぁ
/...(省略).../rosegarden-1.7.2/src/gui/widgets/HSpinBox.h
の中身を見ながらこのファイル内でブレークできそうなところを探します。
・・・無さそうですね。
残念! 他の関数はおろかデストラクタも定義されていませんでした。
ということは標準のデストラクタを呼び出しているので、もしかしたら rosegarden が問題じゃない・・・かも知れませんね。