在变量被释放时中断
Break on variable being freed
有一种方法可以在 variable/memory 地址被释放时中断?一个简单的观察点是否适用于这种情况?
场景,当程序释放变量时出现段错误,显然有问题的变量被释放了两次,我需要知道它第一次被释放的位置。
PS:lldb 和 gdb,如果两个命令都可能的话。
如何在 gdb
中完成
在gdb
中你可以设置条件断点通过写break <em>location</em> if <em>条件</em>
.
这意味着为了在 free
处中断函数被引用一些动态分配数据的指针调用,我们首先必须获得动态分配数据的地址,然后设置条件合适的断点。
进一步阅读:
设置实验
/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% <b>gdb ./a.out</b>
我们需要做的第一件事是找到一个合适的断点,这样我们就可以期待我们想要观察的变量的内容,更具体地说是动态分配内存的地址。
(gdb) <b>主列表</b>
2个
3 void some_function (int * p) {
4 自由 (p);
5 }
6个
7 int 主要 () {
8 int * p = malloc (sizeof (int));
9
10 some_function (p);
11
然后我们将在合适的地方设置一个断点,在本例中是行9
——然后我们运行应用程序来查看值是什么存储在p
是。
(gdb) <b>打破 9</b>
0x400577 处的断点 1:文件 foo.c,第 9 行。
(gdb) <b>运行</b>
启动程序:/tmp/a.out
断点 1,main () 位于 foo.c:10
(gdb) <b>打印 p</b>
$1 = (int *) 0x601010
当我们根据 free
知道我们想要监控的地址时,我们可以轻松地在我们想要的位置设置条件 断点 。首先,我们需要确保 free
的实际命名符合我们的想法。
(gdb) <b>disas main</b>
函数 main 的汇编代码转储:
0x0000000000400561:推送 %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
<em>0x000000000040058a : callq 0x400410 <free@plt></em>
0x000000000040058f : 移动 $0x0,%eax
0x0000000000400594:离开q
0x0000000000400595:retq
我们现在可以创建断点,并继续执行以查看释放数据的位置:
(gdb) <b>break free@plt if $rdi == 0x601010</b>
0x400410 处的断点 2(3 个位置)
(gdb) <b>续</b>
继续。
断点2,0x0000000000400410 in free@plt()
(gdb) <b>回溯</b>
#0 0x0000000000400410 在 free@plt ()
#1 0x000000000040055e 在 some_function (p=0x601010) 在 foo.c:4
#2 0x0000000000400583 in main () at foo.c:10
(gdb) 续
继续。
断点2,0x0000000000400410 in free@plt()
(gdb) <b>回溯</b>
#0 0x0000000000400410 在 free@plt ()
#1 0x000000000040058f in main () at foo.c:12
(gdb) <b>续</b>
继续。
*** `/tmp/a.out' 中的错误:双重释放或损坏(快顶):0x0000000000601010 ***
...
有一种方法可以在 variable/memory 地址被释放时中断?一个简单的观察点是否适用于这种情况?
场景,当程序释放变量时出现段错误,显然有问题的变量被释放了两次,我需要知道它第一次被释放的位置。
PS:lldb 和 gdb,如果两个命令都可能的话。
如何在 gdb
中完成
在gdb
中你可以设置条件断点通过写break <em>location</em> if <em>条件</em>
.
这意味着为了在 free
处中断函数被引用一些动态分配数据的指针调用,我们首先必须获得动态分配数据的地址,然后设置条件合适的断点。
进一步阅读:
设置实验
/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% <b>gdb ./a.out</b>
我们需要做的第一件事是找到一个合适的断点,这样我们就可以期待我们想要观察的变量的内容,更具体地说是动态分配内存的地址。
(gdb) <b>主列表</b>
2个
3 void some_function (int * p) {
4 自由 (p);
5 }
6个
7 int 主要 () {
8 int * p = malloc (sizeof (int));
9
10 some_function (p);
11
然后我们将在合适的地方设置一个断点,在本例中是行9
——然后我们运行应用程序来查看值是什么存储在p
是。
(gdb) <b>打破 9</b>
0x400577 处的断点 1:文件 foo.c,第 9 行。
(gdb) <b>运行</b>
启动程序:/tmp/a.out
断点 1,main () 位于 foo.c:10
(gdb) <b>打印 p</b>
$1 = (int *) 0x601010
当我们根据 free
知道我们想要监控的地址时,我们可以轻松地在我们想要的位置设置条件 断点 。首先,我们需要确保 free
的实际命名符合我们的想法。
(gdb) <b>disas main</b>
函数 main 的汇编代码转储:
0x0000000000400561:推送 %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
<em>0x000000000040058a : callq 0x400410 <free@plt></em>
0x000000000040058f : 移动 $0x0,%eax
0x0000000000400594:离开q
0x0000000000400595:retq
我们现在可以创建断点,并继续执行以查看释放数据的位置:
(gdb) <b>break free@plt if $rdi == 0x601010</b>
0x400410 处的断点 2(3 个位置)
(gdb) <b>续</b>
继续。
断点2,0x0000000000400410 in free@plt()
(gdb) <b>回溯</b>
#0 0x0000000000400410 在 free@plt ()
#1 0x000000000040055e 在 some_function (p=0x601010) 在 foo.c:4
#2 0x0000000000400583 in main () at foo.c:10
(gdb) 续
继续。
断点2,0x0000000000400410 in free@plt()
(gdb) <b>回溯</b>
#0 0x0000000000400410 在 free@plt ()
#1 0x000000000040058f in main () at foo.c:12
(gdb) <b>续</b>
继续。
*** `/tmp/a.out' 中的错误:双重释放或损坏(快顶):0x0000000000601010 ***
...