References:
Gdbserver debugging shared library http://www.limodev.cn/blog/archives/393
Android C/C ++ program debugging (eclipse) http://xy0811.spaces.live.com/blog/cns! F8aecd2a067a6b17! 1480. Entry #
Reference Code: (see the bottom of the file content)
~ /Mydroid/android-1.6_r2/development/self/helloworld/Android. mk
~ /Mydroid/android-1.6_r2/development/self/helloworld. c
~ /Mydroid/android-1.6_r2/development/self/libtest/Android. mk
~ /Mydroid/android-1.6_r2/development/self/libtest. h
~ /Mydroid/android-1.6_r2/development/self/libtest. c
Platform used:
System Platform: ubuntu10.4 lts
Source code version: Android 1.6r2
Emulator platform: Android 1.6 (the SDK is android2.2, which does not matter)
Note: Android compilation is skipped. The compilation target is the default generic release version. If you need to debug the built-in programs such as dalvikvm, it is best to compile the debug version.
(The following default shell has run $ source build/envsetup. Sh)
The command to change the debug version is:
$ Tapas
(Select device debug generic ENG)
(TIPS: run the "Lunch 2" command to change the android compilation target to a host Program. The compiled dalvikvm can be run directly in Ubuntu, which is useful in some cases)
0. Preparations
Start the simulator
$ Emulator-AVD
Aaa
Run the following command in the root directory of the android source code:
$ Source
Build/
Envsetup. Sh
1. Use the execution files helloworld and libtest. So that are not strip versions.
Run the following commands in the root directory of the android source code:
$ Make
Libtest
$ Make
Helloworld
The location of versions not strip is
~ /Mydroid/android-1.6_r2/out/target/product/generic/symbols/system/bin/helloworld
~ /Mydroid/android-1.6_r2/out/target/product/generic/symbols/system/lib/libtest. So
Push helloworld to the/data/bin/directory and libtest. So to the/system/lib/directory.
$ ADB push ~ /
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
Bin/
Helloworld/
Data/
Bin/
$ ADB remount
$ ADB push ~ /
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
LIB/
Libtest. So/
System/
LIB/
2. Start gdbserver
Android 1. 6 simulator comes with the gdbserver program. Execute the following command in Android simulator:
# GDB
Server: 1234/data/bin/helloworld
If it is normal, the result should be: (if it is abnormal, check it by yourself)
Process/data/bin/helloworld created; pid = 206
Listening on port 1234
Do not forget the PID above.
3. Start arm-Eabi-GDB to debug the connection.
3.1 first set the simulator port forwarding:
$ ADB forward TCP: 1234
TCP/IP: 1234
3.2 start arm-Eabi-GDB:
(There are corresponding files in the prebuild directory of the android source code, and there are multiple versions. No difference is found. I use 4.4)
(2010/08/05 +:
You can use arm-Eabi-gdbtui for debugging, but the up and down arrow keys are used to control source code display. In addition,
Some programs do not need to debug the dynamic link library in step 1. I don't know why, but I need to call the two commands related to set solib in GDB (refer to section 5th ), in addition, it is an absolute path. In fact, it is ineffective to use relative paths. You can use N when debugging the dynamic link library. Although the Code position is displayed everywhere, it is correct in key functions .)
$ ~ /
Mydroid/
Android 1.6
_ R2/
Prebuilt/
Linux-x86/
Toolchain/
Arm-eabi-4.4.0/
Bin/
Arm-Eabi-GDB ~ /
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
Bin/
Helloworld
After startup, the following information is displayed:
Gnu gdb 6.6
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 "-- Host = i686-pc-linux-gnu -- target = arm-elf-Linux "...
3.3 First, execute the two commands set solib-××:
(Optional. It does not work if you only debug helloworld and its dynamic libraries. It is best to use an absolute path. It may not work if you use an auto-scaling method)
(
GDB
)
Set
Solib-absolute-Prefix/
Home/
J/
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
(
GDB
)
Set
Solib-search-path/
Home/
J/
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
LIB/
3.4 connect to gdbserver for debugging:
(
GDB
)
Target remote: 1234
If it succeeds, the following information is displayed:
_ DL _ start () at bionic/linker/ARCH/ARM/begin. S: 35
35 mov r0, SP
Current language: auto; currently ASM
If the two commands set solib-××× are not executed, the following information is displayed, but it does not matter.
Warning: unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
And track explicitly loaded dynamic code.
0xb0000100 in ?? ()
4. debug GDB
First, execute two commands:
(
GDB
)
B Main
(
GDB
)
C
The debugging will stop at the main function of helloworld. C, and the prompt is as follows:
Continuing.
Error while mapping shared library sections:
Libc. So: no such file or directory.
Error while mapping shared library sections:
Libstdc ++. So: no such file or directory.
Error while mapping shared library sections:
Libm. So: no such file or directory.
Error while mapping shared library sections:
Libtest. So: no such file or directory.
Breakpoint 1, main ()
At/home/J/mydroid/android-1.6_r2/development/self/helloworld. C: 6
6 printf ("Main 1 ");
Current language: auto; currently C
The last few lines indicate that debugging is normal. If you compile the debug version of Android, the first few lines will show that the dynamic library is successfully loaded, but you cannot directly access the dynamic link library for debugging. :) At least I cannot.
(2010/08/05 +: at this time, you can use info share to determine. Run the info share command to display the memory address loaded by the current dynamic link library. If the address displayed is the same as the address obtained in section 5th, You can debug the dynamic link library, in addition, you can use the N command. If not, try section 5th .)
In this case, you can debug through the Basic GDB debugging command:
(
GDB
)
N (
Execute the next one)
(
GDB
)
B 10
(In 10th
Line breakpoint)
(
GDB
)
List (display source code information)
(
GDB
)
C (continue to the next breakpoint or end)
(Note: I don't know much about GDB debugging, but Google is better)
If you execute the S command at func () to enter the func () function body, an error is prompted and debugging cannot be performed properly. For more information, see-
5. Load the dynamic library so file for debugging
For this part of work, refer to the gdbserver shared library debugging article, but I will repeat the steps on the Android platform:
5.1 view the memory address loaded by the dynamic link library
$ ADB shell cat
/
Proc/
206
/
Maps
The result contains the following rows:
20179000-0000a000 rwxp 00001000 1f: 01 712/data/bin/helloworld
40000000-40008000 R-xs 00000000 07 186/dev/ashmem/system_properties (Deleted)
80000000-80001000 R-XP 00000000 1f: 00 713/system/lib/libtest. So
80001000-80002000 rwxp 00001000 1f: 00 713/system/lib/libtest. So
Afc00000-afc21000 R-XP 00000000 1f: 00 478/system/lib/libm. So
Record the address 80000000.
5.2 view the offset of the text segment in the dynamic link library libtest. So.
Address
$ ./
Prebuilt/
Linux-x86/
Toolchain/
Arm-eabi-4.4.0/
Bin/
Arm-Eabi-objdump-H
~ /
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
LIB/
Libtest. So |
Grep
. Text
The result is displayed as follows:
5. Text 00000034 00000344 00000344 2 ** 2
Record the 00000344 address.
5.3 load the dynamic link library in GDB
Run the following command on the gdb command line: (0x80000344 is 80000000 + 00000344 = 80000344)
(
GDB
)
Add-symbol-file/
Home/
J/
Mydroid/
Android 1.6
_ R2/
Out/
Target/
Product/
Generic/
Symbols/
System/
LIB/
Libtest. So 0x80000344
5.4 go to the dynamic link library for debugging
There are two ways to debug the Dynamic Link Library:
5.4.1 run the S command to enter
Set the breakpoint at the point where the func () function is called:
(
GDB
)
B 10
(
GDB
)
C
When debugging stops at the tenth line of helloworld. C, run the S command:
Breakpoint 2, main ()
At/home/J/mydroid/android-1.6_r2/development/self/helloworld. C: 10
10 func ();
(
GDB
)
S
The libtest. C code is displayed. Run the LIST command to view the Code:
Func () at/home/J/mydroid/android-1.6_r2/development/self/libtest. C: 3
3 void func (){
(
GDB
)
List
1 # include "stdio. H"
2 # include "libtest. H"
3 void func (){
4 printf ("libtest 1 ");
5 printf ("Hello, this is a function in libtest! ");
6 printf ("libtest 2 ");
7}
5.4.2 access through breakpoint setting
Set the breakpoint in libtest. C:
(
GDB
)
B libtest. C: 5 breakpoint 3 at 0x80000352: File/home/J/mydroid/android-1.6_r2/development/self/libtest. C, line 5 .(
GDB
)
Ccontinuing.
Breakpoint 3, func ()
At/home/J/mydroid/android-1.6_r2/development/self/libtest. C: 5
5 printf ("Hello, this is a function in libtes
T !");
In this way, you can debug the dynamic link library.
Note: during use, I cannot use the N command when entering the dynamic link library for debugging. You can use commands such as C finish B.
The following two pages have improved debugging:
Debug the shared library http://blog.csdn.net/absurd/archive/2007/09/20/1793646.aspx with gdbserver
Gdbserver debug shared library (final) http://www.limodev.cn/blog/archives/477
Attached file content:
./Helloworld/Android. mk
1 2 3 4 5 6 7 8 9 10 11 12 |
Local_path: = $ ( Call My- DIR)
Include $ ( Clear_vars ) Local_src_files: = / Helloworld. C Local_module: = Helloworld Local_shared_libraries + = / Libtest Include $ ( Build_executable ) |
./Helloworld. c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Include "stdio. H"
# Include "../libtest. H" Int Main ( )
{
Printf
( "Main 1" ) ;
Int A = 10 ;
While ( A -- ) {
Printf
( "While 1" ) ;
Func ( ) ;
Printf
( "While 2" ) ;
} ;
Printf
( "Hello Android/n " ) ;
Printf
( "Main 2" ) ;
} |
./Libtest/Android. mk
1 2 3 4 5 6 7 8 9 10 11 |
Local_path: = $ ( Call My- DIR)
Include $ ( Clear_vars ) Local_prelink_module: = False Local_src_files: = / Libtest. C Local_module: = Libtest Include $ ( Build_shared_library ) |
./Libtest. h
./Libtest.
C
1 2 3 4 5 6 7 |
# Include "stdio. H"
# Include "libtest. H"
Void Func ( ) {
Printf
( "Libtest 1" ) ;
Printf
( "Hello, this is a function in libtest! " ) ;
Printf
( "Libtest 2" ) ;
} |