exaloop / exaloop/codon

[Bug Report] GC Crash in Multithreaded Python Program Using @codon.convert Class + Python Object + ThreadPoolExecutor

Open
#773 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.8k
Forks
603
Avg merge
4d 23h
Merged PRs (30d)
6

Description

### **Problem Description**
I encountered a GC crash (garbage collection segmentation fault) when running a multithreaded Python program using the Codon compiler. The crash occurs during concurrent execution with ThreadPoolExecutor and a @codon.convert decorated class.
### **Environment**
- OS: Debian GNU/Linux 12 (bookworm)
- Codon version: 0.19.3 && the latest version 0.19.6 build from source (develop codon branch)
- Python version: 3.11.10
### **Minimal Reproducible Code**
```
import codon
from concurrent.futures import ThreadPoolExecutor

@codon.convert
class PyMockCPUBusy:
__slots__ = ["compute_iters"]

def __init__(self, compute_iters: int):
self.compute_iters = compute_iters

@codon.jit
def __call__(self, obj):
count = 0
target = self.compute_iters
while count < target:
count += 1
return obj

def worker(tid: int, op: PyMockCPUBusy):
for i in range(20000):
op(None)

if __name__ == "__main__":
num_threads = 16
op = PyMockCPUBusy(100000)

with ThreadPoolExecutor(max_workers=num_threads) as ex:
futures = [ex.submit(worker, tid, op) for tid in range(num_threads)]
for f in futures:
f.result()
```
### **How to Run**
```
python3 test.py
```
### **Crash Frame**
```
Collecting from unknown thread
Aborted (core dumped)
#0 0x00007fff4a360f12 in GC_find_limit_with_bound () from /data00/home/leelee/.codon/lib/codon/libcodonrt.so
#1 0x00007fff4a360d30 in GC_init_linux_data_start () from /data00/home/leelee/.codon/lib/codon/libcodonrt.so
#2 0x00007fff4a35efef in GC_init () from /data00/home/leelee/.codon/lib/codon/libcodonrt.so
#3 0x00007fff4a362218 in GC_add_roots () from /data00/home/leelee/.codon/lib/codon/libcodonrt.so
#4 0x00007fff4d86afb6 in codon::BoehmGCJITLinkMemoryManager::allocate(llvm::jitlink::JITLinkDylib const*, llvm::jitlink::LinkGraph&, llvm::unique_function > >)>) ()
from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#5 0x00007fff522874c2 in llvm::jitlink::JITLinkerBase::linkPhase1(std::unique_ptr >) ()
from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#6 0x00007fff52263f58 in llvm::jitlink::link_ELF_x86_64(std::unique_ptr >, std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#7 0x00007fff5222413a in llvm::jitlink::link_ELF(std::unique_ptr >, std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#8 0x00007fff521ef75d in llvm::jitlink::link(std::unique_ptr >, std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#9 0x00007fff50a31cc8 in llvm::orc::LinkGraphLinkingLayer::emit(std::unique_ptr >, std::unique_ptr >, std::unique_ptr >) ()
from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#10 0x00007fff50a81479 in llvm::orc::ObjectLinkingLayer::emit(std::unique_ptr >, std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#11 0x00007fff50a81849 in llvm::orc::ObjectTransformLayer::emit(std::unique_ptr >, std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#12 0x00007fff50ac76c3 in llvm::orc::IRCompileLayer::emit(std::unique_ptr >, llvm::orc::ThreadSafeModule) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#13 0x00007fff50ac7f47 in llvm::orc::IRTransformLayer::emit(std::unique_ptr >, llvm::orc::ThreadSafeModule) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#14 0x00007fff50ac7f47 in llvm::orc::IRTransformLayer::emit(std::unique_ptr >, llvm::orc::ThreadSafeModule) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#15 0x00007fff50a28537 in llvm::orc::BasicIRLayerMaterializationUnit::materialize(std::unique_ptr >) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#16 0x00007fff509f1a8b in llvm::orc::MaterializationTask::run() () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#17 0x00007fff509f1e41 in llvm::orc::ExecutionSession::dispatchOutstandingMUs() () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#18 0x00007fff509f2f3d in llvm::orc::ExecutionSession::OL_completeLookup(std::unique_ptr >, std::shared_ptr, std::function >, llvm::DenseMapInfo, llvm::detail::DenseMapPair > > > const&)>) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#19 0x00007fff509f3d33 in llvm::orc::InProgressFullLookupState::complete(std::unique_ptr >) ()
from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#20 0x00007fff509f6c93 in llvm::orc::ExecutionSession::OL_applyQueryPhase1(std::unique_ptr >, llvm::Error) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#21 0x00007fff509f73f2 in llvm::orc::ExecutionSession::lookup(llvm::orc::LookupKind, std::vector, std::allocator for more, q to quit, c to continue without paging--
air > > const&, llvm::orc::SymbolLookupSet, llvm::orc::SymbolState, llvm::unique_function, llvm::detail::DenseMapPair > >)>, std::function >, llvm::DenseMapInfo, llvm::detail::DenseMapPair > > > const&)>) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#22 0x00007fff509f7601 in llvm::orc::ExecutionSession::lookup(std::vector, std::allocator > > const&, llvm::orc::SymbolLookupSet, llvm::orc::LookupKind, llvm::orc::SymbolState, std::function >, llvm::DenseMapInfo, llvm::detail::DenseMapPair > > > const&)>) ()
from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#23 0x00007fff509f83ce in llvm::orc::ExecutionSession::lookup(std::vector, std::allocator > > const&, llvm::orc::SymbolStringPtr, llvm::orc::SymbolState) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#24 0x00007fff50a45b66 in llvm::orc::LLJIT::lookupLinkerMangled(llvm::orc::JITDylib&, llvm::orc::SymbolStringPtr) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#25 0x00007fff4d847421 in llvm::orc::LLJIT::lookup(llvm::orc::JITDylib&, llvm::StringRef) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#26 0x00007fff4d845686 in codon::jit::Engine::lookup(llvm::StringRef) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#27 0x00007fff4d84bdf1 in codon::jit::JIT::init(bool) () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
#28 0x00007fff4d84fb16 in jit_init () from /data00/home/leelee/.codon/lib/codon/libcodonc.so
```
### **Key Observations**
1. Crash only happens in **multithreaded mode** (ThreadPoolExecutor with ≥ 2 threads)
2. Crash should Involves:
- @codon.convert class
- @codon.jit method
- **A PyObject Type param needs to be passed in**
3. The code is CPU-bound and does not perform any heap allocation inside the JIT loop

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.