使用GDB除錯Android Native 層程式碼
--------------步驟:
0. adb root
0. adb shell
0. ps | grep browser
1. gdbserver :5039 --attach pid
2. adb forward tcp:5039 tcp:5039
1. prebuilts/gcc/linux-x86/arm/arm-eabi-4.7/bin/arm-eabi-gdb out/target/product/scx35l_sp9630ea/symbols/system/bin/app_process
2. set solib-absolute-prefix out/target/product/scx35l_sp9630ea/symbols
3. set solib-search-path out/target/product/scx35l_sp9630ea/symbols/system/lib
4. target remote :5039
5. shared
android 5.0:
prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-gdb out/target/product/scx35_sp7731gea_hd/symbols/system/bin/app_process32
set solib-absolute-prefix out/target/product/scx35_sp7731gea_hd/symbols
set solib-search-path out/target/product/scx35_sp7731gea_hd/symbols/system/lib
target remote :5039
android6.0以上版本
android sharkl64
source ***
lunch ***
gdbclient app_process :539 com.android.browser
檢視彙編:
disassemble /m hanshu
set var width=47 修改變數
gdb: 修改函式返回值:
GNU gdb Fedora (6.8-37.el5)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
(gdb) b main
Breakpoint 1 at 0x80483e9: file main.c, line 14.
(gdb) r 7
Starting program: /root/program/testgdb/main 7
Breakpoint 1, main (argc=2, argv=0xbf89e694) at main.c:14
14 int input_val = 0;
(gdb) n
15 if(argc < 2)
(gdb)
20 input_val = atoi(argv[1]);
(gdb)
21 if(func1(input_val))
(gdb) s --------------要進入函式內
func1 (input=7) at main.c:6
6 if(input < 10)
(gdb) n
7 return -1;
(gdb) disassemble ---- 反編譯一下當前函式
Dump of assembler code for function func1:
0x080483b4 <func1+0>: push %ebp
0x080483b5 <func1+1>: mov %esp,%ebp
0x080483b7 <func1+3>: sub $0x4,%esp
0x080483ba <func1+6>: cmpl $0x9,0x8(%ebp)
0x080483be <func1+10>: jg 0x80483c9 <func1+21>
0x080483c0 <func1+12>: movl $0xffffffff,-0x4(%ebp)
0x080483c7 <func1+19>: jmp 0x80483d0 <func1+28>
0x080483c9 <func1+21>: movl $0x0,-0x4(%ebp)
0x080483d0 <func1+28>: mov -0x4(%ebp),%eax ---- 返回值將儲存到eax暫存器中
0x080483d3 <func1+31>: leave
0x080483d4 <func1+32>: ret
End of assembler dump.
(gdb) i r ---- 檢視當前暫存器的值,主要是eax,此時還未執行"return -1"
eax 0x7 7
ecx 0x0 0
edx 0x0 0
ebx 0x9f8ff4 10457076
esp 0xbf89e5c4 0xbf89e5c4
ebp 0xbf89e5c8 0xbf89e5c8
esi 0x8b0ca0 9112736
edi 0x0 0
eip 0x80483c0 0x80483c0 <func1+12>
eflags 0x293 [ CF AF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) n
10 }
(gdb) i r ----- 檢視當前暫存器的資訊,此時已執行"return -1",eax的值也變成了-1,函式退出後修改
eax 0xffffffff -1
ecx 0x0 0
edx 0x0 0
ebx 0x9f8ff4 10457076
esp 0xbf89e5c4 0xbf89e5c4
ebp 0xbf89e5c8 0xbf89e5c8
esi 0x8b0ca0 9112736
edi 0x0 0
eip 0x80483d3 0x80483d3 <func1+31>
eflags 0x293 [ CF AF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) set $eax = 0 ---- 通過set命令修改eax的值,與變數不同,修改暫存器的值時,需要在暫存器名稱前加'$'
(gdb) i r ---- 再次檢視eax的值,eax已變為0.
eax 0x0 0
ecx 0x0 0
edx 0x0 0
ebx 0x9f8ff4 10457076
esp 0xbf89e5c4 0xbf89e5c4
ebp 0xbf89e5c8 0xbf89e5c8
esi 0x8b0ca0 9112736
edi 0x0 0
eip 0x80483d3 0x80483d3 <func1+31>
eflags 0x293 [ CF AF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) n ---- 繼續執行程式碼,可看到程式輸出"Input numeric is bigger than 10."。我們通過修改暫存器的值,對程式程式碼的執行過程進行了控制。
main (argc=2, argv=0xbf89e694) at main.c:24
24 printf("Input numeric is bigger than 10./n");
(gdb) c
Continuing.
Input numeric is bigger than 10.
Program exited normally.
(gdb)
--------------example:
gdb 除錯:
$adb shell
看看它的process id是多少
#ps | grep browser
記住你要的pid
啟動gdbserver, 指定在哪個prot上監聽client,指定除錯哪個程序
#gdbserver :5039 --attach pid
開始cient端的工作
On your workstation, forward port 5039 to the device with adb: 不知道怎麼翻譯
開啟一個新的終端
$adb forward tcp:5039 tcp:5039
$cd ~/mydroid
找一個最新版本的arm-eabi-gdb
$find -name arm-eabi-gdb
記住path
啟動gdbclient
$/home/peipei/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-gdb /home/peipei/mydroid/out/target/product/generic/symbols/system/bin/app_process
In gdb, Tell gdb where to find the shared libraries that will get loaded:
(gdb)set solib-absolute-prefix /home/peipei/mydroid/out/target/product/generic/symbols
(gdb)set solib-search-path /home/peipei/mydroid/out/target/product/generic/symbols/system/lib
小心,路徑別寫錯,如果錯了,gdb是不會告訴你的。
另外,要注意,兩個路徑都要指向symbols目錄。
Connect to the device by issuing the gdb command:
(gdb)target remote :5039
The :5039 tells gdb to connect to the localhost port 5039, which is bridged to the device by adb.
You may need to inspire gdb to load some symbols by typing:
(gdb)shared