簡體   English   中英

gdb監視點未激活

[英]gdb watchpoint not activated

考慮代碼:

#include <stdio.h>
#include <stdlib.h>

int update (int *arr, int size);

#define SIZE 10

int main() { // <---------------------- Breakpoint 1
  int x[SIZE];

  // Initialize array
  for (int c = 0 ; c < SIZE ; c++) {
    x[c] = c * 2;
  }

  // Do some random updates to an array
  update((int*) &x, SIZE);

  // Print the elements
  for (int c = 0 ; c < SIZE ; c++) {
    printf("%d\n", x[c]);
  }

  return EXIT_SUCCESS;
} //            <----------------------Breakpoint 2

int update (int *arr, int size) {
  for (int i = 0 ; i < size ; i++) {
    arr[i] += i;
    update(arr+i, size-1);
  }
  return 1;
}

在斷點1運行info frame結果:

Stack level 0, frame at 0x7ffc176b2610:
 rip = 0x56434b0d76b8 in main (array.c:12); saved rip = 0x7f8190fb92b1
 source language c.
 Arglist at 0x7ffc176b2600, args:
 Locals at 0x7ffc176b2600, Previous frame's sp is 0x7ffc176b2610
 Saved registers:
  rbp at 0x7ffc176b2600, rip at 0x7ffc176b2608

在斷點2運行info frame結果:

Stack level 0, frame at 0x7ffc176b2610:
 rip = 0x56434b0d771a in main (array.c:24); saved rip = 0x2d28490fd6501
 source language c.
 Arglist at 0x7ffc176b2600, args:
 Locals at 0x7ffc176b2600, Previous frame's sp is 0x7ffc176b2610
 Saved registers:
  rbp at 0x7ffc176b2600, rip at 0x7ffc176b2608

我們看到, main()的返回地址rip at 0x7ffc176b2608突變從0x7f8190fb92b10x2d28490fd6501兩個斷點之間。

但是,使用watch * 0x7ffc176b2608rip的地址上設置觀察點並重新運行可執行文件不會按預期在中斷點之間暫停執行。

怎么會這樣?

- - - - - -編輯 - - - - - -

disassemble /s main輸出:

