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