当GDB断点命中时,指令无法恢复

时间:2019-03-28 12:49:26

标签: debugging arm gdb breakpoints trap

背景

我正在使用gdbgdbserver(gdb版本7.11)调试Android(ARM)应用程序。我的主机gdb在Windows 10上运行,而经过调试的Android是通过USB连接的Samsung Galaxy J7。

主机和目标之间的连接良好,gdb似乎运行良好。我能够在目标/调试后的应用程序中的某个位置上设置一个断点,并使该断点被命中。

问题

碰到断点时,会观察到以下问题:

  • 断点地址处的ARM指令读取udf #16,而不是原始指令。
    • ARM udf指令是一个'permanently UNDEFINED encoding',似乎用于实现断点捕获内部机制。执行udf #16指令后,将引发调试器拾取的TRAP信号。
  • 命中断点时,调试器应始终恢复原始指令。在我的系统上没有发生这种情况。
  • 执行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   突然断开。但是,对于较慢的远程目标,插入和   删除断点会降低性能。此行为可以是   由以下命令控制:

     

始终插入断点设置

     

所有断点(包括用户新添加的断点)均插入   仅在恢复目标时才使用目标。所有断点都是   停止时从目标上移开。这是默认模式。

     

设置断点始终插入

     

使所有断点始终插入到目标中。如果   用户添加新的断点或更改现有的断点,   目标中的断点将立即更新。断点已删除   仅在删除断点本身时才从目标中删除。

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调试器无法执行最简单,最关键的调试器操作之一,即在命中断点时恢复指令?

0 个答案:

没有答案