Reputation: 110600
I use malloc() to allocate memory, when I am doing, I use 'free() to free memory. When I free it, I get 'ABORTING LIBC'.
I print out the value of address when I alloc and free, it is 0x410f1008. But when I free it, it is freeing 0x410f1000, why is that?
D/ ( 3076): build_: alloc 0x410f1008
...
D/ ( 3076): build: free 0x410f1008
F/libc ( 3076): @@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x410f1000
F/libc ( 3076): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 3076 (test)
I/DEBUG ( 1647): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 1647): Build fingerprint: ''
I/DEBUG ( 1647): Revision: '0'
I/DEBUG ( 1647): pid: 3076, tid: 3076, name: test >>> test <<<
I/DEBUG ( 1647): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
I/DEBUG ( 1647): r0 00000055 r1 be960720 r2 00000003 r3 deadbaad
I/DEBUG ( 1647): r4 400fa228 r5 410f1000 r6 be960748 r7 400ed73a
I/DEBUG ( 1647): r8 410f1008 r9 ffffff82 sl 000829a0 fp 000007e0
I/DEBUG ( 1647): ip 00000000 sp be960748 lr 400d9a29 pc 400bdffc cpsr 00000030
I/DEBUG ( 1647): d0 3830303166303134 d1 65696c63204d4d20
I/DEBUG ( 1647): d2 0000000000000066 d3 0000000000000072
I/DEBUG ( 1647): d4 0000000000000000 d5 0000000000000000
I/DEBUG ( 1647): d6 0000000000000000 d7 94e7c71700000000
I/DEBUG ( 1647): d8 0000000000000000 d9 0000000000000000
I/DEBUG ( 1647): d10 0000000000000000 d11 0000000000000000
I/DEBUG ( 1647): d12 0000000000000000 d13 0000000000000000
I/DEBUG ( 1647): d14 0000000000000000 d15 0000000000000000
I/DEBUG ( 1647): d16 c1dac60e3a4fdf3b d17 3f50624dd2f1a9fc
I/DEBUG ( 1647): d18 41a9f539c0000000 d19 0000000000000000
I/DEBUG ( 1647): d20 0000000000000000 d21 0000000000000000
I/DEBUG ( 1647): d22 0000000000000000 d23 0000000000000000
I/DEBUG ( 1647): d24 0000000000000000 d25 0000000000000000
I/DEBUG ( 1647): d26 0000000000000000 d27 0000000000000000
I/DEBUG ( 1647): d28 0000000000000000 d29 0000000000000000
I/DEBUG ( 1647): d30 0000000000000000 d31 0000000000000000
I/DEBUG ( 1647): scr 00000010
I/DEBUG ( 1647):
I/DEBUG ( 1647): backtrace:
I/DEBUG ( 1647): #00 pc 0000effc /system/lib/libc.so
I/DEBUG ( 1647): #01 pc 00011da3 /system/lib/libc.so (dlfree+1458)
I/DEBUG ( 1647): #02 pc 0000cf13 /system/lib/libc.so (free+10)
I/DEBUG ( 1647): #03 pc 00002c25 /system/bin/ppm2jpg
I/DEBUG ( 1647): #04 pc 0000316d /system/bin/ppm2jpg
I/DEBUG ( 1647): #05 pc 0001271f /system/lib/libc.so (__libc_init+38)
I/DEBUG ( 1647): #06 pc 00000b3c /system/bin/ppm2jpg
I/DEBUG ( 1647):
I/DEBUG ( 1647): stack:
I/DEBUG ( 1647): be960708 00000001
I/DEBUG ( 1647): be96070c 400ed73a /system/lib/libc.so
I/DEBUG ( 1647): be960710 410f1008
I/DEBUG ( 1647): be960714 400d9a93 /system/lib/libc.so
I/DEBUG ( 1647): be960718 00000010
I/DEBUG ( 1647): be96071c 00000007
I/DEBUG ( 1647): be960720 be96071c [stack]
I/DEBUG ( 1647): be960724 00000001
I/DEBUG ( 1647): be960728 400ed336 /system/lib/libc.so
I/DEBUG ( 1647): be96072c 00000005
I/DEBUG ( 1647): be960730 be960754 [stack]
I/DEBUG ( 1647): be960734 0000004f
I/DEBUG ( 1647): be960738 400fa228
Upvotes: 1
Views: 2177
Reputation: 5741
To understand this scenario, I debugged the dlmalloc as it is most widely used and we do have source code available in public domain. ftp://g.oswego.edu/pub/misc/malloc.c
#include"dlmalloc.h"
#include<string.h>
void use_dlmalloc(void){
size_t sz = 32;
char* a = (char*)malloc(32);
strcpy(a,"DougLeaMalloc");
free(a);
}
int main() {
use_dlmalloc();
return 0;
}
The below is the snapshot from GDB session. We can see that the malloc has returned the 0x60c010 and internally while freeing the memory allocator has moved back the pointer by two word(in this 16 byte as mine is 64 bit machine). So the internally it is actually freeing the 0x60c000. This matches with your problem and the only difference is you are getting the 8 byte difference as your machine should be 32 bit.
(gdb) step
use_dlmalloc () at client.c:5
5 size_t sz = 32;
(gdb) n
6 char* a = (char*)malloc(32);
(gdb)
7 strcpy(a,"DougLeaMalloc");
(gdb) p a
$1 = 0x60c010 ""
(gdb) n
8 free(a);
(gdb) step
free (mem=0x60c010) at dougleamalloc.c:4684
4684 if (mem != 0) {
(gdb) bt
#0 free (mem=0x60c010) at dougleamalloc.c:4684
#1 0x00000000004096f4 in use_dlmalloc () at client.c:8
#2 0x00000000004096ff in main () at client.c:12
(gdb) n
4685 mchunkptr p = mem2chunk(mem);
(gdb) p p
$3 = (mchunkptr) 0x60c000
(gdb) n
4697 if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
mem2chunk is marco and defined as follows. This means TWO_SIZE_T_SIZES would be two word(16 byte on 64 bit machine and 8 on 32 bit machine). This macro basically shifts the pointer back.
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
This the structure of the malloc chunk. When it allocates it return the address to user pointed by arrow. Just prior to that it store all important information like the size of chunk, status of chunk(free-allocated) and some additional housekeeping information.
struct malloc_chunk {
size_t prev_foot; /* Size of previous chunk (if free). */
size_t head; /* Size and inuse bits. */
struct malloc_chunk* fd; =============> This address returned by malloc.
struct malloc_chunk* bk;
};
While freeing user passes the returned address from malloc(). Now heap allocator internally moves back the pointer by 8 or 16 byte so that he can fetch all housekeeping information about the chunk. This is boundary tag method and you can read and understand many good concept by reading the comment in his code.
I think this explain your why the address has shifted from malloc to free(). However I do not have idea why on android you are getting 'ABORTING LIBC' message. Hope the above explanation would be useful.
Upvotes: 1