我想調試一個程序,並且對(int i = 0; i < 10; i ++) 感興趣,並且希望在GDB調試器中將i <更改爲i < = 10。我已經使用print來更改變量名稱,但我該如何做到這一點?謝謝。使用GDB更改for循環條件?
2
A
回答
2
想要更改i < 10到i < = 10在GDB調試器中。
有幾種方法可以做到這一點,這取決於正好你需要什麼。
我假設你只需要做一次這樣的事情,即你的二進制文件沒有經過優化就構建了x86_64
。
鑑於:
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++)
printf("%d\n", i);
return 0;
}
gcc -g -std=c99 t.c && gdb -q ./a.out
gdb) disas main
Dump of assembler code for function main:
0x000000000040052d <+0>: push %rbp
0x000000000040052e <+1>: mov %rsp,%rbp
0x0000000000400531 <+4>: sub $0x10,%rsp
0x0000000000400535 <+8>: movl $0x0,-0x4(%rbp)
0x000000000040053c <+15>: jmp 0x400556 <main+41>
0x000000000040053e <+17>: mov -0x4(%rbp),%eax
0x0000000000400541 <+20>: mov %eax,%esi
0x0000000000400543 <+22>: mov $0x4005f4,%edi
0x0000000000400548 <+27>: mov $0x0,%eax
0x000000000040054d <+32>: callq 0x400410 <[email protected]>
0x0000000000400552 <+37>: addl $0x1,-0x4(%rbp)
0x0000000000400556 <+41>: cmpl $0x9,-0x4(%rbp)
0x000000000040055a <+45>: jle 0x40053e <main+17>
0x000000000040055c <+47>: mov $0x0,%eax
0x0000000000400561 <+52>: leaveq
0x0000000000400562 <+53>: retq
End of assembler dump.
在這裏可以看到,在地址0x400556
指令(在位置$rbp-4
存儲在棧)具有恆定9
比較的i
值,並跳回如果該值小於或等於到9
。
所以,你可以在0x40055a
設置指令斷點,然後即使編譯後的代碼表示,它不應該採取力跳:
(gdb) b *0x40055a if i == 10
Breakpoint 1 at 0x40055a: file t.c, line 4.
(gdb) run
Starting program: /tmp/a.out
0
1
2
3
4
5
6
7
8
9
Breakpoint 1, 0x000000000040055a in main() at t.c:4
4 for (int i = 0; i < 10; i++)
(gdb) p i
$1 = 10
(gdb) jump *0x40053e
Continuing at 0x40053e.
10
[Inferior 1 (process 22210) exited normally]
瞧:我們已經印製一個額外的價值。
另一個可能的方法:設置指令斷點在0x400556
,的i
值調整爲i-1
,單步驟中,i
值調整爲i+1
,繼續。
另一種方法:
(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 09 cmpl $0x9,-0x4(%rbp)
End of assembler dump.
在這裏你可以看到,不斷9
是指令字節的一部分,特別是在字節:二進制補丁在0x400556
指令以恆定10
代替9
比較地址0x400559
。您可以更改字節:
(gdb) start
Starting program: /tmp/a.out
Temporary breakpoint 1, main() at t.c:4
4 for (int i = 0; i < 10; i++)
讓我們覆蓋的指令,再拆卸:
(gdb) set *(char*)0x400559 = 10
(gdb) disas/r 0x400556,0x400557
Dump of assembler code from 0x400556 to 0x400557:
0x0000000000400556 <main+41>: 83 7d fc 0a cmpl $0xa,-0x4(%rbp)
End of assembler dump.
看起來不錯:我們現在比較10
而不是9
。它工作嗎?
(gdb) c
Continuing.
0
1
2
3
4
5
6
7
8
9
10
[Inferior 1 (process 23131) exited normally]
是的,它的確如此!
P.S.二進制修補指令相當於編輯源代碼並重新構建二進制文件,除了該補丁在下一個run
上被「遺忘」。
相關問題
- 1. for循環裏面while循環使用條件如果條件
- 2. 時間條件「for」循環使用PowerShell
- 3. 將foreach循環更改爲for循環
- 4. 在循環中更改爲for循環
- 5. For循環條件問題
- 6. For循環無條件
- 7. For循環條件在Python
- 8. Excel VBA for循環條件
- 9. R - 使用for循環來有條件地更改數據幀中的值
- 10. 使用數組for循環for循環
- 11. 函數調用for循環條件?
- 12. For循環更換:For循環濾鏡
- 13. 進度條使用嵌套for循環
- 14. 使用for循環更改列不同列改變所有列
- 15. 使用for循環
- 16. 使用For循環
- 17. 使用「for」循環
- 18. PHP:while循環 - 在條件下使用更改後的變量
- 19. 在GGPLOT2更改內的for循環
- 20. 在for循環中更改狀態
- 21. For循環python不斷更改索引
- 22. 使用for/foreach循環更新
- 23. 使用for循環更新字典值
- 24. 使用for循環更新ggplot(R)
- 25. Python的條件語句與for循環
- 26. for python中的/空循環條件
- 27. 失蹤;後for循環條件
- 28. Lua的for循環與多個條件
- 29. 如果條件與FOR循環db2 plsql
- 30. for循環中的複合條件
gdb無法更改您的代碼,它被設置爲只讀... –
我同意:我認爲有一些工具可以讓你在調試器(Visual Studio)中實際*替換代碼...但是我懷疑gdb是否可以這樣做。 – GhostCat
我想,你可以改變寄存器來跳轉跳轉條件... – arrowd