I will explain 2 techniques of debugging of an ARM 9 application. Debugging helps to rectify code and makes life easier, but when we deal with embedded systems we have more and more options of choosing right debugger.

Native debugging

Here I like to share some of my experience with strace.I would like to say this as Native debugging since no networking is involved and debugging is done directly over terminal of target. Correct me if I am wrong in this notion. Let us jump into strace..

strace will be compiled while generating cross-compiler for preferred architecture, locate it from cross-compiler and copy to /usr/bin directory of target.

strace allows to trace all the system calls made by a process: opening, reading and writing files, starting other processes, accessing time, etc. When something goes wrong in your application, strace is an invaluable tool to see what it actually does, even when you don’t have the source code.

Application and cross-compilation

$ arm-linux-gcc -o app app.c

copy the binary to target

$ cp app path/to/target/root_dir 

Running application over target,

# ./app

<just hangs, no output>

But this is not the required output, let us use strace now

$ strace ./app

<output truncated>
open(“/etc/vista.key”, O_RDONLY) = -1 ENOENT (No such file or directory)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0xbeeacdf0) = 0
open(“/etc/vista.key”, O_RDONLY) = -1 ENOENT (No such file or directory)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0xbeeacdf0) = 0
open(“/etc/vista.key”, O_RDONLY) = -1 ENOENT (No such file or directory)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0xbeeacdf0) = 0

As you can see my application is looking for a file /etc/pista.c which is not available inside my target, So I created an empty file at /etc/pista.c

# touch /etc/pista.c

Again, running application

# ./app

<I got required output>

You can see that, even without browsing source code of my application I can debug it..

Cheers…!

Remote debugging

We need to install gdb at host and gdbserver at target, both will be connected together with either with serial or ethernet port. Universal law of gdb is binaries(executables) inside host system must have debugging symbols (necessary for any debugging software) and it should not be stripped, whereas the same binary inside target must be stripped of.

Main advantage of strip is it will produce executables in very smaller size.

Let us jump into gdb remote debugging

1) Cross compile application with insisting debug informations inside executable by using -g ,

$ arm-linux-gcc -g -o app app.c

2) Strip of executable inside target

$ arm-linux-strip path/to/root/filesystem/app

Keep in mind, here I am using NFS for root filesystem for target, hence I can access the root filesystem as like any other files inside system.

3) On target run program through gdbserver 

gdbserver localhost:<port> <executable> <args>
gdbserver /dev/ttyS0 <executable> <args>

At target,

# gdbserver localhost: 2345 app

Process app created; pid = 415
Listening on port 2345

as per your judgement yes a new process is created and it starts listening at respective port no 2345 for any host system.

4) And at host, run the ARCH-linux-gdb program, and use the following gdb commands:

To connect to target,

gdb> target remote <ip-addr>:<port> (networking)

gdb> target remote /dev/ttyS0 (serial link)

To tell gdb where shared libraries are:

gdb> set sysroot <library-path>

$ arm-linux-gdb app

GNU gdb (crosstool-NG 1.18.0) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i686-build_pc-linux-gnu –target=arm-unknown-linux-uclibcgnueabi”.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>&#8230;
Reading symbols from /home/elcot/Desktop/Embedded_linux/felabss/sysdev/debugging/vista-emulator…done.
(gdb)

You can see that I am using gdb of crosstool-ng which was configured by me.

Then, we need to tell where to find our libraries, since they are not present in the default /lib and /usr/lib directories on your workstation. This is done by setting GDB sysroot variable,

(gdb) set sysroot /usr/local/xtools/arm-unknown-linux-uclibcgnueabi/arm-unknown-linux-uclibcgnueabi/sysroot/

To connect with target,

(gdb) target remote <target-ip-address>:2345

(gdb)

Now you are connected with target, and start using normal gdb commands for debugging

(gdb) continue
(gdb) backtrace

and so on….upto finding bug in application.

Enjoy..!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s