Menu

#38 Custom allocator crashes interpreter

None
closed-invalid
nobody
gc (1) crash (1)
1
2013-03-20
2013-03-18
Sanel Zukan
No

Adding custom allocator for function scheme_init_new_custom_alloc()
will crash interpreter, causing wrong finalize_cell() call. I'm running
Fedora 18 x86_64.

Here is how to reproduce; create two functions, safe_malloc() and
safe_free() with this content:

void *safe_malloc (size_t siz)
{
  void *p;

  if (siz == 0)
    return 0;
  if ((p = (void *) malloc (siz)) == 0) 
  {
    puts_("Out of memory!");
    sleep (1);
    exit (1);
  }
  return (p);
}

void safe_free (void *ptr)
{
  void **p = (void **)ptr;
  if (*p)
  {
    free (*p);
    *p = 0;
  }
}

Now in scheme.c, in main(), instead

 if(!scheme_init(&sc)) {
  ...
 }

put

 if(!scheme_init_custom_alloc(&sc, safe_malloc, safe_free)) {
   ...
 }

interpreter will be crashed with the following stacktrace:

Program terminated with signal 11, Segmentation fault.
#0  0x0000003de047f8ec in free () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install
glibc-2.16-28.fc18.x86_64
(gdb) bt
#0  0x0000003de047f8ec in free () from /lib64/libc.so.6
#1  0x000000000040200d in safe_free (ptr=0x1f79160) at scheme.c:4953
#2  0x0000000000402f56 in finalize_cell (a=0x1f2c3b0,
sc=0x7fffaa0c9e70) at scheme.c:1326
#3  gc (sc=sc@entry=0x7fffaa0c9e70, a=<optimized out>, b=<optimized
out>) at scheme.c:1300
#4  0x0000000000403047 in _get_cell (b=0x1f77e90, a=0x1f22bd0,
sc=0x7fffaa0c9e70) at scheme.c:634
#5  get_cell_x (sc=sc@entry=0x7fffaa0c9e70, a=a@entry=0x1f22bd0,
b=b@entry=0x1f77e90) at scheme.c:620
#6  0x000000000040312f in get_cell (sc=sc@entry=0x7fffaa0c9e70,
a=a@entry=0x1f22bd0, b=b@entry=0x1f77e90) at scheme.c:748
#7  0x000000000040382a in _cons (sc=sc@entry=0x7fffaa0c9e70,
a=0x1f22bd0, b=0x1f77e90, immutable=immutable@entry=0) at scheme.c:806
#8  0x00000000004039ff in s_save (sc=sc@entry=0x7fffaa0c9e70,
op=op@entry=OP_RDLIST, args=0x1f77e60, code=<optimized out>) at
scheme.c:2470
#9  0x0000000000406d66 in opexe_5 (sc=0x7fffaa0c9e70, op=<optimized
out>) at scheme.c:4156
#10 0x0000000000403efa in Eval_Cycle (sc=sc@entry=0x7fffaa0c9e70,
op=op@entry=OP_T0LVL) at scheme.c:4467
#11 0x000000000040a718 in scheme_load_named_file
(sc=sc@entry=0x7fffaa0c9e70, fin=fin@entry=0x1f791e0,
filename=<optimized out>, filename@entry=0x40b252 "init.scm")
    at scheme.c:482

Sanel

Discussion

  • Dimitrios Souflis

    Safe_free() should free() the same pointer returned by the malloc() inside safe_malloc(), which is passed as the 'p' parameter. Instead, it tries to free() whatever is contained in the first bytes pointed to by 'p'. The custom deallocator should have the same signature as 'free' itself, i.e. it takes the pointer and not a reference to the pointer.

    The correct example for safe_free() would be:

    void safe_free (void *p)
    {
          if (p)
          {
                free (p);
          }
    }
    
     
  • Sanel Zukan

    Sanel Zukan - 2013-03-20

    Yup, I got aware of this a couple hours later (also Richard mailed me pointing me to the same issue).

    After spending the whole day hacking Mutt mail client, I didn't check how they are using allocators, but blindly integrated it... which caused spending a couple of hours chasing nonexisting GC bug :)

    Thanks for reply!
    (please close this ticket as invalid)

     
  • Kevin Cozens

    Kevin Cozens - 2013-03-20
    • status: open --> closed-invalid
    • milestone: -->
     
  • Kevin Cozens

    Kevin Cozens - 2013-03-20

    Closing report as invalid.

     

Log in to post a comment.