中断变量被释放

时间:2015-10-11 15:44:45

标签: c debugging gdb lldb

有一种方法可以中断正在释放的变量/内存地址吗?一个简单的观察点是否适用于这种情况?

场景,当程序释放变量时,我得到一个段错误,显然有问题的变量是免费的两次,我需要知道它首先被释放的位置。

PS:lldb和gdb,如果可能的话,两个命令都可以。

1 个答案:

答案 0 :(得分:2)

如何在gdb

中执行此操作

gdb中,您可以通过编写break location if condition来设置条件断点

这意味着为了在使用引用某些动态分配数据的指针调用函数的free中断,我们首先必须获取动态分配数据的地址,然后设置< em>断点,条件合适。

进一步阅读

设置实验

/tmp% cat > foo.c <<EOF
> #include <stdlib.h>
> 
> void some_function (int * p) {
>   free (p);
> }
> 
> int main () {
>   int * p = malloc (sizeof (int));
> 
>   some_function (p);
> 
>   free (p);
> 
>   return 0;
> }
> EOF
/tmp% gcc -g foo.c -o a.out

冒险

/tmp% gdb ./a.out

我们需要做的第一件事是找到一个合适的断点,以便我们可以期待我们想要观察的变量的内容,更具体地说是动态分配的内存的地址。


(gdb) list main
2   
3   void some_function (int * p) {
4     free (p);
5   }
6   
7   int main () {
8     int * p = malloc (sizeof (int));
9   
10    some_function (p);
11

然后我们将在合适的位置设置断点,在本例中为行9 - 然后我们运行应用程序以查看p中存储的值是什么。


(gdb) break 9
Breakpoint 1 at 0x400577: file foo.c, line 9.
(gdb) run
Starting program: /tmp/a.out 

Breakpoint 1, main () at foo.c:10
(gdb) print p
$1 = (int *) 0x601010

当我们知道我们要根据free监控的地址时,我们可以轻松地在所需位置设置条件断点。首先,我们需要确保free实际上符合我们的想法。

(gdb) disas main
Dump of assembler code for function main:
   0x0000000000400561 : push   %rbp
   0x0000000000400562 : mov    %rsp,%rbp
   0x0000000000400565 : sub    $0x10,%rsp
   0x0000000000400569 : mov    $0x4,%edi
   0x000000000040056e :    callq  0x400440 <malloc@plt>
   0x0000000000400573 :    mov    %rax,-0x8(%rbp)
=> 0x0000000000400577 :    mov    -0x8(%rbp),%rax
   0x000000000040057b :    mov    %rax,%rdi
   0x000000000040057e :    callq  0x400546 <some_function>
   0x0000000000400583 :    mov    -0x8(%rbp),%rax
   0x0000000000400587 :    mov    %rax,%rdi
   0x000000000040058a :    callq  0x400410 <free@plt>
   0x000000000040058f :    mov    $0x0,%eax
   0x0000000000400594 :    leaveq 
   0x0000000000400595 :    retq

我们现在可以创建断点,并继续执行以查看我们的数据被释放的位置:

(gdb) break free@plt if $rdi == 0x601010
Breakpoint 2 at 0x400410 (3 locations)
(gdb) cont
Continuing.

Breakpoint 2, 0x0000000000400410 in free@plt ()
(gdb) backtrace
#0  0x0000000000400410 in free@plt ()
#1  0x000000000040055e in some_function (p=0x601010) at foo.c:4
#2  0x0000000000400583 in main () at foo.c:10
(gdb) cont
Continuing.

Breakpoint 2, 0x0000000000400410 in free@plt ()
(gdb) backtrace
#0  0x0000000000400410 in free@plt ()
#1  0x000000000040058f in main () at foo.c:12
(gdb) cont
Continuing.
*** Error in `/tmp/a.out': double free or corruption (fasttop): 0x0000000000601010 ***
...