mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 10:22:48 +00:00

a crashed program trying to restart itself is very unreliable, especially program that uses KUniqueApplication instance. so, instead all the information about the crash shall be written to a file on the disk (in the temporary directory) and read by external kcrash KDED module that will report the crash (possibily even upload the crash details somewhere) and restart the program as necessarry. this also opens up possibility for per-application configuration for things such as the automatic restart feature but that shall be done by the kcrash KDED module instead (parsing a config from a crashed program is not a good idea) KCrash::NoRestart will be unused but kept for future expansion Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
152 lines
5.5 KiB
Text
152 lines
5.5 KiB
Text
Introduction
|
|
============
|
|
|
|
This is a short tutorial on debugging KDE applications. Throughout this
|
|
tutorial I will use "kedit" as example application.
|
|
|
|
|
|
Configuring for debugging
|
|
=========================
|
|
|
|
You can use -DCMAKE_BUILD_TYPE=Debug with the configure script, if you want to have
|
|
debug code in your KDE libs. If you have the space and can stand code that's
|
|
somewhat slower, this is worth it. The extra information really
|
|
helps debugging and thus bugfixing.
|
|
|
|
On the other hand, -DCMAKE_BUILD_TYPE=None removes all debug messages, leading
|
|
to a faster and cleaner desktop.
|
|
|
|
|
|
Debugging with GDB
|
|
==================
|
|
|
|
The recommended version of gdb to use is version 4.95 or higher, older
|
|
versions have problems generating proper backtraces.
|
|
|
|
There are three ways to debug an application with gdb:
|
|
|
|
1) You can start the application from within gdb.
|
|
2) You can attach gdb to an already running application.
|
|
3) You can run gdb after an application has crashed using a core file.
|
|
|
|
|
|
Starting applications from within gdb
|
|
=====================================
|
|
|
|
To start an application with gdb you can start gdb as follows:
|
|
|
|
> gdb kedit
|
|
GNU gdb 4.95.0
|
|
Copyright 2000 Free Software Foundation, Inc.
|
|
GDB is free software, covered by the GNU General Public License, and you are
|
|
welcome to change it and/or distribute copies of it under certain conditions.
|
|
Type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
|
This GDB was configured as "i686-pc-linux-gnu"...
|
|
(gdb)
|
|
|
|
You can now set the command line arguments that you want to pass to kedit with
|
|
the gdb command "set args":
|
|
|
|
(gdb) set args myfile.txt
|
|
(gdb)
|
|
|
|
gdb has loaded the kedit executable on startup but it hasn't loaded any of
|
|
the libraries yet. This means that you can set any breakpoints in the
|
|
libraries yet. The easiest way to do that is to set a breakpoint in the
|
|
first line of main and then start the program:
|
|
|
|
(gdb) break main
|
|
Breakpoint 1 at 0x8048741: file /d/kde/build/4/kdeutils/kedit/kedit_dummy.cpp, line 3
|
|
(gdb) run
|
|
Starting program: /opt/kde/bin/kedit myfile.txt
|
|
|
|
Breakpoint 1, main (argc=1, argv=0xbfa798b4) at /d/kde/build/4/kdeutils/kedit/kedit_dummy.cpp:3
|
|
3 int main(int argc, char* argv[]) { return kdemain(argc,argv); }
|
|
(gdb)
|
|
|
|
You can now set breakpoints everywhere. For example lets set a breakpoint
|
|
in the KApplication constructor. Remember to use quotes before C++ method names:
|
|
(gdb) break 'KApplication::init()'
|
|
Breakpoint 2 at 0xb7a5f86d: file /d/kde/src/4/kdelibs/kdeui/kernel/kapplication.cpp, line 488.
|
|
(gdb)
|
|
|
|
We can now continue the execution of kedit. Execution will stop when it hits
|
|
a breakpoint of when the program exits. In this case execution will stop
|
|
in the first line of the KApplication constructor:
|
|
|
|
(gdb) continue
|
|
Continuing.
|
|
Qt: gdb: -nograb added to command-line options.
|
|
Use the -dograb option to enforce grabbing.
|
|
|
|
Breakpoint 2, KApplication::init (this=0xbfa797b4) at /d/kde/src/4/kdelibs/kdeui/kernel/kapplication.cpp:488
|
|
488 if ((getuid() != geteuid()) ||
|
|
|
|
|
|
Attaching gdb to already running applications
|
|
=============================================
|
|
|
|
Sometimes it is not practical to start an application from within gdb.
|
|
E.g. in those cases where you didn't know the application was about to
|
|
crash :-).
|
|
|
|
gdb can be attached to an application that hasn't crashed (yet).
|
|
|
|
You start with finding the process of the application with e.g. "ps -aux":
|
|
|
|
> ps -aux | grep kedit
|
|
bastian 21570 15.1 6.8 13740 8800 pts/6 S 15:34 0:01 kedit
|
|
bastian 21582 0.0 0.3 1132 412 pts/6 R 15:34 0:00 grep kedit
|
|
|
|
From this you learn that kedit has process id 21570. Now you can start gdb as
|
|
follows:
|
|
|
|
> gdb kedit 21570
|
|
GNU gdb 4.95.0
|
|
Copyright 2000 Free Software Foundation, Inc.
|
|
GDB is free software, covered by the GNU General Public License, and you are
|
|
welcome to change it and/or distribute copies of it under certain conditions.
|
|
Type "show copying" to see the conditions.
|
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
|
This GDB was configured as "i686-pc-linux-gnu"...
|
|
/home1/bastian/21570: No such file or directory.
|
|
Attaching to program: /opt/kde/bin/kedit, Pid 21570
|
|
Reading symbols from /opt/kde/lib/kedit.so.0...done.
|
|
Loaded symbols for /opt/kde/lib/kedit.so.0
|
|
....
|
|
Reading symbols from /lib/ld-linux.so.2...done.
|
|
Loaded symbols for /lib/ld-linux.so.2
|
|
Reading symbols from /lib/libnss_compat.so.2...done.
|
|
Loaded symbols for /lib/libnss_compat.so.2
|
|
Reading symbols from /lib/libnsl.so.1...done.
|
|
Loaded symbols for /lib/libnsl.so.1
|
|
0x40c3d88e in __select () from /lib/libc.so.6
|
|
(gdb)
|
|
|
|
You will usually end up in the middle of a select() call from the event-loop.
|
|
This is the place where a KDE application spends most of its time, waiting
|
|
for things to happen.
|
|
|
|
A backtrace will typically look something like this:
|
|
|
|
(gdb) bt
|
|
#0 0x40c3d88e in __select () from /lib/libc.so.6
|
|
#1 0x40a22844 in __DTOR_END__ () at fam.c++:356
|
|
#2 0x407293bf in QApplication::enter_loop (this=0xbffff6e8)
|
|
at kernel/qapplication.cpp:2552
|
|
#3 0x406b1d7b in QApplication::exec (this=0xbffff6e8)
|
|
at kernel/qapplication_x11.cpp:2217
|
|
#4 0x4002d500 in main (argc=1, argv=0xbffff854) at kedit.cpp:1662
|
|
#5 0x40bbba5e in __libc_start_main (main=0x8048568 <main>, argc=1,
|
|
argv=0xbffff854, init=0x8048514 <_init>, fini=0x80486cc <_fini>,
|
|
rtld_fini=0x4000aa20 <_dl_fini>, stack_end=0xbffff84c)
|
|
at ../sysdeps/generic/libc-start.c:92
|
|
(gdb)
|
|
|
|
|
|
Getting core dumps
|
|
==================
|
|
|
|
If you want to have a core dump after your application crashes you need to
|
|
setup the kernel option for it (kernel.core_pattern) via `sysctl`.
|