PyO3 / PyO3/pyo3

Misaligned pointer dereference at interpreter finalization when using `PyTzInfo` subclass in dev mode

Open
#6,110 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
16.2k
Forks
1k
Avg merge
2d 6h
Merged PRs (30d)
66

Description

Bug Description

This was originally reported in https://github.com/pydantic/pydantic/issues/12867, and then in https://github.com/pydantic/pydantic/issues/12867.

When defining a Pyo3 class extending PyTzInfo:

use pyo3::prelude::*;
use pyo3::types::{PyDelta, PyTzInfo};

#[pyclass(module = "tzinfo_mre", extends = PyTzInfo, frozen)]
pub struct TzInfo {
    seconds: i32,
}

Referencing an instance of this class as a class attribute somewhere in Python:

class R:
    instance = TzInfo()

Crashes at interpreter finalization, only in development mode:

$ PYTHONDEVMODE=1 python repro.py
misaligned pointer dereference: address must be a multiple of 0x8 but is 0xdddddddddddddddd
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
Fatal Python error: Aborted

Current thread 0x0000000209ba3100 (most recent call first):
  Garbage-collecting
  <no Python frame>

This does not reproduce on Python >= 3.13.

https://github.com/Viicos/pyo3-tzinfo-mre provides a MRE (the stuff with logging is necessary to reproduce).

Claude came up with this fix, but I'm not knowledgeable enough to know if it took the right approach.

Steps to Reproduce

See https://github.com/Viicos/pyo3-tzinfo-mre.

