=?koi8-r?Q?Re[2]=3A_[Gc]_Occasionally_crash_with_GraphicsMagick, _ImageMagick.?=

Ivan Maidanski ivmai at mail.ru
Thu May 6 02:47:56 PDT 2010


Thu, 6 May 2010 09:17:32 +0000 (GMT) Shi Jie Gung <ksc91u_fr at yahoo.fr>:

> --- On Thu, 5/6/10, Boehm, Hans <hans.boehm at hp.com>  wrote:
> 
> > From: Boehm, Hans <hans.boehm at hp.com>
> > Subject: RE: [Gc] Occasionally crash with GraphicsMagick, ImageMagick.
> > To: "Shi Jie Gung" <ksc91u_fr at yahoo.fr>, "gc at napali.hpl.hp.com" <gc at napali.hpl.hp.com>
> > Date: Thursday, May 6, 2010, 3:32 AM
> > My guess is that you are deallocating
> > an object that was allocated using the system malloc or some
> > other means.  You can confirm by invoking GC_base on
> > the objects that's about to be deallocated.  If it
> > returns 0, it doesn't belong to the collector.
> >
> > The object may be allocated in some other library, where
> > you are not intercepting calls.  Or you might be
> > allocating using other libc calls, like strdup() or
> > memalign(), that you are not currently intercepting.
> >
> > Hans
> 
> You meant that there are some objects allocated by system's malloc and freed by gc_free?
> But I could not find anywhere in graphicsmagick's source code that calls malloc, every memory allocation calls the function I set by MagickAllocFunctions.
> 
> Here is another stack tracce from debug version of graphicsmagick and debug version of gc.
> 
> 
> 
> Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
> 0x00000001002fb0c3 in GC_remove_from_fl (hhdr=0x1009f0930, n=-1) at allchblk.c:316
> 316             nhdr -> hb_prev = hhdr -> hb_prev;
> (gdb) bt
> #0  0x00000001002fb0c3 in GC_remove_from_fl (hhdr=0x1009f0930, n=-1) at allchblk.c:316
> #1  0x00000001002fbf07 in GC_freehblk (hbp=0x100cbf000) at allchblk.c:859
> #2  0x000000010030cd21 in GC_reclaim_block (hbp=0x100cbf000, report_if_found=0) at reclaim.c:311
> #3  0x0000000100303657 in GC_apply_to_all_blocks (fn=0x10030cb25 <GC_reclaim_block>, client_data=0) at headers.c:319
> #4  0x000000010030d1c3 in GC_start_reclaim (report_if_found=0) at reclaim.c:518
> #5  0x00000001002fd033 in GC_finish_collection () at alloc.c:885
> #6  0x00000001002fc6eb in GC_try_to_collect_inner (stop_func=0x1002fbfea <GC_never_stop_func>) at alloc.c:467
> #7  0x00000001002fd381 in GC_try_to_collect_general (stop_func=0, force_unmap=0) at alloc.c:967
> #8  0x00000001002fd417 in GC_gcollect () at alloc.c:993
> #9  0x0000000100000eb0 in main (argc=2, argv=0x7fff5fbff240) at main.cpp:103
> Current language:  auto; currently c
> (gdb) print nhdr
> $1 = (hdr *) 0x0
> (gdb) print hhdr
> $2 = (hdr *) 0x1009f0930
> 
> 
> So why kernel complain can not access 0x08 but print nhdr says 0x0?
> 
> (gdb) print nhdr->hb_prev
> Cannot access memory at address 0x8
> (gdb) print nhdr
> $3 = (hdr *) 0x0

Because the offset of hb_prev is 8. The problem is: GET_HDR(hhdr -> hb_next) returns 0 but hhdr -> hb_next is not 0, so it points to a block which is not allocated by GC.

Nobody says GC is free of bugs. Please try to discover the problem's source.

I'd suggest the following:
1. First, use NON-debug versions of GC_free and friends in all places (and define free() as GC_free()).
2. Instead of GC_realloc() use your own version which does GC_malloc, memcpy and GC_free.
3. Compile GC with -DGC_ASSERTIONS and without -DNO_DEBUGGING -DTHREAD_LOCAL_ALLOC -DPARALLEL_MARK -DUSE_MUNMAP.
4. Use your own wrappers for GC_malloc/realloc/free which print returned/passed addrs (to ensure that a value passed to GC_free is exactly as previously returned by some GC_malloc).



More information about the Gc mailing list