Guidelines and HOWTOs/Debugging/Debugging IOSlaves: Difference between revisions
Ahmad Samir (talk | contribs) Add notes about debugging with KDE_FORK_SLAVES env var set |
|||
Line 68: | Line 68: | ||
==Attaching gdb to an io-slave== | ==Attaching gdb to an io-slave== | ||
Due to the above sequence it is rather hard to get an io-slave in your | ===If KDE_FORK_SLAVES is not set=== | ||
debugger. But wait there is hope | |||
that slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the | If <code>KDE_FORK_SLAVES</code> environment variable is ''not set'', your application asks <code>klauncher</code> via DBus for an io-slave. If <code>klauncher<code> does not have an idle io-slave ready, it will ask <code>kdeinit</code> to start a new one. <code>kdeinit</code> forks and dlopens the library that contains the requested io-slave. | ||
Then it calls a function called <code>kdemain()</code> in the library. | |||
Due to the above sequence it is rather hard to get an io-slave in your debugger. But wait there is hope! You can start </code>klauncher</code> in such a way that io-slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the Slave class) are started in debug mode. | |||
E.g. to start all 'http' slaves in debug mode, you type: | E.g. to start all 'http' slaves in debug mode, you type: | ||
Line 85: | Line 88: | ||
</pre> | </pre> | ||
For example, these commands | For example, these commands won't work: | ||
<pre> | <pre> | ||
KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5 | KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5 | ||
Line 91: | Line 94: | ||
</pre> | </pre> | ||
When your application now requests | When your application now requests an http io-slave, the io-slave will be started kdeinit, but before it calls kdemain() (cq. main()) it will suspend the slave by sending it a SIGSTOP signal. | ||
slave by sending it a SIGSTOP signal. | |||
In the terminal from which you started kdeinit you will get | In the terminal from which you started kdeinit you will get a message like this: | ||
message: | |||
<pre> | <pre> | ||
kdeinit: Suspending process | kdeinit: Suspending process | ||
Line 103: | Line 103: | ||
</pre> | </pre> | ||
You can now debug your slave by | You can now debug your slave by using <code>gdb kdeinit 16779</code> in a terminal. | ||
a | |||
Note that modern Linux Kernels disable ptrace. If gdb says "ptrace: Operation not permitted." then you need to use a command like this: | |||
<pre> | |||
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope | |||
</pre> | |||
If you don't want to debug a slave you can let it continue by sending it a SIGCONT, with e.g. <code>kill -SIGCONT 16779</code>. Be aware that slaves will not be killed while they are suspended. | |||
Once you have started gdb, you can set e.g. breakpoints and then resume the slave by typing <code>continue</code> (or <code>c</code> for short). The debugger will return immediate with a message that a "SIGSTOP has been received" so you will have to type <code>continue</code> a second time. | |||
See also [[Development/Tutorials/Debugging/Debugging_on_MS_Windows#Debugging_kioslaves|Windows-specific notes on debugging io-slaves]]. | |||
If | ===If KDE_FORK_SLAVES is set=== | ||
Read the previous section, because a lot of what it said applies here too, the only difference is how the io-slave is started. | |||
slave | |||
If you set the <code>KDE_FORK_SLAVES</code> environment variable: | |||
{{Input|1=<nowiki> | |||
export KDE_FORK_SLAVES=1 | |||
</nowiki>}} | |||
then start your application from that terminal, a dedicated io-slave will be created for your application in-process. In this case to attach gdb to the io-slave, first find the pid of the io-slave process, you can do that by examining the output of e.g.: | |||
<pre> | |||
ps -ef | grep kdeinit | |||
</pre> | |||
let's say you're trying to debug the Trash io-slave, the output should contain something like: | |||
<pre> | |||
username 29333 29156 0 17:57 ? 00:00:00 trash.so [kdeinit5] trash local:/run/user/1000/klauncherJvaxHq.1.slave-socket local:/run/user/1000/<app-name>nUqbkc.4.slave-socket | |||
</pre> | |||
or you could simply use: | |||
<pre> | |||
ps -ef | grep trash.so | |||
</pre> | |||
the pid is 29333 in this case. Note that you may need to examing the output before starting your application and after starting it, in case there are other io-slaves already running. | |||
To attch gdb to that io-slave process: | |||
<pre> | |||
gdb --pid 29333 | |||
</pre> | |||
(if there is only one trash.so process running you can use <code>gdb --pid $(pidof trash.so)</code> | |||
and then follow the same debugging steps from the previous section. | |||
==Debugging io-slaves with valgrind== | ==Debugging io-slaves with valgrind== |
Revision as of 16:36, 31 May 2021
This page describes how you can debug a KIO ioslave.
How to Get Debug Output
GUI (Qt5/KF5 instructions)
- Launch the
kdebugsettings
tool, either from terminal or from KRunner (the latter can be invoked with Alt + F2) - Type the name of the KIO Slave (e.g. ftp, http, ...). (If it's not listed, it doesn't use categorized debug output, so either its output is always on, or commented out in the code, in which case it needs to be ported to qCDebug)
- From the drop-down menu next to each KIO Slave you're interested in, select Full Debug
- Press OK to close the dialog and the save your changes
- You can either run
kdeinit5
in terminal, in which case the output from any IO slave that's started afterwards will show up in that terminal OR - Alternatively log out then log back in, and additional debug info will typically end up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log
Notes:
- If you have rebuilt an IO Slave from source with some changes you'll need ensure that
kdeinit5
will pick it up; this works with KIO from the KDE repos:
cd <path to build dir>/bin export LD_LIBRARY_PATH=$PWD export QT_PLUGIN_PATH=$PWD kdeinit5
- in the first
cd
command you change to the directory containing the compiled binaries, in KIO case it's <build dir>/bin.
- in the first
- Instead of using
kdebugsettings
, you can change the Qt logging categories rules temporarily, in terminal:
export QT_LOGGING_RULES="*kio*=true"
- for more information see this.
GUI (Qt4/kdelibs4 instructions)
- Press ALT+F2.
- Enter 'kdebugdialog --fullmode' without the quotes and press enter.
- Select the desired number in the "Debug area", e.g. 7103 for http.
- In the [Information] box, select "File" as the output.
- Enter the desired file name, e.g. /tmp/kio_http.log.
- Press OK to close the dialog.
- Press ALT+F2, type kdeinit4 and press enter or alternatively log out of KDE and log back in.
This will print additional debug info to the stderr of your kdeinit process, which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log
Manual (Qt4/kdelibs4 instructions)
It is useful to redirect the debug output of your particular slave to a file instead of stderr. E.g. I myself use the following lines in $KDEDIR/share/config/kdebugrc.
[7113] InfoOutput=0 InfoFilename=/tmp/http [7103] InfoOutput=0 InfoFilename=/tmp/http
This redirects all debug info for areas 7103 and 7113 (as used by kio_http) to the file /tmp/http.
To get debug information from the SMB slave you can add the following to kioslaverc:
[SMB] DebugLevel=100
This will print additional debug info to the stderr of your kdeinit process, which typically ends up in ~/.X.err, ~/.xsession-errors or ~/.local/share/sddm/xorg-session.log
How does an io-slave get started?
Your application requests 'klauncher' via DBus for a slave. If 'klauncher' does not have an idle slave ready, it will ask kdeinit to start a new one. kdeinit forks and dlopens the library that contains the io-slave. Then it calls a function called kdemain() in the library.
Attaching gdb to an io-slave
If KDE_FORK_SLAVES is not set
If KDE_FORK_SLAVES
environment variable is not set, your application asks klauncher
via DBus for an io-slave. If klauncher
does not have an idle io-slave ready, it will ask
kdeinit
to start a new one. kdeinit
forks and dlopens the library that contains the requested io-slave.
Then it calls a function called kdemain()
in the library.
in such a way that io-slaves for a certain protocol (the first parameter of KIO::SlaveBase() constructor of the Slave class) are started in debug mode.
Due to the above sequence it is rather hard to get an io-slave in your debugger. But wait there is hope! You can start
klauncher
E.g. to start all 'http' slaves in debug mode, you type:
KDE_SLAVE_DEBUG_WAIT=http kdeinit5
This will restart 'kdeinit' and 'klauncher'.
Note: The string after the equal signal designates the name of a service, not the name of the slave! E.g. if you want to debug the kio_imap4, you must use:
KDE_SLAVE_DEBUG_WAIT=imap kdeinit5
For example, these commands won't work:
KDE_SLAVE_DEBUG_WAIT=imap4 kdeinit5 KDE_SLAVE_DEBUG_WAIT=143 kdeinit5
When your application now requests an http io-slave, the io-slave will be started kdeinit, but before it calls kdemain() (cq. main()) it will suspend the slave by sending it a SIGSTOP signal.
In the terminal from which you started kdeinit you will get a message like this:
kdeinit: Suspending process kdeinit: 'gdb kdeinit 16779' to debug kdeinit: 'kill -SIGCONT 16779' to continue
You can now debug your slave by using gdb kdeinit 16779
in a terminal.
Note that modern Linux Kernels disable ptrace. If gdb says "ptrace: Operation not permitted." then you need to use a command like this:
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
If you don't want to debug a slave you can let it continue by sending it a SIGCONT, with e.g. kill -SIGCONT 16779
. Be aware that slaves will not be killed while they are suspended.
Once you have started gdb, you can set e.g. breakpoints and then resume the slave by typing continue
(or c
for short). The debugger will return immediate with a message that a "SIGSTOP has been received" so you will have to type continue
a second time.
See also Windows-specific notes on debugging io-slaves.
If KDE_FORK_SLAVES is set
Read the previous section, because a lot of what it said applies here too, the only difference is how the io-slave is started.
If you set the KDE_FORK_SLAVES
environment variable:
export KDE_FORK_SLAVES=1
then start your application from that terminal, a dedicated io-slave will be created for your application in-process. In this case to attach gdb to the io-slave, first find the pid of the io-slave process, you can do that by examining the output of e.g.:
ps -ef | grep kdeinit
let's say you're trying to debug the Trash io-slave, the output should contain something like:
username 29333 29156 0 17:57 ? 00:00:00 trash.so [kdeinit5] trash local:/run/user/1000/klauncherJvaxHq.1.slave-socket local:/run/user/1000/<app-name>nUqbkc.4.slave-socket
or you could simply use:
ps -ef | grep trash.so
the pid is 29333 in this case. Note that you may need to examing the output before starting your application and after starting it, in case there are other io-slaves already running.
To attch gdb to that io-slave process:
gdb --pid 29333
(if there is only one trash.so process running you can use gdb --pid $(pidof trash.so)
and then follow the same debugging steps from the previous section.
Debugging io-slaves with valgrind
KLauncher can be told to run certain io-slaves through valgrind. The following command can be used to let klauncher run all https io-slaves via valgrind:
KDE_SLAVE_VALGRIND=https kdeinit5
The valgrind output will appear as the stderr output of the kdeinit process. The $VALGRIND_OPTS environment variable can be used to pass options to valgrind. If you want to use a different skin:
KDE_SLAVE_VALGRIND_SKIN=callgrind ( for example )