Dump of assembler code for function main:
array.c:
8   int main() {
   0x000056434b0d76b0 <+0>: push   rbp
   0x000056434b0d76b1 <+1>: mov    rbp,rsp
   0x000056434b0d76b4 <+4>: sub    rsp,0x30

9     int x[SIZE];
10  
11    // Initialize array
12    for (int c = 0 ; c < SIZE ; c++) {
   0x000056434b0d76b8 <+8>: mov    DWORD PTR [rbp-0x4],0x0
   0x000056434b0d76bf <+15>:    jmp    0x56434b0d76d4 <main+36>

13      x[c] = c * 2;
   0x000056434b0d76c1 <+17>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000056434b0d76c4 <+20>:    lea    edx,[rax+rax*1]
   0x000056434b0d76c7 <+23>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000056434b0d76ca <+26>:    cdqe   
   0x000056434b0d76cc <+28>:    mov    DWORD PTR [rbp+rax*4-0x30],edx

12    for (int c = 0 ; c < SIZE ; c++) {
   0x000056434b0d76d0 <+32>:    add    DWORD PTR [rbp-0x4],0x1
   0x000056434b0d76d4 <+36>:    cmp    DWORD PTR [rbp-0x4],0x9
   0x000056434b0d76d8 <+40>:    jle    0x56434b0d76c1 <main+17>

14    }
15  
16    // Do some random updates to an array
17    update((int*) &x, SIZE);
   0x000056434b0d76da <+42>:    lea    rax,[rbp-0x30]
   0x000056434b0d76de <+46>:    mov    esi,0xa
   0x000056434b0d76e3 <+51>:    mov    rdi,rax
   0x000056434b0d76e6 <+54>:    call   0x56434b0d7721 <update>

18  
19    // Print the elements
20    for (int c = 0 ; c < SIZE ; c++) {
   0x000056434b0d76eb <+59>:    mov    DWORD PTR [rbp-0x8],0x0
   0x000056434b0d76f2 <+66>:    jmp    0x56434b0d7714 <main+100>

21      printf("%d\n", x[c]);
   0x000056434b0d76f4 <+68>:    mov    eax,DWORD PTR [rbp-0x8]
   0x000056434b0d76f7 <+71>:    cdqe   
   0x000056434b0d76f9 <+73>:    mov    eax,DWORD PTR [rbp+rax*4-0x30]
   0x000056434b0d76fd <+77>:    mov    esi,eax
   0x000056434b0d76ff <+79>:    lea    rdi,[rip+0x12e]        # 0x56434b0d7834
   0x000056434b0d7706 <+86>:    mov    eax,0x0
   0x000056434b0d770b <+91>:    call   0x56434b0d7560 <printf@plt>

20    for (int c = 0 ; c < SIZE ; c++) {
   0x000056434b0d7710 <+96>:    add    DWORD PTR [rbp-0x8],0x1
   0x000056434b0d7714 <+100>:   cmp    DWORD PTR [rbp-0x8],0x9
   0x000056434b0d7718 <+104>:   jle    0x56434b0d76f4 <main+68>

22    }
23  
24    return EXIT_SUCCESS;
=> 0x000056434b0d771a <+106>:   mov    eax,0x0

25  }
   0x000056434b0d771f <+111>:   leave  
   0x000056434b0d7720 <+112>:   ret    
End of assembler dump.

disassemble /s update輸出:

Dump of assembler code for function update:
array.c:
27  int update (int *arr, int size) {
   0x000056434b0d7721 <+0>: push   rbp
   0x000056434b0d7722 <+1>: mov    rbp,rsp
   0x000056434b0d7725 <+4>: sub    rsp,0x20
   0x000056434b0d7729 <+8>: mov    QWORD PTR [rbp-0x18],rdi
   0x000056434b0d772d <+12>:    mov    DWORD PTR [rbp-0x1c],esi

28    for (int i = 0 ; i < size ; i++) {
   0x000056434b0d7730 <+15>:    mov    DWORD PTR [rbp-0x4],0x0
   0x000056434b0d7737 <+22>:    jmp    0x56434b0d7793 <update+114>

29      arr[i] += i;
   0x000056434b0d7739 <+24>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000056434b0d773c <+27>:    cdqe   
   0x000056434b0d773e <+29>:    lea    rdx,[rax*4+0x0]
   0x000056434b0d7746 <+37>:    mov    rax,QWORD PTR [rbp-0x18]
   0x000056434b0d774a <+41>:    add    rax,rdx
   0x000056434b0d774d <+44>:    mov    edx,DWORD PTR [rbp-0x4]
   0x000056434b0d7750 <+47>:    movsxd rdx,edx
   0x000056434b0d7753 <+50>:    lea    rcx,[rdx*4+0x0]
   0x000056434b0d775b <+58>:    mov    rdx,QWORD PTR [rbp-0x18]
   0x000056434b0d775f <+62>:    add    rdx,rcx
   0x000056434b0d7762 <+65>:    mov    ecx,DWORD PTR [rdx]
   0x000056434b0d7764 <+67>:    mov    edx,DWORD PTR [rbp-0x4]
   0x000056434b0d7767 <+70>:    add    edx,ecx
   0x000056434b0d7769 <+72>:    mov    DWORD PTR [rax],edx

30      update(arr+i, size-1);
   0x000056434b0d776b <+74>:    mov    eax,DWORD PTR [rbp-0x1c]
   0x000056434b0d776e <+77>:    lea    edx,[rax-0x1]
   0x000056434b0d7771 <+80>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000056434b0d7774 <+83>:    cdqe   
   0x000056434b0d7776 <+85>:    lea    rcx,[rax*4+0x0]
   0x000056434b0d777e <+93>:    mov    rax,QWORD PTR [rbp-0x18]
   0x000056434b0d7782 <+97>:    add    rax,rcx
   0x000056434b0d7785 <+100>:   mov    esi,edx
   0x000056434b0d7787 <+102>:   mov    rdi,rax
   0x000056434b0d778a <+105>:   call   0x56434b0d7721 <update>

28    for (int i = 0 ; i < size ; i++) {
   0x000056434b0d778f <+110>:   add    DWORD PTR [rbp-0x4],0x1
   0x000056434b0d7793 <+114>:   mov    eax,DWORD PTR [rbp-0x4]
   0x000056434b0d7796 <+117>:   cmp    eax,DWORD PTR [rbp-0x1c]
   0x000056434b0d7799 <+120>:   jl     0x56434b0d7739 <update+24>

31    }
32    return 1;
   0x000056434b0d779b <+122>:   mov    eax,0x1

33  }
   0x000056434b0d77a0 <+127>:   leave  
   0x000056434b0d77a1 <+128>:   ret    
End of assembler dump.

~/.gdbinit

# Security
set auto-load safe-path /

# Misc
set disassembly-flavor intel
set disable-randomization off
set pagination off
set follow-fork-mode child

# History
set history filename ~/.gdbhistory
set history save
set history expansion

disp/10i $pc

handle SIGXCPU SIG33 SIG35 SIGPWR nostop noprint

set tui enable

.gdbinit中的這一行可能是您麻煩的根源:

set disable-randomization off

默認情況下,GDB禁用地址空間布局隨機化( ASLR )。 這意味着GDB下的二進制文件從完全相同的地址開始,每次運行時都具有完全相同的堆棧指針。 默認情況下,這是精確啟用的,因此您可以在給定地址上設置觀察點和斷點,並在每次運行時觸發它。

通過disable-randomization ,您要求GDB以與GDB外部相同的方式運行二進制文件,即啟用ASLR。 現在,堆棧變量(以及您擁有的PIE二進制文件的全局變量)的位置將隨運行而變化,並且在給定堆棧地址上設置觀察點將僅隨機且很少起作用。

您可以通過發出info frame來確認這是原因,然后run幾次。 您會觀察到寄存器的存儲位置在兩次運行之間發生了變化。

TL; DR:不要將您不完全了解的設置放入.gdbinit

代碼的問題在於堆棧的混亂。

@Mark Plotnick的評論澄清了該問題,並提供了有關如何解決該問題的建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM