From Event to Action: Accelerate Your Decision Making with Real-Time Automation
How to debug the Common Printing Dialog
1. Debugging of CPD
Naruhiko Ogasawara
OpenPrinting Japan
Koedo LUG Offline Meeting
June 13th, 2009
2. What is OpenPrinting?
*nix の印刷関連の標準化を行う団体
The Linux Foundation の下部組織
Manager: Till Kamppeter
元 Mandriva Linux の印刷オタク
Foomatic という印刷ミドルウェアの開発者
主な業績
Open Printing Vector Printing (OPVP)
PDF Print Path
Automatic Driver Downloading
Common Printing Dialog (CPD)
3. What's Common Printing Dialog?
Desktop OS ではプリンタの印刷設定について
OS 側が用意するのが普通
アプリケーションはどのプリンタについても同じように実
装することができる
プリンタベンダは統一された方法でベンダ独自の機能
をユーザに見せることができる
*nix にはこれまでそういう仕組みがなかった
GTK+ / KDE それぞれ持っているが、互換性がない
それを解消するのが Common Printing Dialog
8. Debugging CPD (KDE ver.) (2)
とりあえずデーモンもどきを起動して、ダイアログア
プリを gdb で起動してえいっと実行
$ kde4dialog/kde4cpd &
$ gdb kde4dialog/viewdialog
GNU gdb 6.8debian
Copyright (C) 2008 Free Software Foundation, Inc.
<snip>
This GDB was configured as quot;i486linuxgnuquot;...
(gdb) run
Starting program: /home/naruhiko/commonprintingdialog/build/kde4
dialog/viewdialog
[Thread debugging using libthread_db enabled]
[New Thread 0xb5f19940 (LWP 19299)]
ASSERT failure in QVector<T>::operator[]: quot;index out of rangequot;, file
/usr/include/qt4/QtCore/qvector.h, line 335
Program received signal SIGABRT, Aborted.
[Switching to Thread 0xb5f19940 (LWP 19299)]
0xb800b422 in __kernel_vsyscall ()
9. Debugging CPD (KDE ver.) (3)
Qt の QVector クラスの [] オペレータで死んでる
でもまさかこんな基本クラスがバグってるとは考え
にくい
呼出側があやしい!> Backtrace !
(gdb) bt
#0 0xb800b422 in __kernel_vsyscall ()
#1 0xb66286d0 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0xb662a098 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7658595 in qt_message_output () from /usr/lib/libQtCore.so.4
#4 0xb7658681 in qFatal () from /usr/lib/libQtCore.so.4
#5 0xb765872c in qt_assert_x () from /usr/lib/libQtCore.so.4
#6 0x08064941 in QVector<CommonPrinting::CUPSDestination>::operator[] (
this=0xa0aef84, i=0) at /usr/include/qt4/QtCore/qvector.h:335
#7 0x0805dc40 in CPDialogWidget::initWidgets (this=0xa0aef50)
at /home/naruhiko/commonprintingdialog/kde4
dialog/cpd_dialog_widget.cpp:861
...
10. Debugging CPD (KDE ver.) (4)
人の書いたプログラムなのでロジックを追いたい
そこでメソッドの先頭に breakpoint して再実行
(gdb) b CPDialogWidget::initWidgets()
Breakpoint 1 at 0x805db19: file /home/naruhiko/commonprintingdialog/kde4dialog/
cpd_dialog_widget.cpp, line 855.
(gdb) run
Starting program: /home/naruhiko/commonprintingdialog/build/kde4dialog/view
dialog
[Thread debugging using libthread_db enabled]
[New Thread 0xb5eac940 (LWP 19668)]
[Switching to Thread 0xb5eac940 (LWP 19668)]
Breakpoint 1, CPDialogWidget::initWidgets (this=0x892b120)
at /home/naruhiko/commonprintingdialog/kde4dialog/cpd_dialog_widget.cpp:855
<snip>
861 currentPrinter = &(printers[0]);
(gdb) n
ASSERT failure in QVector<T>::operator[]: quot;index out of rangequot;, file /usr/include/
qt4/QtCore/qvector.h, line 335
Program received signal SIGABRT, Aborted.
0xb7f9e422 in __kernel_vsyscall ()
12. Debugging CPD (KDE ver.) (6)
Qt のドキュメントをチェック
http://doc.trolltech.com/4.5/qvector.html#operator-5b-5d
T & QVector::operator[] ( int i )
Returns the item at index position i as a modifiable reference.
i must be a valid index position in the vector (i.e., 0 <= i < size()).
size() == 0 のときに operator [] 呼んじゃダメ
だからこのコードの場合 size() == 0 ならアラート
出して終了するのが一番簡単