Backtrace
thread '<unnamed>' (60753294) panicked at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-ffi-0.28.3/src/refcount.rs:237:13:
misaligned pointer dereference: address must be a multiple of 0x8 but is 0xdddddddddddddddd
stack backtrace:
   0:        0x1059db0a0 - std[bb513d90a5cee88a]::backtrace_rs::backtrace::libunwind::trace
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1:        0x1059db0a0 - std[bb513d90a5cee88a]::backtrace_rs::backtrace::trace_unsynchronized::<std[bb513d90a5cee88a]::sys::backtrace::_print_fmt::{closure#1}>
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14
   2:        0x1059db0a0 - std[bb513d90a5cee88a]::sys::backtrace::_print_fmt
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/backtrace.rs:74:9
   3:        0x1059db0a0 - <<std[bb513d90a5cee88a]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[f63e075e1375d836]::fmt::Display>::fmt
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/backtrace.rs:44:26
   4:        0x1059e9460 - <core[f63e075e1375d836]::fmt::rt::Argument>::fmt
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/fmt/rt.rs:152:76
   5:        0x1059e9460 - core[f63e075e1375d836]::fmt::write
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/fmt/mod.rs:1686:22
   6:        0x1059de76c - std[bb513d90a5cee88a]::io::default_write_fmt::<std[bb513d90a5cee88a]::sys::stdio::unix::Stderr>
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/io/mod.rs:639:11
   7:        0x1059de76c - <std[bb513d90a5cee88a]::sys::stdio::unix::Stderr as std[bb513d90a5cee88a]::io::Write>::write_fmt
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/io/mod.rs:1994:13
   8:        0x1059cb764 - <std[bb513d90a5cee88a]::sys::backtrace::BacktraceLock>::print
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/backtrace.rs:47:25
   9:        0x1059cb764 - std[bb513d90a5cee88a]::panicking::default_hook::{closure#0}
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:292:27
  10:        0x1059d6fa8 - std[bb513d90a5cee88a]::panicking::default_hook
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:319:9
  11:        0x1059d72d0 - std[bb513d90a5cee88a]::panicking::panic_with_hook
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:825:13
  12:        0x1059cb810 - std[bb513d90a5cee88a]::panicking::panic_handler::{closure#0}
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:698:13
  13:        0x1059c34fc - std[bb513d90a5cee88a]::sys::backtrace::__rust_end_short_backtrace::<std[bb513d90a5cee88a]::panicking::panic_handler::{closure#0}, !>
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/sys/backtrace.rs:182:18
  14:        0x1059cbde8 - __rustc[b7974e8690430dd9]::rust_begin_unwind
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:689:5
  15:        0x1059f30ec - core[f63e075e1375d836]::panicking::panic_nounwind_fmt::runtime
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/panicking.rs:122:22
  16:        0x1059f30ec - core[f63e075e1375d836]::panicking::panic_nounwind_fmt
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/intrinsics/mod.rs:2447:9
  17:        0x1059f3240 - core[f63e075e1375d836]::panicking::panic_misaligned_pointer_dereference
                               at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/panicking.rs:284:5
  18:        0x10599408c - pyo3_ffi::refcount::Py_INCREF::h86ab68b2c909c5db
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-ffi-0.28.3/src/refcount.rs:237:13
  19:        0x10599408c - pyo3::instance::Py<T>::clone_ref::h61e343a6d4a417b6
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/instance.rs:1764:18
  20:        0x105995cd4 - <pyo3::instance::Bound<T> as core::clone::Clone>::clone::h2b694eb66075ef9e
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/instance.rs:824:47
  21:        0x10599578c - pyo3::instance::Borrowed<T>::to_owned::h869119ab9f3474bb
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/instance.rs:986:17
  22:        0x10598fd60 - pyo3::type_object::PyTypeInfo::type_object::hdfdc3f9bf8dc2a75
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/type_object.rs:78:18
  23:        0x10598bcb0 - <pyo3::pycell::impl_::PyClassObjectBase<U> as pyo3::pycell::impl_::PyClassObjectBaseLayout<T>>::tp_dealloc::h416fec5d657e3245
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/pycell/impl_.rs:231:35
  24:        0x10598bd80 - <pyo3::pycell::impl_::PyStaticClassObject<T> as pyo3::pycell::impl_::PyClassObjectBaseLayout<T>>::tp_dealloc::h858e29c55e6bf137
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/pycell/impl_.rs:466:18
  25:        0x10598d0ec - pyo3::impl_::trampoline::dealloc::{{closure}}::h51b9b5d59bac43e1
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/impl_/trampoline.rs:231:17
  26:        0x10598cfc4 - pyo3::impl_::trampoline::trampoline_unraisable::{{closure}}::hc67d4f5e403f8d81
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/impl_/trampoline.rs:316:54
  27:        0x10598bf74 - std::panicking::catch_unwind::do_call::h4f578a919b921b15
                               at /Users/victorien/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:581:40
  28:        0x105990544 - ___rust_try
  29:        0x105990384 - std::panicking::catch_unwind::h89de98613e181bdd
                               at /Users/victorien/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:544:19
  30:        0x105990384 - std::panic::catch_unwind::h990676cb90cb89c4
                               at /Users/victorien/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
  31:        0x10598ce2c - pyo3::impl_::trampoline::trampoline_unraisable::hffe3fa98a693ea02
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/impl_/trampoline.rs:316:26
  32:        0x10598dfb0 - pyo3::impl_::trampoline::dealloc::h0d1d14ed1fe5f20b
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/impl_/trampoline.rs:229:9
  33:        0x10598c3fc - pyo3::impl_::pyclass::tp_dealloc::h09b4410e9b73e878
                               at /Users/victorien/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pyo3-0.28.3/src/impl_/pyclass.rs:1123:14
  34:        0x1061b2190 - _dictkeys_decref
  35:        0x1061b1cac - _type_clear
  36:        0x1062e3950 - _gc_collect_main
  37:        0x106322ea0 - _finalize_modules
  38:        0x1062f3768 - _Py_FinalizeEx
  39:        0x1063502e0 - _Py_RunMain
  40:        0x1062ff274 - _pymain_main
  41:        0x1062ff068 - _Py_BytesMain
thread caused non-unwinding panic. aborting.
Fatal Python error: Aborted

Current thread 0x0000000209ba3100 (most recent call first):
  Garbage-collecting
  <no Python frame>
Your operating system and version

MacOS

Your Python version (python --version)

3.11/3.12

Your Rust version (rustc --version)

rustc 1.95.0 (59807616e 2026-04-14)

Your PyO3 version

28.0

How did you install python? Did you use a virtualenv?

uv

Additional Info

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the deallocation path in pyo3-ffi/src/refcount.rs and the PyO3 files named in the backtrace, especially pycell/impl_.rs and type_object.rs. Reproduce the crash using the pyo3-tzinfo-mre project with Python 3.11 or 3.12 in development mode, then verify that interpreter finalization completes without aborting.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.