背景
我正在使用gdb
和gdbserver
(gdb版本7.11)调试Android(ARM)应用程序。我的主机gdb
在Windows 10上运行,而经过调试的Android是通过USB连接的Samsung Galaxy J7。
主机和目标之间的连接良好,gdb
似乎运行良好。我能够在目标/调试后的应用程序中的某个位置上设置一个断点,并使该断点被命中。
问题
碰到断点时,会观察到以下问题:
udf #16
,而不是原始指令。
udf
指令是一个'permanently UNDEFINED encoding',似乎用于实现断点捕获内部机制。执行udf #16
指令后,将引发调试器拾取的TRAP信号。ni
(下一条指令)命令一次又一次执行udf #16
指令。udf #16
指令保留在内存中。udf #16
命令。以下是敲断点之前的指令:
(gdb) x/3i 0xd04dc520
0xd04dc520: mov r0, r4
0xd04dc524: bl 0xd04d7af4 <avio_rb32>
0xd04dc528: ldr r6, [sp, #40] ; 0x28
这是命中断点后的 的样子:
(gdb) x/3i 0xd04dc520
0xd04dc520: udf #16
0xd04dc524: bl 0xd04d7af4 <avio_rb32>
0xd04dc528: ldr r6, [sp, #40] ; 0x28
gdb
调试器在命中时无法在断点处还原原始指令。搜索网络并没有发现遇到相同问题的人。
“始终插入设置断点”参数
breakpoint always-inserted [off/on]
参数的目的显然是为了精确控制调试器是否在断点处恢复指令。引用documentation:
GDB通常通过替换以下位置的程序代码来实现断点 带有特殊指令的断点地址 执行,将控制权交给调试器。默认情况下,程序代码 仅在程序恢复后才进行修改。尽快 程序停止后,GDB恢复原始指令。这种行为 防止将断点插入目标中的gdb 突然断开。但是,对于较慢的远程目标,插入和 删除断点会降低性能。此行为可以是 由以下命令控制:
始终插入断点设置
所有断点(包括用户新添加的断点)均插入 仅在恢复目标时才使用目标。所有断点都是 停止时从目标上移开。这是默认模式。
设置断点始终插入
使所有断点始终插入到目标中。如果 用户添加新的断点或更改现有的断点, 目标中的断点将立即更新。断点已删除 仅在删除断点本身时才从目标中删除。
off
的{{1}}值正是我们想要的。确实,这是发生问题时我的breakpoint always-inserted
的值(请参阅下面的可设置参数),所以奥秘不断加深。
相关信息
下面是一个编号为gdb
的会话日志,它清楚地显示了问题以及我的评论。
gdb
第2-8行:GDB版本为7.11,配置为x86_64-w64-mingw32。
第16-21行:处理SIG33和SIGSEGV信号。
第31-33行:确定libFFmpeg共享对象.text段(0xd04b2f80)的已加载地址。这使我能够计算出所需的精确指令断点地址(0xd04dc520)。
第35-38行:将指令转储到预期的断点地址及其后。
第39行:将断点1设置为0xd04dc520。
第41-44行:设置断点后,将指令转储到预期的断点地址及其后。
第48行:继续执行。
第50-68行:执行继续,与设备的交互导致命中断点。
第69行:命中了断点1。
第70-73行:在断点地址处列出指令。该指令原为1. (gdb) show version
2. GNU gdb (GDB) 7.11
3. Copyright (C) 2016 Free Software Foundation, Inc.
4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
5. This is free software: you are free to change and redistribute it.
6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
7. and "show warranty" for details.
8. This GDB was configured as "x86_64-w64-mingw32".
9. Type "show configuration" for configuration details.
10. For bug reporting instructions, please see:
11. <http://www.gnu.org/software/gdb/bugs/>.
12. Find the GDB manual and other documentation resources online at:
13. <http://www.gnu.org/software/gdb/documentation/>.
14. For help, type "help".
15. Type "apropos word" to search for commands related to "word".
16. (gdb) handle SIG33 nostop noprint
17. Signal Stop Print Pass to program Description
18. SIG33 No No Yes Real-time event 33
19. (gdb) handle SIGSEGV nostop print
20. Signal Stop Print Pass to program Description
21. SIGSEGV No Yes Yes Segmentation fault
22. (gdb) set pagination off
23. (gdb) info set
24. ...
25. (gdb) target remote :9999
26. Remote debugging using :9999
27. Reading /system/bin/app_process32 from remote target...
28. ...
29. Reading /system/bin/linker from remote target...
30. 0xf72480b0 in __epoll_pwait () from target:/system/lib/libc.so
31. (gdb) info sharedlibrary libFFmpeg
32. From To Syms Read Shared Object Library
33. 0xd04b2f80 0xd063ec98 Yes (*) target:/data/app/com.test.media/lib/arm/libFFmpeg.so
34. (*): Shared library is missing debugging information.
35. (gdb) x/3i 0xd04dc520
36. 0xd04dc520: mov r0, r4
37. 0xd04dc524: bl 0xd04d7af4 <avio_rb32>
38. 0xd04dc528: ldr r6, [sp, #40] ; 0x28
39. (gdb) b *0xd04dc520
40. Breakpoint 1 at 0xd04dc520
41. (gdb) x/3i 0xd04dc520
42. 0xd04dc520: mov r0, r4
43. 0xd04dc524: bl 0xd04d7af4 <avio_rb32>
44. 0xd04dc528: ldr r6, [sp, #40] ; 0x28
45. (gdb) info break
46. Num Type Disp Enb Address What
47. 1 breakpoint keep y 0xd04dc520
48. (gdb) c
49. Continuing.
50. [New Thread 3313.12241]
51. [New Thread 3313.12243]
52. [New Thread 3313.12257]
53. [New Thread 3313.12271]
54. [New Thread 3313.12323]
55. [New Thread 3313.12326]
56. [New Thread 3313.12335]
57. [New Thread 3313.12338]
58. [New Thread 3313.12339]
59. [New Thread 3313.12342]
60. [New Thread 3313.12343]
61. [New Thread 3313.12344]
62. [New Thread 3313.12355]
63. Reading /system/lib/libsfextcmn.so from remote target...
64. [New Thread 3313.12360]
65. Reading /system/lib/libsfextcmn.so from remote target...
66. [New Thread 3313.12409]
67. [Switching to Thread 3313.12343]
68.
69. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
70. (gdb) x/3i 0xd04dc520
71. => 0xd04dc520: udf #16
72. 0xd04dc524: bl 0xd04d7af4 <avio_rb32>
73. 0xd04dc528: ldr r6, [sp, #40] ; 0x28
74. (gdb) ni
75.
76. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
77. (gdb) info reg pc
78. pc 0xd04dc520 0xd04dc520
79. (gdb) x/i $pc
80. => 0xd04dc520: udf #16
81. (gdb) ni
82.
83. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
84. (gdb) ni
85.
86. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
87. (gdb) ni
88.
89. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
90. (gdb) c
91. Continuing.
92.
93. Thread 160 "mmt_hVideoPlaye" hit Breakpoint 1, 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
94. (gdb) delete 1
95. (gdb) info break
96. No breakpoints or watchpoints.
97. (gdb) c
98. Continuing.
99. [New Thread 3313.12547]
100.
101. Thread 160 "mmt_hVideoPlaye" received signal SIGTRAP, Trace/breakpoint trap.
102. 0xd04dc520 in ?? () from target:/data/app/com.test.media/lib/arm/libFFmpeg.so
103. (gdb)
,现在为mov r0, r4
。
第74-80行:执行udf #16
命令会将$ pc保留在同一位置,ni
完全将我们困住了。
第81-89行:多个udf #16
使我们位于同一位置。
第90-93行:ni
命令同样使我们陷入困境。
第94-102行:删除所有断点不会恢复指令,一条continue
命令会击中尚未恢复的continue
。
以下是一些相关的gdb可设置参数:
udf #16
问题
为什么gdb调试器无法执行最简单,最关键的调试器操作之一,即在命中断点时恢复指令?