llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.64k stars 11.84k forks source link

[mlir][python] Lifetime issue with nested object references can lead to crash #63920

Open rkayaith opened 1 year ago

rkayaith commented 1 year ago

Right now the top-level PyOperation will delete the underlying IR object when it's collected, but child PyOperations aren't keeping the parent PyOperation alive:

import weakref
import gc
from mlir import ir
from mlir.dialects import builtin

with ir.Context():
  mod_op = builtin.ModuleOp.parse("""
    module {
      func.func @foo() {
        return
      }
    }
  """)
  func_op = mod_op.body.operations[0]
  ret_op = func_op.body.blocks[0].operations[0]

  mod_ref = weakref.ref(mod_op, lambda _: print("module was finalized"))
  func_ref = weakref.ref(func_op, lambda _: print("func was finalized"))
  ret_ref = weakref.ref(ret_op, lambda _: print("return was finalized"))

  # Delete module reference.
  del mod_op; gc.collect()

  # Try accessing child operation.
  print(func_op)

output:

module was finalized
Segmentation fault (core dumped)

Ideally the reference to the nested op should keep parent IR objects alive, or at least the nested PyOperation should be set to invalid when its parent is erased.

Seems related to TODO comment here: https://github.com/llvm/llvm-project/blob/5784c47806cf276e8fcc1311201f437cb8169261/mlir/lib/Bindings/Python/IRCore.cpp#L1430-L1432

llvmbot commented 1 year ago

@llvm/issue-subscribers-mlir-python