Segmentation fault when a custom chunk allocator returns a memory block larger than the chunk size

Bradley C. Kuszmaul bradley at mit.edu
Mon Jul 28 19:02:15 PDT 2014


Also 2^31 == 29, not 1<<31

Bradley C Kuszmaul - via snartphone
On Jul 28, 2014 7:04 PM, "meng" <xqmeng at gmail.com> wrote:

> Yes, the address returned from the custom chunk_alloc() is got from
> mmap(0,2^31,...). Because 2^31 is a multiple of 2^22 (the default chunk
> size), it must be aligned with the chunk size.
>
> Below is a simplified version of my test program:
>
> void *space = NULL;
> static  unsigned              _arena;
> static  chunk_alloc_t        *_alloc;
> static  chunk_dalloc_t      *_dalloc;
>
> static void *_chunk_alloc(size_t, size_t, bool *, unsigned);
> static bool _chunk_dalloc(void *, size_t, unsigned);
>
> void * _chunk_alloc(size_t size, size_t alignment, bool *zero, unsigned
> arena_ind)
> {
>   return space;
> }
>
> bool _chunk_dalloc(void *chunk, size_t size, unsigned arena_ind)
> {
>   return true;
> }
>
> int main(void)
> {
>   space = mmap (NULL, 2^31, PROT_READ | PROT_WRITE, MAP_SHARED |
> MAP_ANONYMOUS, -1, 0);
>   assert (space != (void *) -1);
>
>   size_t sz = sizeof(_arena);
>   int ret = mallctl("arenas.extend", &_arena, &sz, NULL, 0);
>   assert (ret == 0);
>
>   sz = sizeof(_alloc);
>   char path[128];
>   snprintf(path, sizeof(path), "arena.%u.chunk.alloc", _arena);
>   chunk_alloc_t *alloc = _chunk_alloc;
>   ret = mallctl(path, (void*)&_alloc, &sz, (void*)&alloc, sizeof(alloc));
>   assert (ret == 0);
>
>   snprintf(path, sizeof(path), "arena.%u.chunk.dalloc", _arena);
>   chunk_dalloc_t *dalloc = _chunk_dalloc;
>   ret = mallctl(path, (void*)&_dalloc, &sz, (void*)&dalloc,
> sizeof(dalloc));
>   assert (ret == 0);
>
>   void *p = mallocx(1024, MALLOCX_ARENA(_arena));
>   assert (p != 0);
>   dallocx(p, MALLOCX_ARENA(_arena));
>
>   //unmap space
>   return 1;
> }
>
> The seg. fault occurs in mallocx, and here is the stack frame in GDB:
> #0  0x00007ffff7d6b7a2 in je_arena_mapbitsp_write (mapbits=4,
> mapbitsp=0x7ffff7cb0008) at include/jemalloc/internal/arena.h:774
> #1  je_arena_mapbits_unzeroed_set (unzeroed=4, pageind=345,
> chunk=0x7ffff7cae000) at include/jemalloc/internal/arena.h:852
> #2  arena_chunk_init_hard (arena=0x7ffff7822140) at src/arena.c:662
> #3  0x00007ffff7d6bea8 in arena_chunk_alloc (arena=0x7ffff7822140) at
> src/arena.c:689
> #4  0x00007ffff7d6ce9b in arena_run_alloc_small (arena=0x7ffff7822140,
> size=65536, binind=20) at src/arena.c:854
> #5  0x00007ffff7d74852 in arena_bin_nonfull_run_get (arena=0x7ffff7822140,
> bin=0x7ffff7822e70) at src/arena.c:1470
> #6  0x00007ffff7d749aa in arena_bin_malloc_hard (arena=0x7ffff7822140,
> bin=0x7ffff7822e70) at src/arena.c:1516
> #7  0x00007ffff7d7558a in je_arena_malloc_small (arena=0x7ffff7822140,
> size=1024, zero=false) at src/arena.c:1713
> #8  0x00007ffff7d17121 in je_arena_malloc (try_tcache=false, zero=false,
> size=1024, arena=0x7ffff7822140) at include/jemalloc/internal/arena.h:1076
> #9  je_imalloct (arena=0x7ffff7822140, try_tcache=false, size=1024) at
> include/jemalloc/internal/jemalloc_internal.h:647
> #10 imallocx (arena=0x7ffff7822140, try_tcache=false, zero=false,
> alignment=0, usize=1024) at src/jemalloc.c:1377
> #11 mallocx (size=1024, flags=512) at src/jemalloc.c:1456
> #12 0x0000000000400c06 in main () at test_jemalloc.c:102
>
>
>
>
>
> On Mon, Jul 28, 2014 at 5:52 PM, Jason Evans <jasone at canonware.com> wrote:
>
>> On Jul 28, 2014, at 2:17 PM, meng <xqmeng at gmail.com> wrote:
>> > I used the new chunk allocator feature to allocate memory from a fixed
>> 2G memory region. Nevertheless, I got a seg. fault.
>> >
>> > The flow of my code is as following:  I first use "arenas.extend"
>> mallctl to create a custom arena. Then I defined custom chunk_alloc() and
>> chunk_dalloc() on this arena. In the initialization phase of my code, I use
>> mmap() to reserve a memory region of size 2^32. In the custom
>> chunk_alloc(), I return the pointer of the 2^32B memory region. Because
>> lg_chunk is 2^22, I thought this should be fine. But the program ran into
>> seg. fault within  arena_mapbits_unzeroed_set() called by
>> arena_chunk_init_hard().  On the other hand, if the mmap() reserved a
>> memory region of size 2^22, everything works fine.
>> >
>> > My question is: why does the custom chunk_alloc() always expect a
>> memory block returned from mmap()/malloc() with the requested size equal to
>> lg_chunk? I can't figure out what wrong it could be if the returned block
>> is a multiple of lg_chunk
>> >
>> > B.T.W. My code only uses mallocx() for a single 1024B buffer from the
>> custom. Memory alignment problem shouldn't exist.
>>
>> Is the address you're returning from the custom chunk_alloc() aligned at
>> a multiple of the chunk size?
>>
>> Jason
>
>
>
>
> --
> Best
> -Xiaoqiao
>
> _______________________________________________
> jemalloc-discuss mailing list
> jemalloc-discuss at canonware.com
> http://www.canonware.com/mailman/listinfo/jemalloc-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://jemalloc.net/mailman/jemalloc-discuss/attachments/20140728/72c4c1c6/attachment-0001.html>


More information about the jemalloc-discuss mailing list