简体   繁体   中英

Using malloc / free in android

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  

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM