www-content/pages/develop/remote_debugging.txt

234 lines
9.4 KiB
Plaintext

~~Title: Remote debugging~~
==== Remote Debugging ====
This tutorial aims at providing approaches to remote debugging.
- [[|ssh]]
- [[|Gdb server]]
- [[|clouseau]]
=== SSH ===
Remote debugging through ssh was not detailed but approached in
[[/contrib/enlightenment-debug.md|Enlightenment Debugging]] section. In
this section, it is more convenient to use ssh for debugging enlightenment
because X is not available.
The version of SSH that you will want to use on Linux is called OpenSSH.
To really make ssh useful, you need a shell account on a remote machine.
The first thing we'll do is simply connect to a remote machine. This is
accomplished by running 'ssh hostname' on your local machine. The hostname
that you supply as an argument is the hostname of the remote machine that you
want to connect to. By default ssh will assume that you want to authenticate
as the same user you use on your local machine. To override this and use a
different user, simply use ''remoteusername@remotehostname'' or
''remoteusername@remoteipadress'' as the argument.
On your host machine:
<code bash>
ssh $remote_user_name@$remote_ip_address
#or
ssh $remote_user_name@$remote_hostname
</code>
The first time around it will ask you if you wish to add the remote host to a
list of known_hosts, go ahead and say yes.
<code bash>
The authenticity of host '10.5.18.65 (10.5.18.65)' can't be established.
ECDSA key fingerprint is f0:72:8c:9d:aa:54:e4:5a:39:50:b5:b9:fd:35:71:71.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.5.18.65' (ECDSA) to the list of known hosts.
</code>
It is important to pay attention to this question however because this is one
of SSH's major features. Host validation. To put it simply, ssh will check to
make sure that you are connecting to the host that you think you are
connecting to. That way if someone tries to trick you into logging into their
machine instead so that they can sniff your SSH session, you will have some
warning.
Finally, your user password should be asked and you can execute your command
as you were on the distant machine:
[[/contrib/enlightenment-debug.md#Debugging_Enlightenment_using_GDB|
Debugging Enlightenment using GDB]].
You can also use ssh-keygen to generate RSA and DSA keys. Public key
authentication for SSH sessions are far superior to any password
authentication and provide much higher security. ssh-keygen is the basic way
for generating keys for such kind of authentication.
=== Gdbserver ===
''gdbserver'' is a control program for Unix-like systems, which allows you to
connect your program with a remote ''gdb'' via ''target remote'' but without linking
in the usual debugging stub.
''gdbserver'' is not a complete replacement for the debugging stubs, because
it requires essentially the same operating-system facilities that ''gdb''
itself does. In fact, a system that can run ''gdbserver'' to connect to a
remote ''gdb'' could also run ''gdb'' locally! ''gdbserver'' is sometimes
useful nevertheless, because it is a much smaller program than ''gdb'' itself.
It is also easier to port than all of ''gdb'', so you may be able to get
started more quickly on a new system by using ''gdbserver''. Finally, if you
develop code for real-time systems, you may find that the tradeoffs involved
in real-time operation make it more convenient to do as much development work
as possible on another system, for example by cross-compiling. You can use
''gdbserver'' to make a similar choice for debugging.
''gdb'' and ''gdbserver'' communicate via either a serial line or a TCP
connection, using the standard gdb remote serial protocol.
<note>
''gdbserver'' does not have any built-in security. Do not run ''gdbserver'' connected
to any public network; a ''gdb'' connection to ''gdbserver'' provides access to the
target system with the same privileges as the user running ''gdbserver''.
</note>
First, you have to install ''gdbserver'' on your server side.
Then, use a segfault program, you can use as in [[apps_efl_debugging#Segfault
in callback function]].
run ''gdbserver'':
<code bash>
#server
gdbserver localhost:2000 hello
</code>
<code bash>
$ Process hello created; pid = 2763
$ Listening on port 2000
</code>
Now ''gdbserver'' is waiting for a connexion on the port 2000.
<note>
You could launch ''gdb'' in multiple process with ''gdbserver --multi
localhost:2000''.
<\note>
On the client side, run ''gdb'':
<code bash>
#client
gdb hello
</code>
<code bash>
...
$ Type "apropos word" to search for commands related to "word"...
$ Reading symbols from test...(no debugging symbols found)...done.
</code>
Use ''target remote''e to connect to the target system by indicating server ip
and port.
<code bash>
#client
(gdb) target remote 10.5.18.65:2000
</code>
<code bash>
$ Remote debugging using 10.5.18.65:2000
$ Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from
$ /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
$ done.
$ Loaded symbols for /lib64/ld-linux-x86-64.so.2
$ 0x00007ffff7ddb2d0 in _start () from /lib64/ld-linux-x86-64.so.2
</code>
At that point, you can add breakpoints or others, then if we continue our
program, the output of the program will be printed in the target machine.
<code bash>
#client
(gdb) continue
</code>
Now, the application is launched on server: if as i do you use the
[[apps_efl_debugging#Segfault in callback function]]
example: click on the seg button will provoke a segfault.
See after clicking, the traces on the client side:
<code bash>
$ Program received signal SIGSEGV, Segmentation fault.
$ 0x0000000000400b71 in ?? ()
</code>
You can now use ''gdb'' as it is explained in [[apps_efl_debugging#Segfault in
callback function]], for example print the backtrace:
<code bash>
(gdb) bt
</code>
<code bash>
$ 0 0x0000000000400b71 in ?? ()
$ 1 0x000000000073a9a0 in ?? ()
$ 2 0x00007ffff74e4f6c 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
$ 3 0x00007ffff561a8b7 in _eo_base_event_callback_call (obj_id=0x80000007e0000040, pd=0x73a3f0, desc=0x85d4c0, event_info=0x0) at lib/eo/eo_base_class.c:712
$ 4 0x00007ffff5619648 in eo_event_callback_call (desc=desc@entry=0x85d4c0, event_info=event_info@entry=0x0) at lib/eo/eo_base.eo.c:94
$ 5 0x00007ffff74e6f6e in evas_object_smart_callback_call (eo_obj=eo_obj@entry=0x80000007e0000040, event=event@entry=0x7ffff7af501f <SIG_CLICKED> "clicked", event_info=event_info@entry=0x0) at lib/evas/canvas/evas_object_smart.c:784
$ 6 0x00007ffff7995baf in _activate (obj=0x80000007e0000040) at elm_button.c:69
$ 7 0x00007ffff7995be5 in _on_clicked_signal (data=<optimized out>, obj=<optimized out>, emission=<optimized out>, source=<optimized out>) at elm_button.c:191
$ 8 0x00007ffff58b0507 in edje_match_callback_exec_check_finals (prop=<optimized out>, ed=0xaaaaaaaaaaaaaaab, source=0x7245b0 "elm", sig=0x73af9c "elm,action,click", source_states=<optimized out>, signal_states=<optimized out>, matches=0x73b0c0, ssp=0x7594e0) at lib/edje/edje_match.c:556
$ 9 edje_match_callback_exec (ssp=ssp@entry=0x7594e0, matches=0x73b0c0, sig=sig@entry=0x73af9c "elm,action,click", source=source@entry=0x7245b0 "elm", ed=ed@entry=0x73a9a0, prop=prop@entry=0 '\000') at lib/edje/edje_match.c:711
$ 10 0x00007ffff58b6a3d in _edje_emit_cb (prop=0 '\000', data=0x0, src=0x7245b0 "elm", sig=0x73af9c "elm,action,click", ed=0x73a9a0) at lib/edje/edje_program.c:1423
$ 11 _edje_emit_handle (ed=0x73a9a0, sig=0x73af9c "elm,action,click", src=0x7245b0 "elm", sdata=0x0, prop=0 '\000') at lib/edje/edje_program.c:1376
$ 12 0x00007ffff58b13a1 in _edje_message_process (em=0x667830) at lib/edje/edje_message_queue.c:684
$ 13 0x00007ffff58b18b3 in _edje_message_queue_process () at lib/edje/edje_message_queue.c:787
$ 14 0x00007ffff58b1a14 in _edje_job (data=<optimized out>) at lib/edje/edje_message_queue.c:154
$ 15 0x00007ffff7235a32 in _ecore_job_event_handler (data=<optimized out>, type=<optimized out>, ev=<optimized out>) at lib/ecore/ecore_job.c:121
$ 16 0x00007ffff7230463 in _ecore_call_handler_cb (event=<optimized out>, type=<optimized out>, data=<optimized out>, func=<optimized out>) at lib/ecore/ecore_private.h:386
$ 17 _ecore_event_call () at lib/ecore/ecore_events.c:565
$ 18 0x00007ffff7237e05 in _ecore_main_loop_iterate_internal (once_only=once_only@entry=0) at lib/ecore/ecore_main.c:1927
$ 19 0x00007ffff7237f14 in ecore_main_loop_begin () at lib/ecore/ecore_main.c:983
$ 20 0x00007ffff7a47e59 in elm_run () at elm_main.c:1097
</code>
=== Clouseau ===
An UI inspection tool for the EFL. This tool lets you inspect UI elements and
get a lot of their properties, e.g position, size and weight. Get more
information there: [[apps_efl_debugging#Clouseau]]
Clouseau consists of a client (clouseau_client) and launcher
(clouseau_server). This design means we can: Run the application we are
debugging on one device and the clouseau_client itself on another. ''It is very
similar to gdbserver''.
Usage of the split client/server approach (different machines/environments/setups):
== Server side ==
Get the ip of your server machine, for example do:
<code bash>
ip a
#or
ifconfig
</code>
Then start, the server side with the ''clouseau_start'' script launching the
application:
<code bash>
clouseau_start elementary_test
#or
clouseau_start ./your_application
</code>
== Client side ==
Simply do:
<code bash>
clouseau_client $ip_server
</code>
or use the client interface as below:
{{ :clouseau_remote.png?1200 }}
And now, clouseau is usable as in [[apps_efl_debugging#Clouseau]].