cedric pushed a commit to branch master. http://git.enlightenment.org/website/www-content.git/commit/?id=14666b3336d583e0d2ee1e4a73348fcb29841304
commit 14666b3336d583e0d2ee1e4a73348fcb29841304 Author: Clément Bénier <clement.ben...@openwide.fr> Date: Thu Jun 11 09:28:29 2015 +0200 Wiki page enlightenment-debugging created Signed-off-by: Clément Bénier <clement.ben...@openwide.fr> Signed-off-by: Pierre Le Magourou <pierre.lemagou...@openwide.fr> Signed-off-by: Cedric BAIL <ced...@osg.samsung.com> --- pages/debugging/enlightenment_debugging.txt | 264 ++++++++++++++++++++++++++++ pages/docs.txt | 7 + 2 files changed, 271 insertions(+) diff --git a/pages/debugging/enlightenment_debugging.txt b/pages/debugging/enlightenment_debugging.txt new file mode 100644 index 0000000..7f953f2 --- /dev/null +++ b/pages/debugging/enlightenment_debugging.txt @@ -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> diff --git a/pages/docs.txt b/pages/docs.txt index 813ebe0..4d44943 100644 --- a/pages/docs.txt +++ b/pages/docs.txt @@ -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 ==== --