Difference between revisions of "EBC Exercise 28 Remote gdb and more"
(→strace: Added info) |
m (→Eclipse, gdb and remote debugging: Added) |
||
(18 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:ECE497]] | [[Category:ECE497]] | ||
+ | {{YoderHead}} | ||
− | + | 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 === |
− | + | You should already have this, but if not. On your host computer run: | |
− | gdb | + | host$ '''apt-get install gdb''' |
− | + | On your Beagle run: | |
− | |||
− | |||
− | |||
− | + | beagle$ '''opkg install gdb gdbserver''' | |
− | + | === The Sample Program === | |
− | + | You can get the sample program via git on both your host and Beagle. | |
− | + | host$ '''git clone git@github.com:MarkAYoder/BeagleBoard-exercises.git exercises''' | |
− | + | beagle$ '''git clone git@github.com:MarkAYoder/BeagleBoard-exercises.git exercises''' | |
− | $ | + | |
− | + | host$ '''cd exerciese/gdbExample''' | |
− | + | host$ '''gedit Makefile''' | |
− | |||
− | $ | ||
− | |||
− | + | 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.) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | 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: | ||
− | + | beagle$ '''gdb cfft_arm''' | |
− | $ gdb cfft_arm | + | GNU gdb (GDB) 7.2 |
− | + | Copyright (C) 2010 Free Software Foundation, Inc. | |
− | GNU gdb (GDB) 7. | + | 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 () | ||
− | |||
− | |||
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. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | (gdb) '''l''' | |
− | + | 42 } | |
− | + | 43 | |
− | + | 44 static complex *new_complex_vector(int size); | |
− | + | 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 | ||
− | |||
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. | ||
− | |||
− | (gdb) s | + | (gdb) '''s''' |
− | fft_init (N=16) at cfft.c:33 | + | fft_init (N=16) at cfft.c:33 |
− | |||
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; |
− | + | ||
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. | ||
− | + | === gdb and core files === | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | 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. | |
+ | On the Beagle: | ||
− | + | beagle $ '''./cfft_arm''' | |
− | + | Floating point exception | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
Let the Beagle write a core file and see how gdb can use it | Let the Beagle write a core file and see how gdb can use it | ||
− | + | ||
− | $ ulimit -c unlimited | + | beagle$ '''ulimit -c unlimited''' |
− | $ ./cfft_arm | + | beagle$ '''./cfft_arm''' |
Floating point exception (core dumped) | Floating point exception (core dumped) | ||
− | $ gdb ./cfft_arm core | + | beagle$ '''gdb ./cfft_arm core''' |
− | GNU gdb (GDB) 7. | + | GNU gdb (GDB) 7.2 |
− | Copyright (C) 2010 Free Software Foundation, Inc. | + | Copyright (C) 2010 Free Software Foundation, Inc. |
− | License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> | + | 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. | + | 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" | + | There is NO WARRANTY, to the extent permitted by law. Type "show copying" |
− | and "show warranty" for details. | + | and "show warranty" for details. |
− | This GDB was configured as "arm-angstrom-linux-gnueabi". | + | This GDB was configured as "arm-angstrom-linux-gnueabi". |
− | For bug reporting instructions, please see: | + | For bug reporting instructions, please see: |
− | <http://www.gnu.org/software/gdb/bugs/>... | + | <http://www.gnu.org/software/gdb/bugs/>... |
− | Reading symbols from /home/root/gdbExample/cfft_arm...done. | + | Reading symbols from /home/root/exercises/gdbExample/cfft_arm...done. |
− | [New Thread | + | [New Thread 30777] |
− | Reading symbols from /lib/libm.so.6... | + | Reading symbols from /lib/libm.so.6...Reading symbols from /lib/.debug/libm-2.9.so...done. |
− | Loaded symbols for /lib/libm.so.6 | + | done. |
− | Reading symbols from /lib/libc.so.6... | + | Loaded symbols for /lib/libm.so.6 |
− | Loaded symbols for /lib/libc.so.6 | + | Reading symbols from /lib/libc.so.6...Reading symbols from /lib/.debug/libc-2.9.so...done. |
− | Reading symbols from /lib/ld-linux.so.3... | + | done. |
− | Loaded symbols for /lib/ld-linux.so.3 | + | Loaded symbols for /lib/libc.so.6 |
− | Core was generated by `./cfft_arm'. | + | Reading symbols from /lib/ld-linux.so.3...Reading symbols from /lib/.debug/ld-2.9.so...done. |
− | Program terminated with signal 8, Arithmetic exception. | + | done. |
− | #0 0x400c35fc in raise () from /lib/libc.so.6 | + | Loaded symbols for /lib/ld-linux.so.3 |
− | (gdb) bt | + | Core was generated by `./cfft_arm'. |
− | #0 0x400c35fc in raise () from /lib/libc.so.6 | + | Program terminated with signal 8, Arithmetic exception. |
− | #1 0x00009abc in __div0 () | + | #0 0x400c35fc in raise () from /lib/libc.so.6 |
− | + | (gdb) '''bt''' | |
− | #2 0x00008c80 in __udivsi3 () | + | #0 0x400c35fc in raise () from /lib/libc.so.6 |
− | + | #1 0x00009abc in __div0 () | |
− | #3 0x00008888 in fft_exec (N=16, in=0x12090) at cfft.c:87 | + | 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 |
− | #4 0x0000868c in main () at main_cfft.c:62 | + | #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 | |
− | gdb tells you right where the error | + | #3 0x00008888 in fft_exec (N=16, in=0x12090) at cfft.c:87 |
− | + | #4 0x0000868c in main () at main_cfft.c:62 | |
− | (gdb) list fft_exec | + | |
− | 67 free (bndx); | + | gdb tells you right where the error occurred. You can even ask it to list the file. |
− | 68 free (tableW); | + | |
− | 69 } | + | (gdb) '''list fft_exec''' |
− | 70 | + | 67 free (bndx); |
− | 71 void fft_exec (int N, complex * in) | + | 68 free (tableW); |
− | 72 { | + | 69 } |
− | 73 unsigned int n = N; | + | 70 |
− | 74 unsigned int a, b, i, j, k, r, s; | + | 71 void fft_exec (int N, complex * in) |
− | 75 complex w, p; | + | 72 { |
− | 76 | + | 73 unsigned int n = N; |
− | (gdb) l 87 | + | 74 unsigned int a, b, i, j, k, r, s; |
− | 82 w = tableW[k]; | + | 75 complex w, p; |
− | 83 | + | 76 |
− | 84 r = 2 * n * k; | + | (gdb) '''l 87''' |
− | 85 s = n * (1 + 2 * k); | + | 82 w = tableW[k]; |
− | 86 | + | 83 |
− | 87 for (j = 0; j < n; j++) | + | 84 r = 2 * n * k; |
− | 88 { | + | 85 s = n * (1 + 2 * k); |
− | 89 a = j + r/0; // An error | + | 86 |
− | 90 b = j + s; | + | 87 for (j = 0; j < n; j++) |
− | 91 cmult (p, w, in[b]); //6 flop | + | 88 { |
− | + | 89 a = j + r/0; // An error | |
+ | 90 b = j + s; | ||
+ | 91 cmult (p, w, in[b]); //6 flop | ||
=== Remote gdb === | === 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. | 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. | ||
− | + | ||
− | $ source ~/.oe/environment- | + | host$ '''source ~/.oe/environment-oecore''' |
− | $ bitbake gdb-cross | + | host$ '''bitbake gdb-cross''' |
− | + | ||
− | The bitbake took about | + | The bitbake took about 2.5 minutes. |
On your Beagle run: | On your Beagle run: | ||
− | + | ||
− | $ gdbserver localhost:2001 ./cfft_arm | + | beagle$ '''gdbserver localhost:2001 ./cfft_arm''' |
− | + | ||
On your host run: | On your host run: | ||
− | + | ||
− | $ source ~/ | + | host$ '''source ~/.oe/crossCompileEnv.sh''' |
− | $ ${CROSS_COMPILE}gdb ./cfft_arm | + | host$ '''${CROSS_COMPILE}gdb ./cfft_arm''' |
− | GNU gdb (GDB) 7.1 | + | GNU gdb (GDB) 7.1 |
− | Copyright (C) 2010 Free Software Foundation, Inc. | + | Copyright (C) 2010 Free Software Foundation, Inc. |
− | License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> | + | 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. | + | 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" | + | There is NO WARRANTY, to the extent permitted by law. Type "show copying" |
− | and "show warranty" for details. | + | and "show warranty" for details. |
− | This GDB was configured as "--host=i686-linux --target=arm-angstrom-linux-gnueabi". | + | This GDB was configured as "--host=i686-linux --target=arm-angstrom-linux-gnueabi". |
− | For bug reporting instructions, please see: | + | For bug reporting instructions, please see: |
− | <http://www.gnu.org/software/gdb/bugs/>... | + | <http://www.gnu.org/software/gdb/bugs/>... |
− | Reading symbols from /home/yoder/BeagleBoard/gdbExample/cfft_arm...done. | + | Reading symbols from /home/yoder/BeagleBoard/gdbExample/cfft_arm...done. |
− | + | ||
Notice the line that says <code>This GDB was configured as "--host=i686-linux --target=arm-angstrom-linux-gnueabi"</code>, this tells us we have the right version of gdb. | Notice the line that says <code>This GDB was configured as "--host=i686-linux --target=arm-angstrom-linux-gnueabi"</code>, this tells us we have the right version of gdb. | ||
Now remotely connect to your Beagle: | Now remotely connect to your Beagle: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Breakpoint 1, main () at main_cfft.c:47 | + | (gdb) '''target remote beagle:2001''' |
− | 47 { | + | Remote debugging using beagle:2001 |
− | (gdb) l | + | warning: Unable to find dynamic linker breakpoint function. |
− | 42 } | + | GDB will be unable to debug shared library initializers |
− | 43 | + | and track explicitly loaded dynamic code. |
− | 44 static complex *new_complex_vector(int size); | + | 0x400007f0 in ?? () |
− | 45 | + | (gdb) '''b main''' |
− | 46 int main () | + | Cannot access memory at address 0x0 |
− | 47 { | + | Breakpoint 1 at 0x8590: file main_cfft.c, line 47. |
− | 48 int i; | + | (gdb) '''c''' |
− | 49 int N, n; | + | Continuing. |
− | 50 int nTimes; | + | warning: `/lib/libm.so.6': Shared library architecture unknown is not compatible with target architecture arm. |
− | 51 float secs; | + | warning: .dynamic section for "/lib/libm.so.6" is not at the expected address (wrong library or version mismatch?) |
− | (gdb) n | + | warning: `/lib/libc.so.6': Shared library architecture unknown is not compatible with target architecture arm. |
− | 56 complex *in = new_complex_vector(N); | + | warning: .dynamic section for "/lib/libc.so.6" is not at the expected address (wrong library or version mismatch?) |
− | (gdb) b fft_exec | + | Error while mapping shared library sections: |
− | Breakpoint 2 at 0x87d4: file cfft.c, line 77. | + | /lib/ld-linux.so.3: No such file or directory. |
− | (gdb) c | + | |
− | Continuing. | + | 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: | 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: | ||
− | + | ||
− | $ ls -l cfft_arm | + | beagle$ '''ls -l cfft_arm''' |
− | $ file cfft_arm | + | beagle$ '''file cfft_arm''' |
− | $ strip cfft_arm | + | beagle$ '''strip cfft_arm''' |
− | $ ls -l cfft_arm | + | beagle$ '''ls -l cfft_arm''' |
− | $ file cfft_arm | + | beagle$ '''file cfft_arm''' |
− | $ gdbserver locatl:2001 ./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. | Mine went from about 26k to 8k when the symbols are removed, but it debugs just like before. | ||
+ | |||
+ | == Eclipse, gdb and remote debugging == | ||
+ | |||
+ | [http://www.eclipse.org/ Eclipse] is an integrated development environment (IDE) that runs on many platforms, OSes, and supports many languages. You can run Eclipse on your host computer and do debugging on your Beagle (bone or xM). | ||
+ | [http://www.youtube.com/watch?v=vFv_-ykLppo&list=UUf_sAmhBw7Tj7-2ujmLFoQg&index=4&feature=plcp Beaglebone: C/C++ Programming Introduction for ARM Embedded Linux] is a video that shows how to use Eclipse for remote debugging. | ||
+ | |||
+ | Have the following loaded on your host and beagle before watching the video. | ||
+ | |||
+ | [http://download.eclipse.org/tm/downloads/drops/R-3.4-201205300905/ TM Release Build: 3.4] is where you get the RSE-runtime. | ||
+ | |||
+ | host$ '''sudo apt-get update''' | ||
+ | host$ '''sudo apt-get install eclipse''' | ||
+ | host$ '''sudo apt-get install gcc-arm-linux-gnueabi''' | ||
+ | host$ '''sudo apt-get install g++-arm-linux-gnueabi''' | ||
+ | host$ '''sudo apt-get install gdb''' | ||
+ | host$ '''sudo apt-get install gdb-multiarch''' | ||
+ | |||
+ | beagle$ '''opkg update''' | ||
+ | beagle$ '''opkg install gdbserver''' | ||
== 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? | ||
− | + | ||
− | $ grep MAXPOW *.c *.h | + | host$ '''grep MAXPOW *.c *.h''' |
− | + | ||
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: | ||
− | + | ||
− | $ 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''' |
− | + | ||
You should see something like: | You should see something like: | ||
+ | |||
[[File:Cbrowser.png|200px]] | [[File:Cbrowser.png|200px]] | ||
+ | |||
Try searching for other symbols. | Try searching for other symbols. | ||
Line 373: | Line 302: | ||
'''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. | '''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. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | === | + | beagle$ '''strace httpd''' |
+ | ... | ||
+ | open("/etc/httpd.conf", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) | ||
+ | open("httpd.conf", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) | ||
+ | rt_sigaction(SIGHUP, {0x1a39c, [], SA_RESTART|0x4000000}, NULL, 8) = 0 | ||
+ | open("/dev/null", O_RDWR|O_LARGEFILE) = 4 | ||
+ | clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x4001df98) = 3595 | ||
+ | io_submit(0, 0, 0xfbad2088 <unfinished ... exit status 0> | ||
+ | Process 3594 detached | ||
− | + | {{YoderFoot}} |
Latest revision as of 08:00, 19 September 2013
Embedded Linux Class by Mark A. Yoder
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.
Contents
Installing gdb
You should already have this, but if not. On your host computer run:
host$ apt-get install gdb
On your Beagle run:
beagle$ opkg install gdb gdbserver
The Sample Program
You can get the sample program via git on both your host and Beagle.
host$ git clone git@github.com:MarkAYoder/BeagleBoard-exercises.git exercises beagle$ git clone git@github.com:MarkAYoder/BeagleBoard-exercises.git exercises host$ cd exerciese/gdbExample host$ gedit Makefile
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.
Running gdb on the Beagle
On your Beagle try:
beagle$ gdb cfft_arm GNU gdb (GDB) 7.2 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 "arm-angstrom-linux-gnueabi". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/root/exercises/gdbExample/cfft_arm...done. (gdb) b main Breakpoint 1 at 0x8554 (gdb) r Starting program: /home/root/gdbExample/cfft_arm Breakpoint 1, 0x00008554 in main ()
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.
(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) n 57 complex *out = new_complex_vector(N); (gdb) n 59 fft_init (N); (gdb) p N $1 = 16
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.
(gdb) s fft_init (N=16) at cfft.c:33
33 tableW = malloc ((N / 2) * sizeof (complex));
(gdb) l 28 29 void fft_init (int N) 30 { 31 int i, j; 32 33 tableW = malloc ((N / 2) * sizeof (complex)); 34 bndx = malloc (N * sizeof (int)); 35 ndx = malloc ((N / 2) * sizeof (int)); 36 37 ndx[0] = 0;
That's enough to get you around a bit. help will get you information about more commands. c will continue from where you stopped.
gdb and core files
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. On the Beagle:
beagle $ ./cfft_arm Floating point exception
Let the Beagle write a core file and see how gdb can use it
beagle$ ulimit -c unlimited beagle$ ./cfft_arm
Floating point exception (core dumped)
beagle$ gdb ./cfft_arm core GNU gdb (GDB) 7.2 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 "arm-angstrom-linux-gnueabi". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/root/exercises/gdbExample/cfft_arm...done. [New Thread 30777] Reading symbols from /lib/libm.so.6...Reading symbols from /lib/.debug/libm-2.9.so...done. done. Loaded symbols for /lib/libm.so.6 Reading symbols from /lib/libc.so.6...Reading symbols from /lib/.debug/libc-2.9.so...done. done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.3...Reading symbols from /lib/.debug/ld-2.9.so...done. done. Loaded symbols for /lib/ld-linux.so.3 Core was generated by `./cfft_arm'. Program terminated with signal 8, Arithmetic exception. #0 0x400c35fc in raise () from /lib/libc.so.6
(gdb) bt
#0 0x400c35fc in raise () from /lib/libc.so.6 #1 0x00009abc in __div0 () 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". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/yoder/BeagleBoard/gdbExample/cfft_arm...done.
Notice the line that says This GDB was configured as "--host=i686-linux --target=arm-angstrom-linux-gnueabi"
, this tells us we have the right version of gdb.
Now remotely connect to your Beagle:
(gdb) target remote beagle:2001 Remote debugging using beagle:2001 warning: Unable to find dynamic linker breakpoint function. GDB will be unable to debug shared library initializers and track explicitly loaded dynamic code. 0x400007f0 in ?? () (gdb) b main Cannot access memory at address 0x0 Breakpoint 1 at 0x8590: file main_cfft.c, line 47. (gdb) c Continuing. warning: `/lib/libm.so.6': Shared library architecture unknown is not compatible with target architecture arm. warning: .dynamic section for "/lib/libm.so.6" is not at the expected address (wrong library or version mismatch?) warning: `/lib/libc.so.6': Shared library architecture unknown is not compatible with target architecture arm. 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.
Eclipse, gdb and remote debugging
Eclipse is an integrated development environment (IDE) that runs on many platforms, OSes, and supports many languages. You can run Eclipse on your host computer and do debugging on your Beagle (bone or xM). Beaglebone: C/C++ Programming Introduction for ARM Embedded Linux is a video that shows how to use Eclipse for remote debugging.
Have the following loaded on your host and beagle before watching the video.
TM Release Build: 3.4 is where you get the RSE-runtime.
host$ sudo apt-get update host$ sudo apt-get install eclipse host$ sudo apt-get install gcc-arm-linux-gnueabi host$ sudo apt-get install g++-arm-linux-gnueabi host$ sudo apt-get install gdb host$ sudo apt-get install gdb-multiarch
beagle$ opkg update beagle$ opkg install gdbserver
cbrowser/cscope
When you changed the value of MAXPOW2 how did you find where it was defined?
host$ grep MAXPOW *.c *.h
works, but what if your files are spread over several directories? (Like the kernel). cbrowser and cscope can help. On the host computer try:
host$ sudo apt-get install cbrowser host$ sudo apt-get install cscope host$ cscope -b host$ cbrowser
You should see something like:
Try searching for other symbols.
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.
beagle$ strace httpd ... open("/etc/httpd.conf", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) open("httpd.conf", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory) rt_sigaction(SIGHUP, {0x1a39c, [], SA_RESTART|0x4000000}, NULL, 8) = 0 open("/dev/null", O_RDWR|O_LARGEFILE) = 4 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x4001df98) = 3595 io_submit(0, 0, 0xfbad2088 <unfinished ... exit status 0> Process 3594 detached
Embedded Linux Class by Mark A. Yoder