Skip to content
  • Kirill Smelkov's avatar
    bigfile/py: Properly untrack PyVMA from GC before dealloc · d97641d2
    Kirill Smelkov authored
    On a testing instance we started to see segfaults in pyvma_dealloc()
    with inside calls to vma_unmap but with NULL pyvma->fileh. That was
    strange, becuse before calling vma_unmap(), the code explicitly checks
    whether pyvma->fileh is !NULL.
    
    That was, as it turned out, due to pyvma_dealloc being called twice at the
    same time from two python threads. Here is how that was possible:
    
    T1 decrefs pyvma and finds its reference count drops to zero. It calls
    pyvma_dealloc. From there vma_unmap() is called, which calls virt_lock()
    and that releases GIL first. Another thread T2 was waiting for GIL, it
    acquires it, does some work at python level and somehow triggers GC.
    Since PyVMA supports cyclic GC, it was on GC list and thus GC calls
    dealloc for the same vma again. Here is how it looks in the backtraces:
    
    T1:
    
    	#0  0x00007f6aefc57827 in futex_abstimed_wait_cancelable (private=0, abstime=0x0, expected=0, futex_word=0x1e011d0) at ../sysdeps/unix/sysv/linux/fut...
    d97641d2