WWW-www.enlightenment.org pushed a commit to branch master.

http://git.enlightenment.org/website/www-content.git/commit/?id=7bd74a834d75ecf510334b242cb603c445aa5a7f

commit 7bd74a834d75ecf510334b242cb603c445aa5a7f
Author: Gareth Halfacree <freela...@halfacree.co.uk>
Date:   Thu Nov 30 05:07:07 2017 -0800

    Wiki page gdb.md changed with summary [created] by Gareth Halfacree
---
 pages/develop/debug/c/gdb.md.txt | 231 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 231 insertions(+)

diff --git a/pages/develop/debug/c/gdb.md.txt b/pages/develop/debug/c/gdb.md.txt
new file mode 100644
index 000000000..b00c5e259
--- /dev/null
+++ b/pages/develop/debug/c/gdb.md.txt
@@ -0,0 +1,231 @@
+## Wrong function on an object ##
+
+---
+~~Title: Debugging with GDB~~
+---
+
+# Debugging with GDB #
+
+The GNU Debugger (GDB) is an invaluable tool for tracking down the precise 
cause of a crash or other error. While more information on GDB is available on 
the [GNU website](https://www.gnu.org/software/gdb/documentation/), this 
document introduces its use specifically for debugging applications written 
with the Enlightenment Foundation Libraries (EFL).
+
+> **NOTE:** Always begin by running the problem application and walking 
through the steps needed to reproduce the crash. GDB is of most use when you 
have a reliable reproduction for your issue.
+
+## Debugging an Incorrect Object ##
+
+The code below creates three Elementary objects: ``win``, ``box`` and ``btn``. 
It displays a window with an "OK" button which closes the window when it is 
clicked. Enter the following and save it as "hello.c":
+
+```c
+#include <Elementary.h>
+
+static void
+on_done(void *data, Evas_Object *obj, void *event_info)
+{
+  `` quit the mainloop (elm_run function will return)
+  elm_exit();
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+  Evas_Object *win, *box, *btn;
+
+  `` new window
+  win = elm_win_util_standard_add("hello", "Hello");
+  `` add a box object
+  box = elm_box_add(win);
+  `` add object as a resize object for the window (controls window minimum
+  `` size as well as gets resized if window is resized)
+  elm_win_resize_object_add(win, box);
+  evas_object_show(box);
+  `` add a button
+  btn = elm_button_add(win);
+  `` set default text of button to "OK"
+  elm_object_text_set(btn, "OK");
+  `` pack the button at the end of the box
+  /****ERROR****/
+  elm_box_pack_end(win, btn); ``win instead of box
+  evas_object_show(btn);
+  `` call on_done when button is clicked
+  evas_object_smart_callback_add(win, "clicked", on_done, NULL);
+  ``show the window
+  evas_object_show(win);
+
+  `` run the mainloop and process events and callbacks
+  elm_run();
+  return 0;
+}
+ELM_MAIN()
+```
+
+Compile with the ``-g`` flag to enable debugging symbols:
+
+```bash
+gcc -Wall -O1 -march=native -g -ggdb3 -o hello hello.c `pkg-config --cflags 
--libs elementary`
+```
+
+Then execute the program:
+
+```bash
+./hello
+ERR<13670>:eo lib/eo/eo.c:780 _eo_api_op_id_get() in elm_box.eo.c:48: unable 
to resolve regular api func 'elm_obj_box_pack_end' 0x7f1128f50faf in class 
'Elm_Win'.
+```
+
+The cause of this error is that the ``elm_box_pack_end()`` function is called 
on the incorrect object, ``win``. The error log says that the 
``elm_obj_box_pack_end`` is not in the ``Elm_win`` API, and so that the error 
is coming from the application and not from EFL itself.
+
+For a more complicated application, this basic trace is not enough to track 
down the precise location of the error. Fortunately, EFL provides a macro for 
backtraces: ``EINA_LOG_ABORT``.
+
+A message generated by CRI macro can automatically call ``abort()`` once a 
message of a given log level is printed. This is controlled by the environment 
variable ``EINA_LOG_ABORT`` and the level to be considered critical with 
``EINA_LOG_ABORT_LEVEL``. This means the program will stop at the first error 
which meets these two requirements.
+
+Run GDB over your application to receive the following backtrace:
+
+```gdb
+EINA_LOG_ABORT_LEVEL=4 EINA_LOG_ABORT=1 gdb hello
+(gdb) run
+Starting program: /home/efl/test/hello
+[Thread debugging using libthread_db enabled]
+Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
+[New Thread 0x7fffea2da700 (LWP 13679)]
+ERR<13675>:eo lib/eo/eo.c:780 _eo_api_op_id_get() in elm_box.eo.c:48: unable
+to resolve regular api func 'elm_obj_box_pack_end' 0x7ffff7991faf in class
+'Elm_Win'.
+ 
+Program received signal SIGABRT, Aborted.
+0x00007ffff6c76cc9 in __GI_raise (sig=sig@entry=6) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:56
+56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
+(gdb) bt
+#0  0x00007ffff6c76cc9 in __GI_raise (sig=sig@entry=6) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:56
+#1  0x00007ffff6c7a0d8 in __GI_abort () at abort.c:89
+#2  0x00007ffff6387919 in eina_log_print_unlocked (args=0x7fffffffdac8, 
fmt=0x7ffff561c970 "in %s:%d: unable to resolve %s api func '%s' %p in class 
'%s'.", line=780,    fnc=0x7ffff561d330 <__FUNCTION__.12409> 
"_eo_api_op_id_get", file=0x7ffff561c48c "lib/eo/eo.c", 
level=EINA_LOG_LEVEL_ERR, domain=25) at lib/eina/eina_log.c:1274
+#3  eina_log_print (domain=25, level=level@entry=EINA_LOG_LEVEL_ERR, 
file=file@entry=0x7ffff561c48c "lib/eo/eo.c", fnc=fnc@entry=0x7ffff561d330 
<__FUNCTION__.12409> "_eo_api_op_id_get", line=line@entry=780, 
fmt=fmt@entry=0x7ffff561c970 "in %s:%d: unable to resolve %s api func '%s' %p 
in class '%s'.") at lib/eina/eina_log.c:2079
+#4  0x00007ffff56122c5 in _eo_api_op_id_get 
(api_func=api_func@entry=0x7ffff7991faf <elm_obj_box_pack_end>, 
is_main_loop=is_main_loop@entry=1 '\001', file=file@entry=0x7ffff7af39cc 
"elm_box.eo.c", line=line@entry=48) at lib/eo/eo.c:778
+#5  0x00007ffff7991fe3 in elm_obj_box_pack_end 
(subobj=subobj@entry=0x80000007e0000040) at elm_box.eo.c:48
+#6  0x00007ffff79940cf in elm_box_pack_end (obj=obj@entry=0x80000003a000001e, 
subobj=subobj@entry=0x80000007e0000040) at elm_box.eo.c:223
+#7  0x0000000000400b69 in elm_main (argc=argc@entry=1, 
argv=argv@entry=0x7fffffffddb8) at hello.c:34
+#8  0x0000000000400bcd in main (argc=1, argv=0x7fffffffddb8) at hello.c:47
+```
+
+The ``elm_obj_box_pack_end()`` function is in frame six, so is called from 
frame seven.
+
+Go to frame seven:
+
+```gdb
+(gdb) fr 7
+#7  0x0000000000400b69 in elm_main (argc=argc@entry=1, 
argv=argv@entry=0x7fffffffddb8) at hello.c:34
+34    elm_box_pack_end(win, btn); //win instead of box
+```
+
+This frame shows that the ``win`` object is used as a parameter of 
``elm_box_pack_end``, instead of ``box``, at line 34 of "hello.c".
+
+
+## Debugging a Callback Function ##
+
+To demonstrate the debugging of a callback function, create the following 
program:
+
+```c
+#include <Elementary.h>
+
+static void
+on_done(void *data, Evas_Object *obj, void *event_info)
+{
+  int *pi = (int *)0; `` pointer on 0x0!!!
+  /**SEGFAULT**/
+  int i = *pi; `` segfault accessing 0x0 address
+
+  `` quit the mainloop (elm_run function will return)
+  elm_exit();
+}
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+  Evas_Object *win, *box, *btn;
+
+  `` new window
+  win = elm_win_util_standard_add("hello", "Hello");
+  `` add a box object
+  box = elm_box_add(win);
+  `` add object as a resize object for the window
+  elm_win_resize_object_add(win, box);
+  evas_object_show(box);
+  `` add a button
+  btn = elm_button_add(win);
+  `` set default text of button to "SEG"
+  elm_object_text_set(btn, "SEG");
+  `` pack the button at the end of the box
+  elm_box_pack_end(box, btn);
+  evas_object_show(btn);
+  `` call on_done when button is clicked
+  evas_object_smart_callback_add(btn, "clicked", on_done, NULL);
+  ``show the window
+  evas_object_show(win);
+
+  `` run the mainloop and process events and callbacks
+  elm_run();
+  return 0;
+}
+ELM_MAIN()
+```
+
+Save the program as "helloworld.c", compile it, and run it. The program will 
quit with a segmentation fault (segfault) error when the "seg" button is 
clicked; in other words, during the callback function.
+
+To debug this, load the program into GDB and run it:
+
+```gdb
+gdb helloworld
+(gdb) run
+(gdb) bt
+#0  0x0000000000400c7f in on_done (data=0x0, obj=0x8000000800000041, 
event_info=0x0) at helloworld.c:6
+#1  0x00007ffff6c1cb84 in _eo_evas_smart_cb (data=<optimized out>, 
eo_obj=<optimized out>, desc=<optimized out>, event_info=<optimized out>) at
+    lib/evas/canvas/evas_object_smart.c:65
+#2  0x00007ffff5e43d22 in _eo_base_event_callback_call 
(obj_id=0x8000000800000041, pd=0x92b4f0, desc=0x94e320, event_info=0x0) at
+    lib/eo/eo_base_class.c:716
+#3  0x00007ffff5e42a97 in eo_event_callback_call (desc=desc@entry=0x94e320,
+    event_info=event_info@entry=0x0) at lib/eo/eo_base.eo.c:94
+#4  0x00007ffff6c1ebad in evas_object_smart_callback_call 
(eo_obj=eo_obj@entry=0x8000000800000041, event=event@entry=0x7ffff7af0bdf
+    <SIG_CLICKED> "clicked", event_info=event_info@entry=0x0) at 
lib/evas/canvas/evas_object_smart.c:791
+#5  0x00007ffff7994b8c in _activate (obj=0x8000000800000041) at elm_button.c:69
+#6  0x00007ffff7994bc2 in _on_clicked_signal (data=<optimized out>,
+    obj=<optimized out>, emission=<optimized out>, source=<optimized out>) at
+    elm_button.c:191
+#7  0x00007ffff60d0425 in edje_match_callback_exec_check_finals 
(prop=<optimized out>, ed=<optimized out>, source=<optimized out>,
+    sig=<optimized out>, source_states=<optimized out>, 
signal_states=<optimized out>, matches=<optimized out>, ssp=<optimized
+    out>) at lib/edje/edje_match.c:556
+#8  edje_match_callback_exec (ssp=0x0, ssp@entry=0x946520, 
matches=0x8000000800000041, sig=0x0, sig@entry=0x92c06c "elm,action,click",
+     source=0x0, source@entry=0x914f60 "elm", ed=0x7ffff5e471b7, 
ed@entry=0x92ba70, prop=94 '^', prop@entry=0 '\000') at
+     lib/edje/edje_match.c:712
+#9  0x00007ffff60d673d in _edje_emit_cb (prop=0 '\000', data=0x0, src=0x914f60
+    "elm", sig=0x92c06c "elm,action,click", ed=0x92ba70) at 
lib/edje/edje_program.c:1392
+#10 _edje_emit_handle (ed=0x92ba70, sig=0x92c06c "elm,action,click", 
src=0x914f60 "elm", sdata=0x0, prop=0 '\000') at lib/edje/edje_program.c:1345
+#11 0x00007ffff60d1296 in _edje_message_process (em=0x669cf0) at 
lib/edje/edje_message_queue.c:651
+#12 0x00007ffff60d178c in _edje_message_queue_process () at 
lib/edje/edje_message_queue.c:754
+#13 0x00007ffff60d18ec in _edje_job (data=<optimized out>) at 
lib/edje/edje_message_queue.c:155
+#14 0x00007ffff696d3e0 in _ecore_job_event_handler (data=<optimized out>, 
type=<optimized out>, ev=<optimized out>) at lib/ecore/ecore_job.c:113
+#15 0x00007ffff69680a4 in _ecore_call_handler_cb (event=<optimized out>,
+    type=<optimized out>, data=<optimized out>, func=<optimized out>) at 
lib/ecore/ecore_private.h:386
+#16 _ecore_event_call () at lib/ecore/ecore_events.c:565
+#17 0x00007ffff696f711 in _ecore_main_loop_iterate_internal 
(once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1927
+#18 0x00007ffff696f81e in ecore_main_loop_begin () at 
lib/ecore/ecore_main.c:983
+#19 0x00007ffff7a4559f in elm_run () at elm_main.c:1097
+#20 0x0000000000400d79 in elm_main (argc=1, argv=0x7fffffffe398) at 
helloworld.c:39
+#21 0x0000000000400dc2 in main (argc=1, argv=0x7fffffffe398) at helloworld.c:42
+```
+
+The program failed in the callback function, meaning the problem comes from 
the program itself and not the libraries - even if the callback is called from 
``Evas``.
+
+To look at the problem more deeply:
+
+* Go to frame zero, the callback function
+* Print the ``pi`` pointer
+* Print what it points to
+
+```bash
+(gdb) fr 0
+#0  0x0000000000400c86 in on_done (data=0x0, obj=0x8000000800000041, 
event_info=0x0) at helloworld.c:6
+6     int i=*pi;
+(gdb) p pi
+$1 (int *) 0x0
+(gdb) p *pi
+Cannot access memory at address 0x0
+```
+
+This demonstrates the problem: address ``0x0`` cannot be accessed. Using these 
techniques, even if the callback functions are called from Evas and so generate 
lots of traces, it is quite simple to track down these types of bug.
\ No newline at end of file

-- 


Reply via email to