Maemo Debugging Guide
Introduction
This debugging guide is targeted for beginner-level maemo developers needing to know how to perform debugging in the maemo environment.
This document covers the two basic debugging tools available in the maemo environment and shows how to use them. The tools are:
gdb
- The Gnu Project Debugger. General tool for various debugging needs.valgrind
- Debugger and profiler. Valgrind works only in the X86 environment under Scratchbox, so this tool cannot be used in the device itself.
This document assumes that the developer already knows how to:
- develop software in the Linux environment using the C language
- install software to the tablet device
- gain root access to the device
- install
ssh
to the device - configure repositories in the
/etc/apt/sources.list
file - set up USB networking between a Linux PC and the Tablet (the device can also be used over a local WLAN connection instead)
- work with the Scratchbox environment and Scratchbox targets
If you do not know how to perform these, read first the other documents available on the maemo.org site and in the maemo wiki.
Pre-Requisites
To follow the debugging examples the following is needed:
- maemo 4.0 SDK installed in a Linux PC
- Nokia Internet Tablet device running OS2008.
- USB cable to connect the device with the Linux PC
- Internet access both for the tablet and for the Linux PC
- USB networking (or WLAN) set up between the Linux PC and the device
- root login access to the device over
ssh
- package maemo-sdk-debug installed
osso-xterm
installed in the devicessh
software installed in the device
General Notes on Debugging
Debugging Issues on ARM Architecture
There are some issues one needs to be aware of when debugging on the ARM architecture.
- To make backtraces work properly in ARM side, the dbg packages need to be installed for the libraries the application is using. Profiling and debugging (gdb) tools require code to have either framepointers or debugging symbols to unwind stack. This is needed for showing backtraces or call graphs.
- C language functions with the
__attribute__((__noreturn__))
statement need to be compiled with the gcc option:-fno-omit-frame-pointer
. Without framepointers, no backtrace can be gotten through"noreturn"
functions. In practice, what would happen is that when thebt
command is used, this kind of function would repeat infinitely. - In addition, for the
gdb
to be able to display correct function names during debugging, it also needs to have access to the debug symbols. Without them, it shows preceding exported function name for a given address.
Debugging Issues in Scratchbox
It is recommended to use the native
gdb
in the target, not the Scratchbox
host-gdb
.
When debugging threads in an application, gdb
needs to be linked against the same thread library that the
application is using. For this reason, the Scratchbox-provided
gdb
is not suitable for threads debugging, but the
native gdb
needs to be used instead. See
instructions in the next section on how to start using the
native gdb
.
warning:
Cannot initialize thread debugging library: unknown
thread_db error '22'
" messages in gdb
output, and info threads
command in
gdb
will show nothing.
Using Gdb Debugger
Introduction to Gdb
The Gnu Project Debugger, or gdb
for short, is
a general purpose debugger that can be used for various
debugging purposes.
This section does not explain how to use the
gdb
debugger itself, i.e. it does not explain the
specific commands in gdb to perform some specific actions.
There are other tutorials and documentation readily available
in the Internet (http://www.gnu.org/software/gdb/documentation/)
for that purpose. This document focuses on explaining how to
set up and perform the basic debugging steps with the
gdb
in the maemo environment.
For additional gdb documentation take a look at the maemo tools documentation for gdb.
Setting up Environment
Both the Internet Tablet device and the Scratchbox environment need to be set up.
Preparing Scratchbox Environment for Debugging
If the maemo 4.0 release is not yet installed, it must be installed before continuing.
After installing maemo 4.0, the default target names for Armel and X86 are CHINOOK_ARMEL and CHINOOK_X86. These will be used in this example.
gdb
debugger. If
just [sbox-CHINOOK_X86: ~] > gdb ...
is
run, then that gdb
debugger is used. In this
document, the native-gdb
(i.e. non-Scratchbox
version of gdb
) is used.
Next, install gdb
to the Scratchbox from the
maemo 4.0 repositories.
[sbox-CHINOOK_X86: ~] > fakeroot apt-get install gdb [sbox-CHINOOK_X86: ~] > fakeroot apt-get install maemo-debug-scripts [sbox-CHINOOK_X86: ~] > fakeroot apt-get install maemo-sdk-debug
Now two gdb
programs are installed. The one
used can be checked with:
[sbox-CHINOOK_X86: ~] > which gdb /targets/links/arch_tools/bin/gdb
If only using the command gdb
, then the
gdb
used is the one provided by Scratchbox.
Start briefly both gdb
debuggers to see that
they start properly in the Scratchbox environment. First just
run gdb
:
[sbox-CHINOOK_X86: ~] > gdb GNU gdb 6.4.90 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu". (gdb) q [sbox-CHINOOK_X86: ~] >
Then run the maemo version of gdb
:
[sbox-CHINOOK_X86: ~] > native-gdb GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu". (gdb) q [sbox-CHINOOK_X86: ~] >
To quit from gdb
, type 'q' and hit ENTER.
This document uses the native-gdb
, since it
allows also threads to be debugged.
Both gdb
versions are available in the
Scratchbox X86 environment. The native-gdb
should
always be run instead of the Scratchbox version.
Preparing Internet Tablet for Debugging
The gdb
needs to be installed in the Internet
Tablet device. It is recommended that first
osso-xterm
and then ssh
are installed
in the device before continuing.
- Start
osso-xterm
. - Gain root access to the device while running osso-xterm.
- Edit the
/etc/apt/sources.list
file in the device so that it contains line:deb http://repository.maemo.org/ chinook free non-free
The
/etc/apt/sources.list
file can be edited with a text editor (e.g.vi
), but following command given from theosso-xterm
is also valid:echo "deb http://repository.maemo.org/ chinook free non-free" >> /etc/apt/sources.list
WarningImportant: it is not recommended to perform device software updates from the maemo sdk repositories (for example, 'apt-get upgrade' is not recommended for the device). The reason for this is that there might be some software packages in the SDK repositories that are so-called sdk variants. They might create a problem, if directly installed in the actual device. In this example, onlygdb
software is used from the repository. - Perform an
apt-get update
in the device. The update command will refresh the package list database in the device. - Perform an
apt-get install gdb
You should now have the gdb
and
gdbserver
(included in the gdb
package) installed in the device.
/etc/apt/sources.list
file, remove or comment
the line out. This way, you will not accidentally get
programs from the wrong repository to the device. See notes
above.
Debugging Use Cases with Gdb
Debugging Command Line Application in Scratchbox X86 Environment with Gdb
One of the most common debugging case is performing debugging in the Scratchbox X86 environment.
By now, the gdb
is installed in the CHINOOK_X86
target. Next, download the
gdb_example.tar.gz
package and extract it to a
directory under your Scratchbox. For example, do the
following:
[sbox-CHINOOK_X86: ~] > mkdir src
[sbox-CHINOOK_X86: ~] > cd src/testing
# download this gdb_example.tar.gz
and copy it to this directory.
[sbox-CHINOOK_X86: ~/src] > tar xvzf gdb_example.tar.gz
gdb_example/
gdb_example/gdb_example.c
gdb_example/gdb_example2.c
[sbox-CHINOOK_X86: ~/src] > cd gdb_example
[sbox-CHINOOK_X86: ~/src/testing/gdb_example] >
There should now be two files: gdb_example.c
and gdb_example2.c
files under the
~/src/testing/gdb_example/
directory.
The example apps are:
- the
gdb_example.c
is a very simple C application that has some functions that call each other in a row. This is used here to demonstrate how to get backtraces. - the
gdb_example2.c
is a simple variant of thegdb_example.c
that has some additionalsleep()
calls. This will be used to demonstrate simple core dump debugging.
Next, the small gdb_example.c
file should be
compiled as shown below, and the gdb
debugger
should be started. This simple example shows how to set
breakpoints, and how to get a backtrace from the program.
Backtrace tells what functions have been called and what
parameters have been used.
Compile the gdb_example.c
application with the
-g option like this:
[sbox-CHINOOK_X86: ~/src/testing/gdb_example] > gcc gdb_example.c -o gdb_example -g
Next, start the gdb
with the
gdb_example
application as a parameter.
[sbox-CHINOOK_X86: ~/src/testing/gdb_example] > native-gdb gdb_example GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"... Using host libthread_db library "/lib/libthread_db.so.1".
Set the breakpoint (br) to function
example_3
(gdb) br example_3 Breakpoint 1 at 0x80483e9: file gdb_example.c, line 48.
Run the application under gdb
giving a command
line parameter foobar
to the application.
(gdb) run foobar Starting program: /home/user/src/testing/gdb_example/gdb_example foobar Now in main(). Now in example_1(2) function. Now in example_2(parameter here) function. Breakpoint 1, example_3 () at gdb_example.c:48 48 printf("Now in example_3()\n");
The above shows that the running of the application stopped
in function example_3
. This happened because the
breakpoint (br example_3
) was set.
Now the backtrace (bt
) can be listed from
application to see what functions have been called. The list
goes from recent to older. The oldest function was naturally
the main()
function at the end of the list. It
shows also the parameters to the called functions.
(gdb) bt #0 example_3 () at gdb_example.c:48 #1 0x080483dc in example_2 (a=0x80484f8 "parameter here") at gdb_example.c:39 #2 0x080483b9 in example_1 (x=2) at gdb_example.c:30 #3 0x08048387 in main (argc=2, argv=0xbfc437e4) at gdb_example.c:18 (gdb)
It can be convenient to see what the source code is for a line mentioned in the output:
(gdb) list 39 34 * 35 */ 36 int example_2(char* a) 37 { 38 printf("Now in example_2(%s) function.\n",a); 39 example_3(); 40 return 0; 41 } 42 /* 43 * (gdb)
Also the values of the variables can be inspected:
(gdb) br example_2 Breakpoint 1 at 0x80483c4: file gdb_example.c, line 38. (gdb) run Starting program: /home/user/src/testing/gdb_example Now in main(). Now in example_1(1) function. Breakpoint 2, example_2 (a=0x80484f8 "parameter here") at gdb_example.c:38 38 printf("Now in example_2(%s) function.\n",a);
To see the value of variable 'a' just type:
(gdb) print a $1 = 0x80484f8 "parameter here" (gdb)
Essentially, debugging with gdb
in the
Scratchbox X86 target is similar to debugging with
gdb
in any Linux host. In this example, only a
small subset of gdb's
functionality has been
used.
Debugging Command Line Application in Internet Tablet Device
It is possible to debug an application in the Internet
tablet device itself using gdb
. Before starting,
log in on the device and install (if you have not done so yet)
the gdb
debugger to the device:
/home/user # apt-get install gdb ... etc ... /home/user #
Here it is assumed that ssh
and
osso-xterm
are already installed in the tablet and
that it is possible to log in on the device using
ssh
from a Linux PC. In addition, the maemo 4.0
repository entries should be set in the
/etc/apt/sources.list
file as explained
previously.
Debugging with the gdb
debugger in the device
is similar to using gdb
in a normal Linux PC
environment. The limitations are mostly related to the
available free RAM memory, meaning that in the worst case,
memory might run out while trying to debug an application in
the device.
This example follows the basic logic of the first example, but this time is performed in the device.
- Compile the
gdb_example.c
application in the Scratchbox for armel architecture.[sbox-CHINOOK_X86: ~] > sb-conf select CHINOOK_ARMEL Hangup Shell restarting... [sbox-CHINOOK_ARMEL: ~] > pwd /home/user [sbox-CHINOOK_ARMEL: ~] > cd src/testing/gdb_example [sbox-CHINOOK_ARMEL: ~/src/testing/gdb_example] > gcc gdb_example.c -o gdb_example -g [sbox-CHINOOK_ARMEL: ~/src/testing/gdb_example] > file gdb_example gdb_example: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped [sbox-CHINOOK_ARMEL: ~/src/testing/gdb_example] >
- Copy the armel version of the
gdb_example
to the tablet. You need to have thesshd
daemon up and running in the device before you can copy files withscp
.[sbox-CHINOOK_ARMEL: ~/src/testing/gdb_example] > scp gdb_example user@192.168.2.15: user@192.168.2.15's password: ........... gdb_example 100% 9135 8.9KB/s 00:00
- Log in on the device with
ssh
with nameuser
. The IP address is an example, and your device IP address can be different.[sbox-CHINOOK_ARMEL: ~/src/testing/gdb_example] > ssh root@192.168.2.15 root@192.168.2.15's password: .......... BusyBox v1.6.1 (2007-09-27 18:08:59 EEST) Built-in shell (ash) Enter 'help' for a list of built-in commands. ~# cd ~user /home/user# pwd /home/user /home/user# mkdir src /home/user# mkdir src/testing /home/user# mv gdb_example src/testing /home/user# cd src/testing /home/user# pwd /home/user/src/testing
- Start the
gdb
debugger with thegdb_example
application./home/user# gdb gdb_example GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... Using host libthread_db library "/lib/libthread_db.so.1". (gdb)
You should now be able to debug this small example application in a similar way as in the previous example.
Debugging Core Files in Device
This section explains how to debug core files in the Internet Tablet.
The kernel does not dump cores of a failing process, unless told where to dump the core files.
The default values for core dumps can be seen by reading the
file linuxrc
with the more
command in
the device, and by studying the enable_coredumps()
function:
/home/user # more /mnt/initfs/linuxrc ... snip ... enable_coredumps() { coredir=/media/mmc1/core-dumps echo -n "Enabling core dumps to $coredir/..." echo "$coredir/%e-%s-%p.core" > /proc/sys/kernel/core_pattern ulimit -c unlimited echo "done." } ... snip ...
As can be seen, the default location for core dumps is in
/media/mmc1/core-dumps
directory. The second
echo
command defines the name of the core dump
file. The default name contains the name of the executable
(%e), the signal (%s) and the PID number (%p).
If these default settings are satisfactory, it is enough to
create the core-dumps
directory under the
/media/mmc1
directory.
Next, the small example application
gdb_example2
will be used to demonstrate how to
debug the core file.
- Compile the
gdb_example2
in the ScratchboxCHINOOK_ARMEL
target, and just copy the file to the device usingscp
. Now, unplug the USB cable to get access to memory cars. Then start thegdb_example2
in the device like this:/home/user # ./gdb_example2 & /home/user # gdb_example2. Now in main(). Now in example_1(1) function.
- The
gdb_example2
is now running in the background, and it starts to dump its output to the screen. There are somesleep()
calls in thegdb_example2
, so that you have time to kill it with theSIGSEGV
signal. Now just make it to generate a core dump. Assuming that the process is referred to as %1, just use the kill command as below and press the ENTER key a couple of times:/home/user # kill -SIGSEGV %1 /home/user # [1] + Segmentation fault (core dumped) ./gdb_example2
- You should now have a core file under the
/media/mmc1/core-dumps
directory. Its name should start with "core
", include the name of the file and end with the PID number of thegdb_example2
program. Check that you got it (the number shown below, 11437, will naturally be different in your environment):/home/user # ls -l /media/mmc1/core-dumps/ -rw-r--r-- 1 user root 139264 Nov 9 13:09 gdb_example2-11-1390.core /home/user #
- The
gdb_example2
is linked against thelibc
library. If you want to be able to resolve symbols also for the library during debugging, you need to installlibc6-dbg
package in the device. This same rule applies to other libraries that your application might be linked against. See the further notes about the DBG packages in this document.Now install the
libc6-dbg
package to get symbols for the library./home/user # apt-get install libc6-dbg Reading Package Lists... Done Building Dependency Tree... Done The following NEW packages will be installed: libc6-dbg .... snip ... /home/user #
- Now you can debug the core file together with the
gdb_example2
binary that you compiled with the-g
flag. Try and see where the execution of thegdb_example2
was when you used the-SIGSEGV
signal. Start thegdb
and give thegdb_example2
as the first parameter, and thecore
file as the second parameter:/home/user # gdb ./gdb_example2 /media/mmc1/core-dumps/gdb_example2-11-1390.core GNU gdb 6.6-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... Using host libthread_db library "/lib/libthread_db.so.1". Reading symbols from /lib/libc.so.6...BFD: /usr/lib/debug/lib/libc-2.5.so: warning: sh_link not set for section `.ARM.exidx' Reading symbols from /usr/lib/debug/lib/libc-2.5.so...done. done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.3...BFD: /usr/lib/debug/lib/ld-2.5.so: warning: sh_link not set for section `.ARM.exidx' Reading symbols from /usr/lib/debug/lib/ld-2.5.so...done. done. Loaded symbols for /lib/ld-linux.so.3 Core was generated by `./gdb_example2'. Program terminated with signal 11, Segmentation fault. #0 0x410adcec in nanosleep () from /lib/libc.so.6
The example above shows that now
gdb
is using debug symbols from/usr/lib/debug/lib/libc-2.5.so
. Had thelibc6-dbg
package not been installed, thegdb
would not have information available about the libraries' debug symbols.Now, the
gdb
is waiting for a command, so just give thebt
(backtrace) command. You should see something similar to this:(gdb) bt #0 0x410adcec in nanosleep () from /lib/libc.so.6 #1 0x410ada54 in sleep () from /lib/libc.so.6 #2 0x0000846c in example_2 (a=0x8570 "parameter here") at gdb_example2.c:41 #3 0x0000842c in example_1 (x=1) at gdb_example2.c:32 #4 0x000083e0 in main (argc=1, argv=0xbee57e24) at gdb_example2.c:19
N.B.For this simple example, the availablelibc6-dbg
package was installed before starting to debug thegdb_example2
application. If the dbg packages for various libraries were not installed, it would mean that the backtrace information coming from the non-debug version of the library could not be trusted.Depending on at what point the
kill -SIGSEGV
command was given, the output can be different. In this example, the process was hit when it was calling thesleep
function inside theexample_1
function in filegdb_example2.c
. It can also be seen that thesleep()
function has further called thenanosleep()
function, and that is when it got the-SIGSEGV
signal (see the note above).
Debugging Core File from Device Inside Scratchbox
Because the binaries and libraries in the device are pre-linked, successful debugging inside the Scratchbox environment using the programs core file (from the device) would require that:
- you copy the relevant libraries (i.e. the ones the
application is using) from the device to the Scratchbox.
Otherwise addresses in the pre-linked and unpre-linked
libraries would not match, and
gdb
backtraces would not load the library. - If the core file debugging is performed in the Scratchbox
ARMEL environment, the native
gdb
program needs to be used instead of the one provided by Scratchbox. See the previous section on how to set the nativegdb
as the default one.
After copying the /lib/libc6
library from the
device and setting the native gdb
to be used, the
application can be debugged normally.
Debugging UI Applications in Scratchbox X86
Many maemo applications use the graphical UI, and debugging these applications differs slightly from debugging simple command line applications.
Here the maemopad will be used as an example application to
debug in the X86 target with gdb
.
If the Scratchbox environment is set up correctly as explained above, these steps should be easy to follow to perform UI debugging with maemopad application.
- Activate the X86 target, go to the testing directory and
download the source package of maemopad application.
[sbox-CHINOOK_ARMEL] sb-conf select CHINOOK_X86 [sbox-CHINOOK_X86] cd ~/src/ [sbox-CHINOOK_X86 ~/src] mkdir maemopad [sbox-CHINOOK_X86 ~/src/maemopad] cd maemopad [sbox-CHINOOK_X86 ~/src/maemopad] apt-get source maemopad Reading package lists... Done Building dependency tree... Done Need to get 384kB of source archives. Get:1 http://juri.research.nokia.com chinook/free maemopad 2.1 (dsc) [476B] Get:2 http://juri.research.nokia.com chinook/free maemopad 2.1 (tar) [384kB] Fetched 384kB in 0s (4637kB/s) dpkg-source: warning: extracting unsigned source package (./maemopad_2.1.dsc) dpkg-source: extracting maemopad in maemopad-2.1 dpkg-source: unpacking maemopad_2.1.tar.gz
- Check that you have the correct files.
[sbox-CHINOOK_X86: ~/src/maemopad] > ls -l total 388 drwxrwxr-x 6 maemo maemo 4096 Sep 26 15:00 maemopad-2.1 -rw-rw-r-- 1 maemo maemo 476 Nov 8 17:26 maemopad_2.1.dsc -rw-rw-r-- 1 maemo maemo 383834 Nov 8 17:26 maemopad_2.1.tar.gz
- Go to the
maemopad-2.1
source directory and set theDEB_BUILD_OPTIONS
environment variable, so that the generated binaries are not stripped. Then build the maemopad package withdpkg-buildpackage
command as shown here:[sbox-CHINOOK_X86: ~/src/maemopad] > cd maemopad-2.1 [sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > export DEB_BUILD_OPTIONS=debug,nostrip [sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > dpkg-buildpackage -rfakeroot dpkg-buildpackage: source package is maemopad dpkg-buildpackage: source version is 2.1 dpkg-buildpackage: source changed by Maemo Integration <integration@maemo.org> dpkg-buildpackage: host architecture i386 dpkg-buildpackage: source version without epoch 2.1 : Using Scratchbox tools to satisfy builddeps .... etc ....
N.B.In this example, the standardexport DEB_BUILD_OPTIONS=debug,nostrip
environment variable is used, but there might be source packages that do not support thesedebug,nostrip
options. In that case, one must make sure that the source is compiled with-g
flag (usually this option can be added to theCFLAGS
variable in thedebian/rules
file), and that the produced binaries will not be stripped.
In the long run, it is better to modify the source package to generate a separate debug symbol (-dbg) package. This requires modifying both thedebian/rules
anddebian/control
files. - You should now have maemopad binaries generated so that
they have the debug symbols in them. Check that you get a
"not stripped"
flag from the maemopad binary:[sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > file debian/tmp/usr/bin/maemopad debian/tmp/usr/bin/maemopad: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), not stripped
- You should now have a
maemopad_2.1_i386.deb
file in the~/src/maemopad
directory. Check that you have it:[sbox-CHINOOK_X86: ~/src/maemopad] > ls -l total 440 drwxrwxr-x 6 maemo maemo 4096 Nov 9 13:37 maemopad-2.1 -rw-rw-r-- 1 maemo maemo 476 Nov 9 13:36 maemopad_2.1.dsc -rw-rw-r-- 1 maemo maemo 388593 Nov 9 13:36 maemopad_2.1.tar.gz -rw-rw-r-- 1 maemo maemo 675 Nov 9 13:37 maemopad_2.1_i386.changes -rw-r--r-- 1 maemo maemo 42632 Nov 9 13:37 maemopad_2.1_i386.deb
- Install the newly compiled
maemopad_2.1_i386.deb
file inside the Scratchbox environment:[sbox-CHINOOK_X86: ~/src/maemopad] > dpkg -i maemopad_2.1_i386.deb ... output from dpkg ...
- Start the
Xephyr
server outside the Scratchbox:Linux-PC $ Xephyr :2 -host-cursor -screen 800x480x16 -dpi 96 -ac -extension Composite &
- Start the Application Framework from inside the
Scratchbox X86 target:
[sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > export DISPLAY=:2 [sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > af-sb-init.sh start ... lots of output from various programs ...
You should now have the application framework up and running and theXephyr
window should contain the normal SDK UI. - Move to the source directory:
[sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1] > cd src/ui
- In the ui directory, you should have the files:
[sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1/src/ui] ls -l total 40 -rw-r--r-- 1 maemo maemo 12404 Sep 26 14:13 callbacks.c -rw-r--r-- 1 maemo maemo 2250 Sep 26 14:11 callbacks.h -rw-r--r-- 1 maemo maemo 15562 Jun 20 10:42 interface.c -rw-r--r-- 1 maemo maemo 3282 Jun 20 10:42 interface.h
- In this example, a debugging breakpoint will be set at
the callback function
callback_help()
located in thecallbacks.c
file. This function is called when the user clicks theHELP
button from the maemopad menu. Set the debugging breakpoint like this:[sbox-CHINOOK_X86: ~/src/maemopad/maemopad-2.1/src/ui] > run-standalone.sh gdb maemopad (gdb) br callback_help Breakpoint 1 at 0x804bf56: file ui/callbacks.c, line 296.
- Start the maemopad application from the
gdb
.(gdb) run Starting program: /targets/CHINOOK_X86/usr/bin/maemopad [Thread debugging using libthread_db enabled] [New Thread -1222154560 (LWP 22944)] /home/maemo/.osso/current-gtk-key-theme:1: Unable to find include file: "keybindings.rc" maemopad[22944]: GLIB WARNING ** GLib-GObject - invalid cast from `HildonProgram' to `GtkWidget' maemopad[22944]: GLIB CRITICAL ** Gtk - gtk_widget_show: assertion `GTK_IS_WIDGET (widget)' failed Audio File Library: could not open file '/usr/share/sounds/ui-window_open.wav' [error 3] Audio File Library: could not open file '/usr/share/sounds/ui-window_close.wav' [error 3] hello-world background
N.B.Thread-debugging: Now the nativegdb
program is used. If you need to debug threads in the application, you need to use the nativegdb
linked against the same thread library that your application is using. Remember that the Scratchboxgdb
is not suitable for this purpose.
To use the nativegdb
,native-gdb
needs to be used, as mentioned earlier in this document. - Now you should be able to see the maemopad application
inside the
Xephyr
window, and you should be able to use it normally. Next, click the upper menu and select the item HELP. In yourgdb
terminal window you should now see :Breakpoint 1, callback_help (action=0x80bda40, data=0x806eca8) at ui/callbacks.c:296 296 {
- The breakpoint that you set above is now reached, and
execution of maemopad application is stopped. The
gdb
debugger waits for your command now. Try something simple, like using the list command to see where the execution of the application is going. You should get:(gdb) list 291 } 292 } 293 294 /* help */ 295 void callback_help( GtkAction * action, gpointer data ) 296 { 297 osso_return_t retval; 298 299 /* connect pointer to our AppUIData struct */ 300 AppUIData *mainview = NULL;
- You can now debug the maemopad normally. Try and see, if
you can execute the maemopad step by step so that you can get
the help window on screen. Enter the
s
command like this:(gdb) s 302 g_assert(mainview != NULL && mainview->data != NULL ); (gdb) s 302 g_assert(mainview != NULL && mainview->data != NULL ); (gdb) s 304 retval = hildon_help_show( (gdb) s hildon_help_show (osso=0x80bda40, help_id=0x804cb08 "Example_MaemoPad_Content", flags=1) at osso-helplib.c:636 636 osso-helplib.c: No such file or directory. in osso-helplib.c (gdb)
- You can also try the
bt
(backtrace) command to see what functions were called. You should see a list of functions that have been called, similar to the following:(gdb) bt #0 hildon_help_show (osso=0x80bda40, help_id=0x804cb08 "Example_MaemoPad_Content", flags=1) at osso-helplib.c:636 #1 0x0804bfb0 in callback_help (action=0x80bda40, data=0x1) at ui/callbacks.c:304 #2 0xb78bc688 in IA__g_cclosure_marshal_VOID__VOID (closure=0x8106ae0, return_value=0x0, n_param_values=1, param_values=0xfffffffe, invocation_hint=0xbfac6798, marshal_data=0x0) at gmarshal.c:77 #3 0xb78a563b in IA__g_closure_invoke (closure=0x8106ae0, return_value=0x1, n_param_values=1, param_values=0x1, invocation_hint=0x1) at gclosure.c:490 #4 0xb78bb058 in signal_emit_unlocked_R (node=0x80f2bb8, detail=0, instance=0x80bda40, emission_return=0x0, instance_and_params=0xbfac68c0) at gsignal.c:2440 #5 0xb78bbfa8 in IA__g_signal_emit_valist (instance=0x80bda40, signal_id=1, detail=0, var_args=0xbfac6a4c "\001\020") at gsignal.c:2199 #6 0xb78bc296 in IA__g_signal_emit (instance=0x1, signal_id=1, detail=1) at gsignal.c:2243 #7 0xb7def78b in IA__gtk_widget_activate (widget=0x80bda40) at gtkwidget.c:4273 #8 0xb7cd9c62 in IA__gtk_menu_shell_activate_item (menu_shell=0x8103030, menu_item=0x80bda40, force_deactivate=1) at gtkmenushell.c:1230 #9 0xb7cda009 in gtk_menu_shell_button_release (widget=0x8103030, event=0x810c060) at gtkmenushell.c:748 #10 0xb7cd0f78 in gtk_menu_button_release (widget=0x8103030, event=0x810c060) at gtkmenu.c:2978 #11 0xb7cc67d0 in _gtk_marshal_BOOLEAN__BOXED (closure=0x8071028, return_value=0xbfac6c90, n_param_values=2, param_values=0xbfac6de0, invocation_hint=0xbfac6cb8, marshal_data=0xb7cd0e40) at gtkmarshalers.c:84 #12 0xb78a5979 in g_type_class_meta_marshal (closure=0x8071028, return_value=0x1, n_param_values=1, param_values=0xbfac6de0, invocation_hint=0x1, marshal_data=0x1) at gclosure.c:567 #13 0xb78a563b in IA__g_closure_invoke (closure=0x8071028, return_value=0x1, n_param_values=1, param_values=0x1, invocation_hint=0x1) at gclosure.c:490 #14 0xb78babcb in signal_emit_unlocked_R (node=0x80708c0, detail=0, instance=0x8103030, emission_return=0xbfac6d70, instance_and_params=0xbfac6de0) at gsignal.c:2478 #15 0xb78bbcfd in IA__g_signal_emit_valist (instance=0x8103030, signal_id=0, detail=0, var_args=0xbfac6f70 "xo%G��%@00\020\b") at gsignal.c:2209 #16 0xb78bc296 in IA__g_signal_emit (instance=0x1, signal_id=1, detail=1) at gsignal.c:2243 #17 0xb7def914 in gtk_widget_event_internal (widget=0x8103030, event=0x810c060) at gtkwidget.c:4242 #18 0xb7cc4bd7 in IA__gtk_propagate_event (widget=0x8103030, event=0x810c060) at gtkmain.c:2348 #19 0xb7cc4f2f in IA__gtk_main_do_event (event=0x810c060) at gtkmain.c:1582 #20 0xb7b40551 in gdk_event_dispatch (source=0x1, callback=0, user_data=0x0) at gdkevents-x11.c:2318 #21 0xb78341fc in IA__g_main_context_dispatch (context=0x8066cc8) at gmain.c:2045 #22 0xb7835bb5 in g_main_context_iterate (context=0x8066cc8, block=1, dispatch=1, self=0x80690e0) at gmain.c:2677 #23 0xb7835eda in IA__g_main_loop_run (loop=0x8062200) at gmain.c:2881 #24 0xb7cc41b3 in IA__gtk_main () at gtkmain.c:1155 #25 0x0804a669 in main (argc=1, argv=0xbfac7224) at main.c:108
On top of the backtrace list are functions that were called last, and on the bottom of the list are the applicationsmain()
function and then thegtk_main()
, etc. - If you now continued debugging with
s
(step) command, you would end up looping the gtk main event loop. However, it is better to just give thec
(continue) command:(gdb) c Continuing.
- Now the maemopad application is running. If you select
the
HELP
menu item again, the breakpoint is still set. So if you clickHELP
you would get again:Breakpoint 1, callback_help (action=0x80bda40, data=0x806ec78) at ui/callbacks.c:296 296 { (gdb)
- You can clear a specific breakpoint using the clear
command. Remove the breakpoint in
callback_help()
function:(gdb) clear callback_help Deleted breakpoint 1 (gdb) c Continuing.
- Because the breakpoint is now cleared, you can use the
application normally under the
Xephyr
.
Debugging Hildon Desktop Plug-ins
This section explains how to debug Hildon Desktop plug-ins in maemo environment.
Desktop and Control Panel applications are both launched by
the maemo-launcher daemon. Their plug-ins are all shared
libraries (i.e. .so
files). Writing these plug-ins
is explained in the maemo document How to Write Hildon
Desktop Plug-ins for Maemo.
Downloading and Compiling the Example Apps
For this example, you need to first download, compile and
install the hello-world-app
package.
- Download the source package of hello-world-app:
[sbox-CHINOOK_X86: ~/src] > apt-get source hello-world-app Reading package lists... Done Building dependency tree... Done Need to get 235kB of source archives. Get:1 http://repository.maemo.org chinook/free hello-world-app 0.7 (dsc) [363B] Get:2 http://repository.maemo.org chinook/free hello-world-app 0.7 (tar) [235kB] Fetched 235kB in 0s (264kB/s) dpkg-source: warning: extracting unsigned source package (./hello-world-app_0.7.dsc) dpkg-source: extracting hello-world-app in hello-world-app-0.7 dpkg-source: unpacking hello-world-app_0.7.tar.gz
- Go to the sources directory ...
[sbox-CHINOOK_X86: ~/src] > cd hello-world-app-0.7 [sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] >
- ... and compile it like this:
[sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] > export DEB_BUILD_OPTIONS=debug,nostrip [sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] > ./autogen.sh ... etc ... [sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] > dpkg-buildpackage -rfakeroot dpkg-buildpackage: source package is hello-world-app dpkg-buildpackage: source version is 0.7 dpkg-buildpackage: source changed by Maemo Integration <integration@maemo.org> dpkg-buildpackage: host architecture i386 dpkg-buildpackage: source version without epoch 0.7 dpkg-checkbuilddeps: Using Scratchbox tools to satisfy builddeps fakeroot debian/rules clean dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. /scratchbox/tools/bin/make clean ... snip, output from compilation ... dpkg-genchanges: including full source code in upload dpkg-buildpackage: full upload; Debian-native package (full source is included) [sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] >
- You should now have:
[sbox-CHINOOK_X86: ~/src/hello-world-app-0.7] > cd .. [sbox-CHINOOK_X86: ~/src] > ls -lt total 312 -rw-rw-r-- 1 maemo maemo 738 Nov 14 08:27 hello-world-app_0.7_i386.changes -rw-r--r-- 1 maemo maemo 58402 Nov 14 08:27 hello-world-app_0.7_i386.deb drwxr-xr-x 5 maemo maemo 4096 Nov 14 08:27 hello-world-app-0.7 -rw-rw-r-- 1 maemo maemo 363 Nov 14 08:26 hello-world-app_0.7.dsc -rw-rw-r-- 1 maemo maemo 234825 Nov 14 08:26 hello-world-app_0.7.tar.gz
- Install the newly compiled debug version of the package
hello-world-app_0.7_i386.deb
:[sbox-CHINOOK_X86: ~/src] > fakeroot dpkg -i hello-world-app_0.7_i386.deb (Reading database ... 15186 files and directories currently installed.) Unpacking hello-world-app (from hello-world-app_0.7_i386.deb) ... ... snip ...
Now the Hildon desktop plug-ins example applications should be installed in the Scratchbox X86 target.
How to Debug Applications Started by Maemo-Launcher
Basically, these applications can be debugged by:
- attaching to an already running process
- starting the application using maemo-summoner
Attaching to Maemo-Launched Application with Gdb
With maemo-launched applications, it is necessary to give
maemo-launcher binary to gdb
and attach to the
already running process.
[sbox-CHINOOK_X86: ~/ ] > af-sb-init.sh start ... snip ... [sbox-CHINOOK_X86: ~/ ] > pidof hildon-desktop | cut -d' ' -f1 22961 # # this would take the first (largest) PID value from the returned list. The number 22961 is just an example. # smallest PID value is maemo-invoker which had requested maemo-launcher to start hildon-desktop. # [sbox-CHINOOK_X86: ~/ ] > native-gdb maemo-launcher ... snip ... (gdb) attach 22961 Attaching to program: /targets/CHINOOK_X86/usr/bin/maemo-launcher, process 22961 ... snip... (gdb)
Now it should be possible to debug the application normally with the gdb.
Starting Maemo-Launched Application with Maemo-Summoner
The following will start the Control Panel under (native)
gdb
, and the newly installed Control Panel applet
called hello-world-app
will be debugged. The
breakpoint will be set to function
hello_world_dialog_show()
. Pay attention to the
question about the "pending shared library
load"
.
[sbox-CHINOOK_X86: ~/ ] > af-sb-init.sh start ... snip ... [sbox-CHINOOK_X86: ~/ ] > run-standalone.sh native-gdb maemo-summoner ... snip ... (gdb) br hello_world_dialog_show Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (hello_world_dialog_show) pending. (gdb) run /usr/bin/controlpanel.launch Starting program: /targets/CHINOOK_X86/usr/bin/maemo-summoner /usr/bin/controlpanel.launch ... snip ...
This should start the Control Panel in the Xephyr screen. When clicking the hello world plug-in in the Control Panel, the execution should stop at the given breakpoint. Try, for example, to get a backtrace:
Breakpoint 2, hello_world_dialog_show () at libhelloworld.c:68 68 GtkWidget *dialog = hello_world_dialog_new (); (gdb) bt #0 hello_world_dialog_show () at libhelloworld.c:68 #1 0xb70b05f7 in execute (osso=0x8075948, data=0x8084088, user_activated=1) at hello-world-applet.c:11 #2 0xb7ea4a71 in hcp_app_idle_launch (d=0x810ad08) at hcp-app.c:200 #3 0xb776c4d1 in g_idle_dispatch (source=0x810ac98, callback=0x806ac70, user_data=0x8075948) at gmain.c:3928 #4 0xb77691fc in IA__g_main_context_dispatch (context=0x806dbc0) at gmain.c:2045 #5 0xb776abb5 in g_main_context_iterate (context=0x806dbc0, block=1, dispatch=1, self=0x806f228) at gmain.c:2677 #6 0xb776aeda in IA__g_main_loop_run (loop=0x80deb40) at gmain.c:2881 #7 0xb7bec1b3 in IA__gtk_main () at gtkmain.c:1155 #8 0xb7ea1e37 in main (argc=1, argv=0xbfa7d184) at hcp-main.c:64 #9 0x080489bd in ?? () #10 0x00000001 in ?? () #11 0xbfa7d184 in ?? () #12 0x0804b030 in ?? () #13 0x00000002 in ?? () #14 0x00000000 in ?? () (gdb) list 63 } 64 65 void 66 hello_world_dialog_show () 67 { 68 GtkWidget *dialog = hello_world_dialog_new (); 69 gtk_dialog_run (dialog); 70 gtk_widget_destroy (dialog); 71 } 72 (gdb) c Continuing.
The question marks are shown because there are no debug
symbols for maemo-summoner (no debug package was installed for
that). The backtrace tells what functions were called before
the breakpoint was reached at
hello_world_dialog_show()
. Now the plug-in can be
debugged normally with gdb
.
Because the hello world plug-in was compiled with the
-g
option, the source code listing can be viewed
with the list
command.
To do this same for desktop, the hildon-desktop
process needs to be killed first. The desktop can be killed
with the command:
[sbox-CHINOOK_X86: ~] > kill $(pidof hildon-desktop)
#
# after this you could start the hildon-desktop under gdb
like this:
#
[sbox-CHINOOK_X86: ~] > run-standalone.sh native-gdb maemo-summoner
... snip ...
(gdb) run /usr/bin/hildon-desktop.launch
... snip ...
flasher
tool. If
this is not done, the device will reboot. The flag is:--set-rd-flags=no-lifeguard-reset
Running Out of Memory During Debugging in Device
If running out of RAM memory during debugging in the device, there are a couple of options:
- Add (more) swap to the device using the Memory applet
from the Control Panel.
If there is enough memory, but
gdb
is still abruptly terminated, you can try setting it OOM-protected asroot
:/home/user # echo -17 > /proc/[PID of your gdb]/oom_adj
By default, processes have OOM (i.e. Out-of-Memory) adjustment value of zero. The value
-17
disables the kernel OOM killing for the given process. N.B. As a result of this, some other processes might be killed by the kernel. - Use
gdbserver
to debug
Notes on using gdbserver
Gdbserver
is a debugging tool that can be
started and run in the Internet Tablet device. Then a
connection can be made to this running instance of
gdbserver
program from a Linux PC with a
gdb
program. Gdbserver
uses a lot
less memory than a full scale gdb
program, thus
making it possible to perform debugging in devices that have a
limited RAM memory, such as PDAs.
The gdbserver
does not care about symbols in
the binary, but instead the Linux PC side gdb
expects to have a local copy of the binary being debugged so
that the binaries in the device can be stripped.
Gdbserver
has the same issues as with
debugging core files from the device in Scratchbox. In
practice, it is easier to perform the debugging in the
device itself. See the section above about pre-linked
binaries and libraries.
For further information about using gdbserver,
gdb
and DDD, see:
Valgrind Debugger
Introduction to Valgrind Tool
Valgrind is a CPU simulator with different debugging and analyzing plug-ins. The Valgrind plug-ins are:
memcheck
This plug-in tool is used to debug memory leaks and deallocation errors in applications. The following example will mainly focus on this.massif
This plug-in produces PostScript graph of process memory usage as a function of time. This also produces an ASCII or HTML report of allocation backtraces.callgrind
This can be used for profiling performance and getting call traces from programs. These can be further visualized with theKcachegrind
tool.helgrind
This helps in finding race conditions in threaded programs. This does not work in maemo Valgrind. It works only with Valgrind 2.2.
Valgrind has many options, but only the basic ones are covered here with examples. The link to the full Valgrind manual is given at the end of this section.
Installing Valgrind Tool
Installing Valgrind is simple. Log in on Scratchbox and run the following commands:
- Get Valgrind from the repository:
[sbox-CHINOOK_ARMEL: ~] > sb-conf select CHINOOK_X86 ... Setting up valgrind (3.2.3-1.osso1) ... [sbox-CHINOOK_X86: ~] >
N.B.The maemo Valgrind version depends on the libc6-dbg. On the desktop Linux, some of the debug symbols are included in the libc6 library itself. If the debug symbols are missing from the libraries, Valgrind cannot match the error suppressions to the internal library functions. In the maemo libc6 case, it would show lots of errors for the dynamic linker.
If using a non-maemo version of Valgrind, the following environment variable needs to be set before valgrinding programs using Glib:
[sbox-CHINOOK_X86: ~] > export G_SLICE="always-malloc"
Without this, Valgrind will report bogus leaks from Glib.
- Get the two small example applications written in C
language to demonstrate the basic usage of valgrind tool. You
can download these from maemo.org:
valgrind_example.tar.gz
.[sbox-CHINOOK_X86: ~] > mkdir src [sbox-CHINOOK_X86: ~] > cd src [sbox-CHINOOK_X86: ~/src] >
After downloading, just copy the
valgrind_example.tar.gz
file to the~/src/
directory and perform the following:[sbox-CHINOOK_X86: ~/src] > tar xvzf valgrind_example.tar.gz valgrind_example/ valgrind_example/valgrind_example.c valgrind_example/valgrind_example2.c [sbox-CHINOOK_X86: ~/src] > cd valgrind_example [sbox-CHINOOK_X86: ~/src/valgrind_example] >
-
Compile the two small example applications in the following way:
[sbox-CHINOOK_X86: ~/src/valgrind_example] > gcc valgrind_example.c -o valgrind_example -g [sbox-CHINOOK_X86: ~/src/valgrind_example] > gcc valgrind_example2.c -o valgrind_example2 -g
You are now ready to move the next section.
Using Valgrind Memory Debugger Tool
After compiling the small example application, it can be run under valgrind with the command:
[sbox-CHINOOK_X86: ~/src/valgrind_example] > valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \ --num-callers=20 --track-fds=yes ./valgrind_example
Explanation of the parameters and their meanings:
-
--tool=memcheck
Defines which tool Valgrind should use. In this example, the memory checker tool is used.
-
--leak-check=yes
With this option, Valgrind checks the code for potential memory leaks.
-
--show-reachable=yes
This option creates a stack trace of the creation of the reachable but unfreed memory when the program exits.
-
--num-callers=20
With this option, the number of function call levels that Valgrind displays can be changed. The default value is 12. Giving higher number takes a bit more memory. It is advisable to tune this option, because for example the gtk callstack can consist of more than 100 items.
-
--track-fds=yes
Track-fds
meansTrack FileDescriptors
. If the application is opening and closing files withfopen()
oropen()
, this will report which files are not closed.
The output of the example application should look like:
==4493== Memcheck, a memory error detector. ==4493== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==4493== Using LibVEX rev 1732, a library for dynamic binary translation. ==4493== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==4493== Using valgrind-3.2.3-Debian, a dynamic binary instrumentation framework. ==4493== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==4493== For more details, rerun with: -v ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400A970: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x40033B3: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400A99C: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x40033B3: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400AFF3: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x40033B3: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400A825: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4003448: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400A86C: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4003448: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== Conditional jump or move depends on uninitialised value(s) ==4493== at 0x400A99C: _dl_relocate_object (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4003448: dl_main (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4012C29: _dl_sysdep_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x400193F: _dl_start (in /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== by 0x4000846: (within /targets/CHINOOK_X86/lib/ld-2.5.so) ==4493== ==4493== FILE DESCRIPTORS: 3 open at exit. ==4493== Open file descriptor 2: /dev/pts/2 ==4493== <inherited from parent> ==4493== ==4493== Open file descriptor 1: /dev/pts/2 ==4493== <inherited from parent> ==4493== ==4493== Open file descriptor 0: /dev/pts/2 ==4493== <inherited from parent> ==4493== ==4493== ==4493== ERROR SUMMARY: 11 errors from 6 contexts (suppressed: 0 from 0) ==4493== malloc/free: in use at exit: 40 bytes in 2 blocks. ==4493== malloc/free: 3 allocs, 1 frees, 60 bytes allocated. ==4493== For counts of detected errors, rerun with: -v ==4493== searching for pointers to 2 not-freed blocks. ==4493== checked 56,760 bytes. ==4493== ==4493== ==4493== 10 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==4493== at 0x4020626: malloc (vg_replace_malloc.c:149) ==4493== by 0x804841B: main (valgrind_example.c:26) ==4493== ==4493== ==4493== 30 bytes in 1 blocks are definitely lost in loss record 2 of 2 ==4493== at 0x4020626: malloc (vg_replace_malloc.c:149) ==4493== by 0x8048482: main (valgrind_example.c:48) ==4493== ==4493== LEAK SUMMARY: ==4493== definitely lost: 40 bytes in 2 blocks. ==4493== possibly lost: 0 bytes in 0 blocks. ==4493== still reachable: 0 bytes in 0 blocks. ==4493== suppressed: 0 bytes in 0 blocks. [sbox-CHINOOK_X86: ~/src/valgrind_example] >
The output of the Valgrind tells that there were 40 unallocated bytes for the application ("definitely lost"). This means that the example application is leaking memory, and cannot free it anymore. This means that the code should be studied closely.
Valgrind also tells the lines in the code where these allocations that are not freed are performed. In this example, the lines in question are 41 and 19.
Official Valgrind Manual
Valgrind.org has an official Valgrind manual available in the Internet, explaining the many options and debugging practices that Valgrind can support. For full coverage of Valgrind see:
Other Debugging Tools
The SDK provides a number of other tools that are useful in debugging. See the linked documentation pages to learn more about them.
- strace - a system call tracer. Print out all the system calls made by the traced process.
- ltrace - a library call tracer. Print out all library calls made by the traced process.
- sp-rich-core - produce rich cores that will provide a snapshot of the system's state at the time of the crash in addition to the core dump file.
- syslog - a logging system that can collect logs in a centralized way.
Please also have a look at the tools main page http://maemo.org/development/tools/ for even more tools that could be useful for you.
Code Examples
Here are the two example code packages that were used in this text.
Improve this page