【发布时间】:2019-03-28 12:49:26
【问题描述】:
背景
我正在使用 gdb 和 gdbserver(gdb 版本 7.11)调试 Android (ARM) 应用程序。我的主机gdb 运行在 Windows 10 上,而调试的 Android 是三星 Galaxy J7,通过 USB 连接。
主机和目标连接良好,gdb 似乎运行良好。我能够在目标/调试应用程序中的某个位置设置断点,并使断点被命中。
问题
当断点被命中时,观察到以下问题:
- 断点地址处的ARM指令读取
udf #16,而不是原始指令。- ARM
udf指令是一个'permanently UNDEFINED encoding',似乎用于实现断点捕获内部机制。当udf #16指令被执行时,它会抛出一个被调试器拾取的 TRAP 信号。
- ARM
- 当断点被命中时,调试器应该总是恢复原始指令。我的系统上没有发生这种情况。
- 执行
ni(下一条指令)命令会一次又一次地执行udf #16指令。 - 删除断点不会恢复原始指令。相反,
udf #16指令仍保留在内存中。 - 将 $pc 寄存器递增四 (4) 只会跳过应该存在的原始指令。
- 删除所有断点并继续 gdb 只需一次又一次地点击
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 突然断开。然而,对于慢速远程目标,插入和 删除断点会降低性能。这种行为可以 用以下命令控制:
设置断点始终插入关闭
所有断点,包括用户新添加的,都插入 仅当目标恢复时目标。所有断点都是 停止时从目标中移除。这是默认模式。
设置断点始终插入
使所有断点始终插入到目标中。如果 用户添加新断点或更改现有断点, 目标中的断点会立即更新。断点被删除 仅当断点本身被删除时才从目标中删除。
breakpoint always-inserted 的值 off 正是我们想要的。确实,这是我的gdb出现问题时的值(见下方可设置的参数),谜底加深了。
相关信息
以下是编号为 gdb 的会话日志,它清楚地显示了问题,以及我的 cmets。
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)
第 2-8 行:GDB 版本为 7.11,配置为 x86_64-w64-mingw32。
第 16-21 行:处理 SIG33 和 SIGSEGV 信号。
第 31-33 行:确定 libFFmpeg 共享对象 .text 段 (0xd04b2f80) 的加载地址。这让我可以计算出我想要的精确指令断点地址 (0xd04dc520)。
第 35-38 行:将指令转储到预期断点地址处和之后。
第 39 行:在 0xd04dc520 处设置断点 1。
第 41-44 行:在设置断点后,将指令转储到预期的断点地址处和之后。
第 48 行:继续执行。
第 50-68 行:执行继续,与设备的交互导致断点被命中。
第 69 行:断点 1 被命中。
第 70-73 行:列出断点地址处的指令。该指令原本是mov r0, r4,现在是udf #16。
第 74-80 行:执行 ni 命令将 $pc 保持在同一个位置,udf #16 完全将我们困住。
第 81-89 行:多个 ni 将我们保持在同一个位置。
第 90-93 行:continue 命令同样让我们陷入困境。
第 94-102 行:删除所有断点不会恢复指令,continue 命令会命中尚未恢复的 udf #16。
以下是一些相关的 gdb 可设置参数:
architecture: The target architecture is set automatically (currently arm)
arm abi: The current ARM ABI is "auto" (currently "AAPCS").
arm apcs32: Usage of ARM 32-bit mode is on.
arm disassembler: The disassembly style is "std".
arm fallback-mode: The current execution mode assumed (when symbols are unavailable) is "auto".
arm force-mode: The current execution mode assumed (even when symbols are available) is "auto".
arm fpu: The current ARM floating point model is "auto".
auto-connect-native-target: Whether GDB may automatically connect to the native target is on.
auto-load gdb-scripts: Auto-loading of canned sequences of commands scripts is on.
auto-load local-gdbinit: Auto-loading of .gdbinit script from current directory is on.
auto-load python-scripts: Auto-loading of Python scripts is on.
auto-load safe-path: List of directories from which it is safe to auto-load files is $debugdir:$datadir/auto-load.
auto-load scripts-directory: List of directories from which to load auto-loaded scripts is $debugdir:$datadir/auto-load.
auto-load-scripts: Auto-loading of Python scripts is on.
auto-solib-add: Autoloading of shared library symbols is on.
breakpoint always-inserted: Always inserted breakpoint mode is off.
breakpoint auto-hw: Automatic usage of hardware breakpoints is on.
breakpoint condition-evaluation: Breakpoint condition evaluation mode is auto (currently host).
breakpoint pending: Debugger's behavior regarding pending breakpoints is auto.
can-use-hw-watchpoints: Debugger's willingness to use watchpoint hardware is 1.
debug aarch64: AArch64 debugging is off.
debug arch: Architecture debugging is 0.
debug arm: ARM debugging is off.
disassemble-next-line: Debugger's willingness to use disassemble-next-line is off.
disassembly-flavor: The disassembly flavor is "att".
osabi: The current OS ABI is "auto" (currently "Cygwin").
The default OS ABI is "Cygwin".remote breakpoint-commands-packet: Support for the `BreakpointCommands' packet is auto-detected, currently unknown.
remote btrace-conf-bts-size-packet: Support for the `Qbtrace-conf:bts:size' packet is auto-detected, currently unknown.
remote btrace-conf-pt-size-packet: Support for the `Qbtrace-conf:pt:size' packet is auto-detected, currently unknown.
remote catch-syscalls-packet: Support for the `QCatchSyscalls' packet is auto-detected, currently unknown.
remote conditional-breakpoints-packet: Support for the `ConditionalBreakpoints' packet is auto-detected, currently unknown.
remote conditional-tracepoints-packet: Support for the `ConditionalTracepoints' packet is auto-detected, currently unknown.
remote ctrl-c-packet: Support for the `vCtrlC' packet is auto-detected, currently unknown.
remote disable-btrace-packet: Support for the `Qbtrace:off' packet is auto-detected, currently unknown.
remote disable-randomization-packet: Support for the `QDisableRandomization' packet is auto-detected, currently unknown.
remote enable-btrace-bts-packet: Support for the `Qbtrace:bts' packet is auto-detected, currently unknown.
remote enable-btrace-pt-packet: Support for the `Qbtrace:pt' packet is auto-detected, currently unknown.
remote exec-event-feature-packet: Support for the `exec-event-feature' packet is auto-detected, currently unknown.
remote exec-file: (null)
remote fast-tracepoints-packet: Support for the `FastTracepoints' packet is auto-detected, currently unknown.
remote fetch-register-packet: Support for the `p' packet is auto-detected, currently unknown.
remote fork-event-feature-packet: Support for the `fork-event-feature' packet is auto-detected, currently unknown.
remote get-thread-information-block-address-packet: Support for the `qGetTIBAddr' packet is auto-detected, currently unknown.
remote get-thread-local-storage-address-packet: Support for the `qGetTLSAddr' packet is auto-detected, currently unknown.
remote hardware-breakpoint-limit: The maximum number of target hardware breakpoints is -1.
remote hardware-breakpoint-packet: Support for the `Z1' packet is auto-detected, currently unknown.
remote hardware-watchpoint-length-limit: The maximum length (in bytes) of a target hardware watchpoint is -1.
remote hardware-watchpoint-limit: The maximum number of target hardware watchpoints is -1.
remote hostio-close-packet: Support for the `vFile:close' packet is auto-detected, currently unknown.
remote hostio-fstat-packet: Support for the `vFile:fstat' packet is auto-detected, currently unknown.
remote hostio-open-packet: Support for the `vFile:open' packet is auto-detected, currently unknown.
remote hostio-pread-packet: Support for the `vFile:pread' packet is auto-detected, currently unknown.
remote hostio-pwrite-packet: Support for the `vFile:pwrite' packet is auto-detected, currently unknown.
remote hostio-readlink-packet: Support for the `vFile:readlink' packet is auto-detected, currently unknown.
remote hostio-setfs-packet: Support for the `vFile:setfs' packet is auto-detected, currently unknown.
remote hostio-unlink-packet: Support for the `vFile:unlink' packet is auto-detected, currently unknown.
remote hwbreak-feature-packet: Support for the `hwbreak-feature' packet is auto-detected, currently unknown.
remote install-in-trace-packet: Support for the `InstallInTrace' packet is auto-detected, currently unknown.
remote interrupt-on-connect: W whether interrupt-sequence is sent to remote target when gdb connects to is off.
remote interrupt-sequence: Send the ASCII ETX character (Ctrl-c) to the remote target to interrupt the execution of the program.
remote kill-packet: Support for the `vKill' packet is auto-detected, currently unknown.
remote library-info-packet: Support for the `qXfer:libraries:read' packet is auto-detected, currently unknown.
remote library-info-svr4-packet: Support for the `qXfer:libraries-svr4:read' packet is auto-detected, currently unknown.
remote memory-map-packet: Support for the `qXfer:memory-map:read' packet is auto-detected, currently unknown.
remote memory-read-packet-size: The memory-read-packet-size is 0. Packets are limited to 648 bytes.
remote memory-write-packet-size: The memory-write-packet-size is 0. Packets are limited to 648 bytes.
remote multiprocess-feature-packet: Support for the `multiprocess-feature' packet is auto-detected, currently unknown.
remote no-resumed-stop-reply-packet: Support for the `N stop reply' packet is auto-detected, currently unknown.
remote noack-packet: Support for the `QStartNoAckMode' packet is auto-detected, currently unknown.
remote osdata-packet: Support for the `qXfer:osdata:read' packet is auto-detected, currently unknown.
remote p-packet: remote pass-signals-packet: Support for the `QPassSignals' packet is auto-detected, currently unknown.
remote pid-to-exec-file-packet: Support for the `qXfer:exec-file:read' packet is auto-detected, currently unknown.
remote program-signals-packet: Support for the `QProgramSignals' packet is auto-detected, currently unknown.
remote query-attached-packet: Support for the `qAttached' packet is auto-detected, currently unknown.
remote read-aux-vector-packet: Support for the `qXfer:auxv:read' packet is auto-detected, currently unknown.
remote read-btrace-conf-packet: Support for the `qXfer:btrace-conf' packet is auto-detected, currently unknown.
remote read-btrace-packet: Support for the `qXfer:btrace' packet is auto-detected, currently unknown.
remote read-fdpic-loadmap-packet: Support for the `qXfer:fdpic:read' packet is auto-detected, currently unknown.
remote read-sdata-object-packet: Support for the `qXfer:statictrace:read' packet is auto-detected, currently unknown.
remote read-siginfo-object-packet: Support for the `qXfer:siginfo:read' packet is auto-detected, currently unknown.
remote read-spu-object-packet: Support for the `qXfer:spu:read' packet is auto-detected, currently unknown.
remote read-watchpoint-packet: Support for the `Z3' packet is auto-detected, currently unknown.
remote reverse-continue-packet: Support for the `bc' packet is auto-detected, currently unknown.
remote reverse-step-packet: Support for the `bs' packet is auto-detected, currently unknown.
remote run-packet: Support for the `vRun' packet is auto-detected, currently unknown.
remote search-memory-packet: Support for the `qSearch:memory' packet is auto-detected, currently unknown.
remote set-register-packet: Support for the `P' packet is auto-detected, currently unknown.
remote software-breakpoint-packet: Support for the `Z0' packet is auto-detected, currently unknown.
remote static-tracepoints-packet: Support for the `StaticTracepoints' packet is auto-detected, currently unknown.
remote supported-packets-packet: Support for the `qSupported' packet is auto-detected, currently unknown.
remote swbreak-feature-packet: Support for the `swbreak-feature' packet is auto-detected, currently unknown.
remote symbol-lookup-packet: Support for the `qSymbol' packet is auto-detected, currently unknown.
remote system-call-allowed: Calling host system(3) call from target is not allowed
remote target-features-packet: Support for the `qXfer:features:read' packet is auto-detected, currently unknown.
remote thread-events-packet: Support for the `QThreadEvents' packet is auto-detected, currently unknown.
remote threads-packet: Support for the `qXfer:threads:read' packet is auto-detected, currently unknown.
remote trace-buffer-size-packet: Support for the `QTBuffer:size' packet is auto-detected, currently unknown.
remote trace-status-packet: Support for the `qTStatus' packet is auto-detected, currently unknown.
remote traceframe-info-packet: Support for the `qXfer:traceframe-info:read' packet is auto-detected, currently unknown.
remote unwind-info-block-packet: Support for the `qXfer:uib:read' packet is auto-detected, currently unknown.
remote verbose-resume-packet: Support for the `vCont' packet is auto-detected, currently unknown.
remote verbose-resume-supported-packet: Support for the `vContSupported' packet is auto-detected, currently unknown.
remote vfork-event-feature-packet: Support for the `vfork-event-feature' packet is auto-detected, currently unknown.
remote write-siginfo-object-packet: Support for the `qXfer:siginfo:write' packet is auto-detected, currently unknown.
remote write-spu-object-packet: Support for the `qXfer:spu:write' packet is auto-detected, currently unknown.
remote write-watchpoint-packet: Support for the `Z2' packet is auto-detected, currently unknown.
remoteaddresssize: The maximum size of the address (in bits) in a memory packet is 0.
remotebreak: remotecache: Deprecated remotecache flag is off.
step-mode: Mode of the step operation is off.
问题
为什么 gdb 调试器无法执行最简单和最关键的调试器操作之一,即在断点被命中时恢复指令?
【问题讨论】:
-
遇到同样的问题,你有没有找到解决办法?
-
我从来没有解决过这个问题。最后,我转而使用 Frida 动态检测开源项目,该项目非常棒且强烈推荐。您可能想阅读 Chris Coulson 的博客文章“调试调试器”(chriscoulson.me.uk/blog/?p=295)。它记录了设置断点时他的 ARM 二进制文件是如何崩溃的。崩溃是由于 Thumb 模式下的 UDF(“未定义”)指令造成的。您可能会从该博客条目中收集想法 - 祝您好运。请务必发布您发现的任何解决方案!
标签: debugging memory-management arm gdb breakpoints