Wiki page enlightenment-debugging created
Signed-off-by: Clément Bénier <clement.benier@openwide.fr> Signed-off-by: Pierre Le Magourou <pierre.lemagourou@openwide.fr> Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
d342f75a86
commit
14666b3336
|
@ -0,0 +1,264 @@
|
|||
~~Title: Enlightenment debugging~~
|
||||
==== Enlightenment Debugging ===
|
||||
|
||||
This tutorial aims at providing a comprehensive and reproducible documentation
|
||||
to debug Enlightenment. It is divided in two sections:
|
||||
* [[enlightenment_debugging#Debugging_Enlightenment_using_Gdb|Gdb]]
|
||||
* [[enlightenment_debugging#Valgrind|Valgrind]]
|
||||
|
||||
Before debugging make sure your debug symbols are enabled, if not, go to the
|
||||
[[/docs-efl-start#Enable_debug_symbols_Optional|Enable debug symbols]]
|
||||
section.
|
||||
|
||||
|
||||
=== Debugging Enlightenment using Gdb ===
|
||||
|
||||
In order to use gdb, we will simulate a crash in Enlightenment.
|
||||
|
||||
Start by running Enlightenment on a machine. Then switch to another tty
|
||||
(CTRL+ALT+F1 for tty1).
|
||||
|
||||
At that point, 2 processes are interesting, enlightenment and
|
||||
enlightenment_start. Indeed, enlightenment is traced by enlightenment_start.
|
||||
|
||||
Then setup SEGV to segfault enlightenment.
|
||||
<code c>
|
||||
kill -SIGSEGV $(pidof enlightenment)
|
||||
</code>
|
||||
|
||||
enlightenment_start will open a pop-up named Enlightenment Error.
|
||||
This pop-up indicates that Enlightenment segfaulted and allows to recover or
|
||||
log out but also detaches from the child process (enlightenment) and let
|
||||
advanced users use gdb to debug it.
|
||||
<code bash>
|
||||
#gdb on the running enlightenment process
|
||||
gdb enlightenment $(pidof enlightenment)
|
||||
</code>
|
||||
|
||||
After a bit a prompt is available, if you want, you can save the
|
||||
traces in a log:
|
||||
<code bash>
|
||||
#save the traces in log.txt
|
||||
set logging file log.txt
|
||||
set logging on
|
||||
</code>
|
||||
|
||||
== Backtrace ==
|
||||
|
||||
Use the backtrace command to get information about frames to
|
||||
know where the segfault is coming from.
|
||||
|
||||
<code bash>
|
||||
(gdb) bt
|
||||
#0 0xb7d539f8 in select () from /lib/tls/libc.so.6
|
||||
#1 0xb7dff66a in _XEnq () from /usr/X11R6/lib/libX11.so.6
|
||||
#2 0xb7dffa7e in _XRead () from /usr/X11R6/lib/libX11.so.6
|
||||
#3 0xb7e01795 in _XReadEvents () from /usr/X11R6/lib/libX11.so.6
|
||||
#4 0xb7defa88 in XNextEvent () from /usr/X11R6/lib/libX11.so.6
|
||||
#5 0x0809b698 in e_alert_show (
|
||||
text=0x80a34f0 "This is very bad. Enlightenment has segfaulted.\nThis
|
||||
is not meant to happen and is likely a
|
||||
sign of a\nbug in Enlightenment
|
||||
or the libraries it relies on.\n\nYou can gdb attach to this process
|
||||
now to try"...)
|
||||
at e_alert.c:136
|
||||
#6 0x0808f706 in e_sigseg_act (x=11, info=0x80a9fb0, data=0x80aa030)
|
||||
at e_signals.c:54
|
||||
#7 <signal handler called>
|
||||
#8 0xb7d539f8 in select () from /lib/tls/libc.so.6
|
||||
#9 0xb7f814ee in _ecore_main_select (timeout=0)
|
||||
at ecore_main.c:338
|
||||
#10 0xb7f819ba in _ecore_main_loop_iterate_internal (once_only=0)
|
||||
at ecore_main.c:575
|
||||
#11 xb7f81a2b in ecore_main_loop_begin () at ecore_main.c:79
|
||||
#12 0x08059bb3 in main (argc=1, argv=0xbffff144) at e_main.c:551
|
||||
</code>
|
||||
|
||||
As you can see in the stack trace, gdb finds the segfault in libc and pops to the
|
||||
main function in e_main. But it doesn't seem credible to have a bug in libc or
|
||||
x, the important thing is Enlightenment has its own segfault handler which is
|
||||
very explicit on frame 5.
|
||||
|
||||
The e_sigseg_act() function at frame 6 is called directly from the kernel when
|
||||
the program segfaults, meaning enlightenment causes the
|
||||
segfault. So, the
|
||||
segfault comes from the select function (a libc function) at frame 8 called in
|
||||
_e_core_main_select_function at frame 9.
|
||||
|
||||
== Go in a frame ==
|
||||
|
||||
So, the reason of segfault seems to be at frame 9, when //select// function is
|
||||
called. Let's go to frame 9:
|
||||
|
||||
<code bash>
|
||||
fr 9
|
||||
#9 0xb7f814ee in _ecore_main_select (timeout=0) at ecore_main.c:338
|
||||
338 ret = select(max_fd + 1, &rfds, &wfds, &exfds, t);
|
||||
(gdb) l
|
||||
333 }
|
||||
334 }
|
||||
335 #ifndef WIN32
|
||||
336 if (_ecore_signal_count_get()) return -1;
|
||||
337 #endif
|
||||
338 ret = select(max_fd + 1, &rfds, &wfds, &exfds, t);
|
||||
339 if (ret < 0)
|
||||
340 {
|
||||
341 if (errno == EINTR) return -1;
|
||||
342 }
|
||||
</code>
|
||||
|
||||
The first command **//fr 9//** gives useful information: name of the file,
|
||||
number of the line, the function called, ...
|
||||
The second command **//l//** lists the code around the called function.
|
||||
Another useful command allows to print the variables, the parameters, helping
|
||||
you to find out the problem, a wrong parameter, a null pointer,...
|
||||
|
||||
<code bash>
|
||||
(gdb) p ret
|
||||
$1 = -4
|
||||
(gdb) p rfds
|
||||
$2 = {__fds_bits = {1280, 0 <repeats 31 times>}}
|
||||
(gdb) p wfds
|
||||
$3 = {__fds_bits = {0 <repeats 32 times>}}
|
||||
(gdb) p exfds
|
||||
$4 = {__fds_bits = {0 <repeats 32 times>}}
|
||||
</code>
|
||||
|
||||
Gdb is important to start debugging, it will help you to resize the problem
|
||||
even if sometimes is not enough.
|
||||
|
||||
----
|
||||
|
||||
=== Valgrind ===
|
||||
|
||||
Valgrind aims at finding memory problems but for that Enlightenment needs to be run
|
||||
through Valgrind.
|
||||
|
||||
== Prerequisites ==
|
||||
|
||||
This tutorial will present 3 different ways to run enlightenment through valgrind:
|
||||
* remote debugging
|
||||
* Xephyr invocation
|
||||
* Xinit invocation
|
||||
|
||||
The easiest way is certainly Xephyr because it allows to target a window on a
|
||||
X server host, sadly Xephyr doesn't yet support OpenGL and any issue that may
|
||||
be related to it will need to use the Xinit version.
|
||||
|
||||
== Remote Debugging ==
|
||||
|
||||
Enlightenment_start launcher will handle
|
||||
setting up environment variables, paths, and launching any other required
|
||||
services before Enlightenment starts.
|
||||
Fortunately, there are some options in enlightenment_start that allow to run
|
||||
Enlightenment through valgrind:
|
||||
|
||||
<code bash>
|
||||
$enlightenment_start --help
|
||||
Options:
|
||||
-valgrind[=MODE]
|
||||
Run enlightenment from inside valgrind, mode is OR of:
|
||||
1 = plain valgrind to catch crashes (default)
|
||||
2 = trace children (thumbnailer, efm slaves, ...)
|
||||
4 = check leak
|
||||
8 = show reachable after processes finish.
|
||||
all = all of above
|
||||
-massif
|
||||
Run enlightenment from inside massif valgrind tool.
|
||||
-callgrind
|
||||
Run enlightenment from inside callgrind valgrind tool.
|
||||
-valgrind-log-file=<FILENAME>
|
||||
Save valgrind log to file, see valgrind's --log-f
|
||||
</code>
|
||||
|
||||
First of all, get the ip address of your host machine and connect to it, then
|
||||
on the distant machine, launch X:
|
||||
|
||||
<code bash>
|
||||
#launch X on tty1
|
||||
sudo X -ac :1 &
|
||||
</code>
|
||||
|
||||
For example, If you want to check leak and save traces in a log file :
|
||||
|
||||
<code bash>
|
||||
export DISPLAY=:1
|
||||
enlightenment_start -valgrind=4 -valgrind-log-file=log.txt
|
||||
</code>
|
||||
|
||||
At that point, Enlightenment should have started on your host machine. If the
|
||||
session is closed then the summary of valgrind should look like :
|
||||
|
||||
<code bash>
|
||||
==1488==
|
||||
==1488== HEAP SUMMARY:
|
||||
==1488== in use at exit: 4,479,487 bytes in 24,302 blocks
|
||||
==1488== total heap usage: 336,239 allocs, 311,937 frees, 88,068,674 bytes allocated
|
||||
==1488==
|
||||
==1488== LEAK SUMMARY:
|
||||
==1488== definitely lost: 825 bytes in 15 blocks
|
||||
==1488== indirectly lost: 39 bytes in 2 blocks
|
||||
==1488== possibly lost: 384 bytes in 1 blocks
|
||||
==1488== still reachable: 4,478,239 bytes in 24,284 blocks
|
||||
==1488== suppressed: 0 bytes in 0 blocks
|
||||
==1488== Rerun with --leak-check=full to see details of leaked memory
|
||||
==1488==
|
||||
==1488== For counts of detected and suppressed errors, rerun with: -v
|
||||
==1488== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
|
||||
</code>
|
||||
|
||||
== Valgrind Invocation - xinit ==
|
||||
|
||||
Create a file called .xinitrc-debug in your home with the following content:
|
||||
|
||||
<code bash>
|
||||
#!/bin/sh
|
||||
|
||||
ulimit -c unlimited
|
||||
|
||||
log_file="$HOME/enlightenment-xinit-debug-valgrind.log"
|
||||
#path of you installation
|
||||
enlightenment_install_path=/usr/local
|
||||
|
||||
#set vars
|
||||
LD_LIBRARY_PATH="$enlightenment_install_path/lib"
|
||||
PATH="$enlightenment_install_path/bin:$PATH"
|
||||
|
||||
#log to file
|
||||
echo "using installation at $enlightenment_install_path"
|
||||
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" > $log_file
|
||||
echo "PATH=$enlightenment_install_path/bin: ... " >> $log_file
|
||||
|
||||
#start e with valgrind
|
||||
$enlightenment_install_path/bin/enlightenment_start -valgrind 2>&1 | tee -a "$log_file"
|
||||
</code>
|
||||
|
||||
You can now start a debugging session, after X was closed if it is not the
|
||||
case log out:
|
||||
|
||||
<code bash>
|
||||
/usr/bin/xinit ~/.xinitrc-debug -- :1 -nolisten tcp
|
||||
</code>
|
||||
|
||||
== Valgrind Invocation - Xephyr ==
|
||||
|
||||
Xephyr is a display server implementing the X11 display server protocol which
|
||||
targets a window on a X Server host. So, for this it is important that X is
|
||||
launched, you can even do it in your usual window manager under X.
|
||||
|
||||
Of course, you need to install Xephyr.
|
||||
|
||||
<code bash>
|
||||
Xephyr -ac -br -noreset -screen 800x600 :1
|
||||
</code>
|
||||
*ac: disable access control restrictions
|
||||
*br: create root window with black background
|
||||
*noreset: don't reset after last client exists
|
||||
*screen 800x600: Specify screen characteristics
|
||||
|
||||
A black screen should now be displayed, and the interesting thing for us is
|
||||
that you can launch a window manager on it with valgrind in addition:
|
||||
|
||||
<code bash>
|
||||
DISPLAY=:1 enlightenment_start -valgrind
|
||||
</code>
|
|
@ -25,6 +25,13 @@ course you can use stable packages for your distribution as well.
|
|||
* [[docs/efl/start|Get started with EFL]]
|
||||
* [[docs/efl/advanced/start|Advanced EFL Topics]]
|
||||
|
||||
Go check the current available version of EFL on each distro/platform:
|
||||
[[https://phab.enlightenment.org/w/packaging_status/|Table of current version of EFL]]
|
||||
|
||||
=== Debugging ===
|
||||
|
||||
* [[debugging/enlightenment_debugging|Enlightenment debugging]]
|
||||
|
||||
----
|
||||
|
||||
==== API Documentation ====
|
||||
|
|
Loading…
Reference in New Issue