There's a way to break on a variable/memory address being freed ? Does a simple watchpoint work on this case ?
Scenario, I getting a segfault when the program does the freeing of variables apparently the variable in question is getting free two times, i need know where it's first freed.
PS: lldb and gdb, if possible for both respective commands.
gdbIn gdb you can set conditional breakpoints by writing break location if condition.
This means that in order to break on free where the function is invoked with a pointer that refers to some dynamically allocated data, we first have to obtain the address of the dynamically allocated data, and then set a breakpoint with a suitable condition.
Further reading:
gdb/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
The first thing we need to do is find a suitable breakpoint so that we can expect the contents of the variable we would like to watch, more specifically the address of the dynamically allocated memory.
(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
We will then set a breakpoint on a suitable place, in this case line 9 — we then run the application to see what the value stored in p is.
(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
When we know the address we would like to monitor in terms of free, we can easily set a conditional breakpoint at our desired location. First we will need to make sure that free is actually named what we think.
(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
We can now create the breakpoint, and continue execution to see where our data is freed:
(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 ***
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With