This is a continuation of the earlier gdb lab. In the past lab we did local execution on the BeagleBoard. Here we'll do remote execution with gdb running on your host and debugging code on your Beagle.

−

== gdb ==

+

=== Installing gdb ===

−

gdb, the [http://www.gnu.org/software/gdb/ GNU Project debugger], allows you to see what is going on ''inside'' another program while it executes -- or what another program was doing at the moment it crashed.

+

You should already have this, but if not. On your host computer run:

−

gdb can do four main kinds of things to help you catch bugs in the act:

* Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.

+

−

The program being debugged can be written in Ada, C, C++, Objective-C, Pascal (and many other languages). Those programs might be executing on the same machine as GDB (native) or on another machine (remote). GDB can run on most popular UNIX and Microsoft Windows variants.

+

beagle$ '''opkg install gdb gdbserver'''

−

For our lab we'll be using a C program and do both local execution on the BeagleBoard and remote execution with gdb running on your host and debugging code on your Beagle.

Edit the '''Makefile''' and correct '''ARM_TOOLCHAIN_PATH''' for your machine. Also search for '''install:''' and fix it for your beagle.

−

You can get the sample program from dfs.

+

host$ '''make all install'''

−

<pre>

+

This will compile the code and '''scp''' it to your Beagle. You've just compiled a program that performs a complex fft on random data. It's main purpose is to see how fast it runs on the Beagle. (In case you are interested, I added to rule so you can compile it for your host computer. Try '''make x86''' and compare the times on your host to those on the Beagle.)

−

$ sftp dfs.rose-hulman.edu

+

−

Connecting to dfs.rose-hulman.edu...

+

−

yoder@dfs.rose-hulman.edu's password:

+

−

sftp> cd users/y/yoder/shared/beagleboard

+

−

sftp> get gdbExample.tar.gz

+

−

sftp> exit

+

−

$ tar xvf gdbExample.tar.gz

+

−

gdbExample/

+

−

gdbExample/cfft.c

+

−

gdbExample/main_bench.c

+

−

gdbExample/changelog

+

−

gdbExample/distance.c

+

−

gdbExample/cfft.h

+

−

gdbExample/README

+

−

gdbExample/distance.h

+

−

gdbExample/common.h

+

−

gdbExample/Makefile

+

−

gdbExample/main_cfft.c

+

−

$ cd gdbExample

+

−

$ gedit Makefile

+

−

</pre>

+

−

Edit the '''Makefile''' and correct '''ARM_TOOLCHAIN_PATH''' for your machine. Also search for '''install:''' and fix it for your beagle.

+

−

<pre>

+

−

$ make all install

+

−

</pre>

+

−

This will compile the code and '''scp''' to your Beagle. You've just compiled a program that performs a complex fft on random data. It's main purpose is to see how fast it runs on the Beagle. (In case you are interested, I added to rule so you can compile it for your host computer. Try '''make x86''' and compare the times on your host to those on the Beagle.)

+

The program takes several seconds to run on the Beagle, so you may want to edit the code so it doesn't run so many iterations.

The program takes several seconds to run on the Beagle, so you may want to edit the code so it doesn't run so many iterations.

Line 67:

Line 36:

On your Beagle try:

On your Beagle try:

−

<pre>

+

beagle$ '''gdb cfft_arm'''

−

$ gdb cfft_arm

+

GNU gdb (GDB) 7.2

−

gdb cfft_arm

+

Copyright (C) 2010 Free Software Foundation, Inc.

−

GNU gdb (GDB) 7.1

+

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

−

Copyright (C) 2010 Free Software Foundation, Inc.

+

This is free software: you are free to change and redistribute it.

−

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

+

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

−

This is free software: you are free to change and redistribute it.

+

and "show warranty" for details.

−

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

+

This GDB was configured as "arm-angstrom-linux-gnueabi".

−

and "show warranty" for details.

+

For bug reporting instructions, please see:

−

This GDB was configured as "arm-angstrom-linux-gnueabi".

+

<http://www.gnu.org/software/gdb/bugs/>...

−

For bug reporting instructions, please see:

+

Reading symbols from /home/root/exercises/gdbExample/cfft_arm...done.

−

<http://www.gnu.org/software/gdb/bugs/>...

+

−

Reading symbols from /home/root/gdbExample/cfft_arm...done.

+

(gdb) '''b main'''

−

(gdb) b main

+

Breakpoint 1 at 0x8554

−

Breakpoint 1 at 0x8554

+

(gdb) '''r'''

−

(gdb) r

+

Starting program: /home/root/gdbExample/cfft_arm

−

Starting program: /home/root/gdbExample/cfft_arm

+

+

Breakpoint 1, 0x00008554 in main ()

−

Breakpoint 1, 0x00008554 in main ()

−

</pre>

When first starting gdb notice the line '''This GDB was configured as "arm-angstrom-linux-gnueabi'''. This is a good sign. The first command '''b main''' sets a breakpoint at '''main'''. The next command '''r'''uns to that break point. Now lets look at our code a this point. Try the list command.

When first starting gdb notice the line '''This GDB was configured as "arm-angstrom-linux-gnueabi'''. This is a good sign. The first command '''b main''' sets a breakpoint at '''main'''. The next command '''r'''uns to that break point. Now lets look at our code a this point. Try the list command.

−

<pre>

−

(gdb) l

−

1 /home/yoder/BeagleBoard/oe/build/tmp-angstrom_2008_1/work/armv7a-angstrom-linux-gnueabi/glibc-2.9-r36.3/build-arm-angstrom-linux-gnueabi/csu/crtn.S: No such file or directory.

−

in /home/yoder/BeagleBoard/oe/build/tmp-angstrom_2008_1/work/armv7a-angstrom-linux-gnueabi/glibc-2.9-r36.3/build-arm-angstrom-linux-gnueabi/csu/crtn.S

−

(gdb) quit

−

</pre>

−

Hmmm.... We have a problem. For gdb to be most useful we need to tell gcc to include debugging information. Back to your host computer and do an ls on cfft_arm and note it's size. Mine is about 18k. Next edit the '''Makefile''' and find '''ARM_CFLAGS''' and add '''-g'''. The line should look like:

−

<pre>

−

ARM_CFLAGS = $(CFLAGS) -g

−

</pre>

−

Now clean everything and remake.

−

<pre>

−

$ make clean all install

−

$ ls -l cfft_arm

−

</pre>

−

How has the size of cfft_arm changed?

−

Back to the Beagle.

+

(gdb) '''l'''

−

<pre>

+

42 }

−

$ gdp cfft_arm

+

43

−

(gdb) b main

+

44 static complex *new_complex_vector(int size);

−

(gdb) r

+

45

−

(gdb) l

+

46 int main ()

−

42 }

+

47 {

−

43

+

48 int i;

−

44 static complex *new_complex_vector(int size);

+

49 int N, n;

−

45

+

50 int nTimes;

−

46 int main ()

+

51 float secs;

−

47 {

+

(gdb) '''n'''

−

48 int i;

+

56 complex *in = new_complex_vector(N);

−

49 int N, n;

+

(gdb) '''n'''

−

50 int nTimes;

+

57 complex *out = new_complex_vector(N);

−

51 float secs;

+

(gdb) '''n'''

−

(gdb) n

+

59 fft_init (N);

−

56 complex *in = new_complex_vector(N);

+

(gdb) '''p N'''

−

(gdb) n

+

$1 = 16

−

57 complex *out = new_complex_vector(N);

+

−

(gdb) n

+

−

59 fft_init (N);

+

−

(gdb) p N

+

−

$1 = 16

+

−

</pre>

+

Now '''l''' shows the code around the breakpoint. If you aren't seeing code, be sure to '''scp''' your '''.c''' and '''.h''' files to the Beagle.

Now '''l''' shows the code around the breakpoint. If you aren't seeing code, be sure to '''scp''' your '''.c''' and '''.h''' files to the Beagle.

The '''n''' steps to the next line in the program, the '''p''' command prints the variable that is listed. Use the '''s''' command to step into a function.

The '''n''' steps to the next line in the program, the '''p''' command prints the variable that is listed. Use the '''s''' command to step into a function.

−

<pre>

−

(gdb) s

+

(gdb) '''s'''

−

fft_init (N=16) at cfft.c:33

+

fft_init (N=16) at cfft.c:33

−

warning: Source file is more recent than executable.

+

33 tableW = malloc ((N / 2) * sizeof (complex));

33 tableW = malloc ((N / 2) * sizeof (complex));

−

(gdb) l

+

(gdb) '''l'''

−

28

+

28

−

29 void fft_init (int N)

+

29 void fft_init (int N)

−

30 {

+

30 {

−

31 int i, j;

+

31 int i, j;

−

32

+

32

−

33 tableW = malloc ((N / 2) * sizeof (complex));

+

33 tableW = malloc ((N / 2) * sizeof (complex));

−

34 bndx = malloc (N * sizeof (int));

+

34 bndx = malloc (N * sizeof (int));

−

35 ndx = malloc ((N / 2) * sizeof (int));

+

35 ndx = malloc ((N / 2) * sizeof (int));

−

36

+

36

−

37 ndx[0] = 0;

+

37 ndx[0] = 0;

−

</pre>

+

That's enough to get you around a bit. '''help''' will get you information about more commands. '''c''' will continue from where you stopped.

That's enough to get you around a bit. '''help''' will get you information about more commands. '''c''' will continue from where you stopped.

−

Try this:

+

=== gdb and core files ===

−

<pre>

+

−

gdb cfft_arm

+

Sometimes you have a program that stops running expectedly. gdb can help find where it quit and why. Let's find the bug in the cfft program.

−

gdb) b fft_exec

+

On the Beagle:

−

(gdb) r

+

−

(gdb) n 4

+

beagle $ '''./cfft_arm'''

−

(gdb) l

+

Floating point exception

−

(gdb) p n

+

−

</pre>

+

Let the Beagle write a core file and see how gdb can use it

−

We're in the '''fft_exec''' routine and have '''n'''ext'ed a in a way and then printed the value of '''n'''. The '''main''' routine also has an '''n''', how do we see it's value? It's on another stack frame, so do a backtrace to see what's on the stack and then select the frame we want.

+

−

<pre>

+

beagle$ '''ulimit -c unlimited'''

−

(gdb) bt

+

beagle$ '''./cfft_arm'''

−

#0 fft_exec (N=16, in=0x12090) at cfft.c:80

+

Floating point exception (core dumped)

−

#1 0x0000865c in main () at main_cfft.c:62

+

beagle$ '''gdb ./cfft_arm core'''

−

(gdb) f 1

+

GNU gdb (GDB) 7.2

−

#1 0x0000865c in main () at main_cfft.c:62

+

Copyright (C) 2010 Free Software Foundation, Inc.

−

62 fft_exec (N, out);

+

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

−

(gdb) p n

+

This is free software: you are free to change and redistribute it.

−

$7 = <value optimized out>

+

There is NO WARRANTY, to the extent permitted by law. Type "show copying"

−

(gdb) f 0

+

and "show warranty" for details.

−

#0 fft_exec (N=16, in=0x12090) at cfft.c:80

+

This GDB was configured as "arm-angstrom-linux-gnueabi".

−

80 for (k = 0; k < i; k++)

+

For bug reporting instructions, please see:

−

(gdb) p n

+

<http://www.gnu.org/software/gdb/bugs/>...

−

$8 = 16

+

Reading symbols from /home/root/exercises/gdbExample/cfft_arm...done.

−

</pre>

+

[New Thread 30777]

−

The '''f''' command selects the frame we want to inspect. Notice in this case the value of '''n''' in '''main''' has been ''optimized out'', that means the compiler found a way to compile the code that didn't need to put '''n''' on the stack. In the '''Makefile''' you will find the '''-O3''' option will tells the compiler to optimize a lot. Try removed the '''-O3''' and remaking everything and seeing if '''n''' appears in '''main'''.

at /home/yoder/BeagleBoard/oe/build/tmp-angstrom_2008_1/work/armv7a-angstrom-linux-gnueabi/gcc-cross-4.3.3-r16.1/gcc-4.3.3/libgcc/../gcc/config/arm/lib1funcs.asm:1079

+

#2 0x00008c80 in __udivsi3 ()

+

at /home/yoder/BeagleBoard/oe/build/tmp-angstrom_2008_1/work/armv7a-angstrom-linux-gnueabi/gcc-cross-4.3.3-r16.1/gcc-4.3.3/libgcc/../gcc/config/arm/lib1funcs.asm:834

+

#3 0x00008888 in fft_exec (N=16, in=0x12090) at cfft.c:87

+

#4 0x0000868c in main () at main_cfft.c:62

+

+

gdb tells you right where the error occurred. You can even ask it to list the file.

+

+

(gdb) '''list fft_exec'''

+

67 free (bndx);

+

68 free (tableW);

+

69 }

+

70

+

71 void fft_exec (int N, complex * in)

+

72 {

+

73 unsigned int n = N;

+

74 unsigned int a, b, i, j, k, r, s;

+

75 complex w, p;

+

76

+

(gdb) '''l 87'''

+

82 w = tableW[k];

+

83

+

84 r = 2 * n * k;

+

85 s = n * (1 + 2 * k);

+

86

+

87 for (j = 0; j < n; j++)

+

88 {

+

89 a = j + r/0; // An error

+

90 b = j + s;

+

91 cmult (p, w, in[b]); //6 flop

+

+

=== Remote gdb ===

+

+

Sometimes you can't run gdb on an embedded target since it doesn't have enough resources for all of gdb. You can run gdb on your host and debug on the Beagle. You must install a version of gdb on your host that is compiled for the target.

+

+

host$ '''source ~/.oe/environment-oecore'''

+

host$ '''bitbake gdb-cross'''

+

+

The bitbake took about 2.5 minutes.

+

+

On your Beagle run:

+

+

beagle$ '''gdbserver localhost:2001 ./cfft_arm'''

+

+

On your host run:

+

+

host$ '''source ~/.oe/crossCompileEnv.sh'''

+

host$ '''${CROSS_COMPILE}gdb ./cfft_arm'''

+

GNU gdb (GDB) 7.1

+

Copyright (C) 2010 Free Software Foundation, Inc.

+

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

+

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-linux --target=arm-angstrom-linux-gnueabi".

warning: .dynamic section for "/lib/libc.so.6" is not at the expected address (wrong library or version mismatch?)

+

Error while mapping shared library sections:

+

/lib/ld-linux.so.3: No such file or directory.

+

+

Breakpoint 1, main () at main_cfft.c:47

+

47 {

+

(gdb) '''l'''

+

42 }

+

43

+

44 static complex *new_complex_vector(int size);

+

45

+

46 int main ()

+

47 {

+

48 int i;

+

49 int N, n;

+

50 int nTimes;

+

51 float secs;

+

(gdb) '''n'''

+

56 complex *in = new_complex_vector(N);

+

(gdb) '''b fft_exec'''

+

Breakpoint 2 at 0x87d4: file cfft.c, line 77.

+

(gdb) '''c'''

+

Continuing.

+

+

Breakpoint 2, fft_exec (N=16, in=0x12090) at cfft.c:77

+

77 for (i = 1; i < N; i = i * 2)

+

(gdb) '''p n'''

+

$1 = 1

+

(gdb) '''n'''

+

72 {

+

(gdb) '''n 3'''

+

80 for (k = 0; k < i; k++)

+

(gdb) '''p n'''

+

$2 = 16

+

+

And so on. The nice thing is the remote binary, cfft_arm, doesn't have to have the debugging information in it. On your Beagle try:

+

+

beagle$ '''ls -l cfft_arm'''

+

beagle$ '''file cfft_arm'''

+

beagle$ '''strip cfft_arm'''

+

beagle$ '''ls -l cfft_arm'''

+

beagle$ '''file cfft_arm'''

+

beagle$ '''gdbserver locatl:2001 ./cfft_arm'''

+

+

Mine went from about 26k to 8k when the symbols are removed, but it debugs just like before.

+

+

=== Remote via Eclipse ===

+

+

I haven't tried this yet, but [http://www.lvr.com/eclipse5.htm this] looks like a good way to setup Eclipse on your host to do remote debugging on the Beagle.

== cbrowser/cscope ==

== cbrowser/cscope ==

When you changed the value of '''MAXPOW2''' how did you find where it was defined?

When you changed the value of '''MAXPOW2''' how did you find where it was defined?

−

<pre>

+

−

$ grep MAXPOW *.c *.h

+

host$ '''grep MAXPOW *.c *.h'''

−

</pre>

+

works, but what if your files are spread over several directories? (Like the kernel). '''cbrowser''' and '''cscope''' can help. On the host computer try:

works, but what if your files are spread over several directories? (Like the kernel). '''cbrowser''' and '''cscope''' can help. On the host computer try:

−

<pre>

+

−

$ sudo apt-get install cbrowser

+

host$ '''sudo apt-get install cbrowser'''

−

$ sudo apt-get install cscope

+

host$ '''sudo apt-get install cscope'''

−

$ cscope -b

+

host$ '''cscope -b'''

−

$ cbrowser

+

host$ '''cbrowser'''

−

</pre>

+

You should see something like:

You should see something like:

−

[[File:Cbrowser.png|100px‎]]

−

== strace ==

+

[[File:Cbrowser.png|200px‎]]

−

== Binary Utilities ==

+

Try searching for other symbols.

+

+

== strace ==

−

=== readelf ===

+

'''strace''' is a nice debugging tool that shows all the system calls a program is making. The book gives some nice examples of using strace. One place I used it was to learn where httpd looked for configuration files.

Revision as of 11:35, 17 July 2012

This is a continuation of the earlier gdb lab. In the past lab we did local execution on the BeagleBoard. Here we'll do remote execution with gdb running on your host and debugging code on your Beagle.

Edit the Makefile and correct ARM_TOOLCHAIN_PATH for your machine. Also search for install: and fix it for your beagle.

host$ make all install

This will compile the code and scp it to your Beagle. You've just compiled a program that performs a complex fft on random data. It's main purpose is to see how fast it runs on the Beagle. (In case you are interested, I added to rule so you can compile it for your host computer. Try make x86 and compare the times on your host to those on the Beagle.)

The program takes several seconds to run on the Beagle, so you may want to edit the code so it doesn't run so many iterations.

When first starting gdb notice the line This GDB was configured as "arm-angstrom-linux-gnueabi. This is a good sign. The first command b main sets a breakpoint at main. The next command runs to that break point. Now lets look at our code a this point. Try the list command.

Remote gdb

Sometimes you can't run gdb on an embedded target since it doesn't have enough resources for all of gdb. You can run gdb on your host and debug on the Beagle. You must install a version of gdb on your host that is compiled for the target.

strace

strace is a nice debugging tool that shows all the system calls a program is making. The book gives some nice examples of using strace. One place I used it was to learn where httpd looked for configuration files.