FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[Bug]: SIGSEGV on ft2font under certain compilation conditions · Issue #29976 · matplotlib/matplotlib · GitHub

Repository navigation

[Bug]: SIGSEGV on ft2font under certain compilation conditions #29976

Closed

Description

Bug summary

Running ft2font import through pytest with pytest-cov plugin causes Python to crash.

Code for reproduction

MRE:

from matplotlib import ft2font

def test_dummy():
	pass

print('unreachable')

Env:

python3 -m venv ./venv
source ./venv/bin/activate.fish
pip install matplotlib pytest pytest-cov
pytest ./segft2.py

Actual outcome

====================================== test session starts =======================================
platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.5.0
rootdir: /home/mmatous/playground/segft2
plugins: cov-6.1.1
collecting ... fish: Job 1, 'pytest ./segft2.py' terminated by signal SIGSEGV (Address boundary error)

Expected outcome

====================================== test session starts =======================================
platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.5.0
rootdir: /home/mmatous/playground/segft2
collected 1 item

segft2.py .                                                                                [100%]

======================================= 1 passed in 0.09s ========================================

Additional information

  • Uninstalling pytest-cov makes dummy test pass.
  • matplotlib-3.9.4 is unaffected.
  • matplotlib-3.10.0 is affected.
  • main HEAD (828ec6f) is affected.
  • Persists even after copying system ft2font.*.so into venv (so not simply broken wheels).
  • Possibly not related to pytest specifically, but being run as subprocess or being loaded multiple times in general? I encounter the same problem when trying to build doc. with tox run -e docs-dev while setting up https://pydata-sphinx-theme.readthedocs.io/en/latest/community/setup.html#build-the-documentation where MPL is a dependency.
  • CPU: AMD Ryzen 9 7950X (in case it's some weird hw/simd/optimization thing)
  • Feel free to ask for more info, I don't know much about debugging C/Python boundary, so for now here's an LLDB backtrace:
(lldb) bt
* thread #1, name = 'pytest', stop reason = SIGSEGV: address not mapped to object (fault address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x00007f211fd9dc00 libunwind.so.8`_ULx86_64_dwarf_find_proc_info(as=0x00007ffd900eb900, ip=140727020337416, pi=0x00007ffd900eb958, need_unwind_info=1, arg=<unavailable>) at Gfind_proc_info-lsb.c:807:9
    frame #2: 0x00007f211fd9e817 libunwind.so.8`fetch_proc_info(c=0x00007ffd900eb800, ip=<unavailable>) at Gparser.c:473:18
    frame #3: 0x00007f211fd96e73 libunwind.so.8`_Unwind_GetLanguageSpecificData [inlined] _ULx86_64_dwarf_make_proc_info(c=<unavailable>) at Gparser.c:1089:9
    frame #4: 0x00007f211fd96e61 libunwind.so.8`_Unwind_GetLanguageSpecificData [inlined] _ULx86_64_get_proc_info(cursor=<unavailable>, pi=<unavailable>) at Gget_proc_info.c:35:7
    frame #5: 0x00007f211fd96e61 libunwind.so.8`_Unwind_GetLanguageSpecificData(context=<unavailable>) at GetLanguageSpecificData.c:34:3
    frame #6: 0x00007f211eee32dd libstdc++.so.6`__gxx_personality_v0 + 285
    frame #7: 0x00007f211fd7f6dc libgcc_s.so.1`___lldb_unnamed_symbol337 + 156
    frame #8: 0x00007f211fd80001 libgcc_s.so.1`_Unwind_Resume + 161
    frame #9: 0x00007f20ca1fb720 ft2font.cpython-313-x86_64-linux-gnu.so`ft2font__getattr__(std::string) (.lto_priv.0.cold) + 81
    frame #10: 0x00007f20ca2351c6 ft2font.cpython-313-x86_64-linux-gnu.so`void pybind11::cpp_function::initialize<pybind11::object (*&)(std::string), pybind11::object, std::string, pybind11::name, pybind11::scope, pybind11::sibling>(pybind11::object (*&)(std::string), pybind11::object (*)(std::string), pybind11::name const&, pybind11::scope const&, pybind11::sibling const&)::'lambda1'(pybind11::detail::function_call&)::_FUN(pybind11::detail::function_call&) + 454
    frame #11: 0x00007f20ca20ba3d ft2font.cpython-313-x86_64-linux-gnu.so`pybind11::cpp_function::dispatcher(_object*, _object*, _object*) + 3373
    frame #12: 0x00007f21219587f7 libpython3.13.so.1.0`cfunction_call(func=0x00007f20ca3c3880, args=0x0000000000000000, kwargs=0x0000000000000000) at methodobject.c:540:18

Operating system

Gentoo

Matplotlib Version

3.10.1

Matplotlib Backend

tkagg

Python version

Python 3.13.3

Jupyter version

No response

Installation

pip

Activity

  1. mmatous commented on Apr 28, 2025

    Author

    Bisected. Bad commit: 9e02512

    py::attribute_error: module 'matplotlib.ft2font' has no attribute '__path__' gets thrown but something something got messed up during unwinding and it resulted in segfault and ended up hidden.

  2. added this to the v3.10.2 milestone on Apr 28, 2025
  3. tacaswell commented on Apr 28, 2025

    Member

    Interesting. Curious if this is an mpl bug, a pytest-cov bug, or a pybind11 bug.

  4. tacaswell commented on Apr 28, 2025

    Member

    That said, I can not reproduce this with wheels and Python from fedora

    (segfault) /tmp 
    ✔ 10:55:20 [yennefer] @ pytest tests.py
    ============================= test session starts ==============================
    platform linux -- Python 3.13.2, pytest-8.3.5, pluggy-1.5.0
    rootdir: /tmp
    plugins: cov-6.1.1
    collected 1 item                                                               
    
    tests.py .                                                               [100%]
    
    ============================== 1 passed in 0.13s ===============================
    (segfault) /tmp 
    ✔ 10:55:27 [yennefer] @ pip list
    Package         Version
    --------------- -----------
    contourpy       1.3.2
    coverage        7.8.0
    cycler          0.12.1
    fonttools       4.57.0
    iniconfig       2.1.0
    kiwisolver      1.4.8
    matplotlib      3.10.1
    numpy           2.2.5
    packaging       25.0
    pillow          11.2.1
    pip             24.2
    pluggy          1.5.0
    pyparsing       3.2.3
    pytest          8.3.5
    pytest-cov      6.1.1
    python-dateutil 2.9.0.post0
    six             1.17.0
    (segfault) /tmp 
    ✔ 10:55:58 [yennefer] @
    
    
  5. mmatous commented on Apr 28, 2025

    Author

    Do you get the same query for __path__ attr that triggers the exception? And it proceeds to be handled just fine?

  6. tacaswell commented on Apr 28, 2025

    Member

    I see the attribute error, but it does not get turned into a segfault:

    (segfault) /tmp 
    ✔ 10:55:58 [yennefer] @ python
    Python 3.13.2 (main, Feb  4 2025, 00:00:00) [GCC 14.2.1 20250110 (Red Hat 14.2.1-7)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import matplotlib.ft2font
    >>> matplotlib.ft2font.__path__
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        matplotlib.ft2font.__path__
    AttributeError: module 'matplotlib.ft2font' has no attribute '__path__'. Did you mean: '__name__'?
    >>> 
    
    
  7. QuLogic commented on Apr 28, 2025

    Member

    import matplotlib.ft2font
    matplotlib.ft2font.path

    FWIW, I also tried this in valgrind, and didn't see any memory issues.

  8. mmatous commented on Apr 28, 2025

    Author

    Still digging. Currently dealing with libunwind. Pretty sure it's not MPL, but I'm not done just yet. There's an instance of iterate_phdr_function ptr being null, when it should point to a libc's dl_iterate_phdr(). I'm gonna get back to you after I know more, feel free to ignore until then.

  9. removed this from the v3.10.2 milestone on Apr 29, 2025
  10. mmatous commented on Apr 30, 2025

    Author

    TLDR; rebuilding with clang fixes the issue, but I'm not sure about the underlying cause.

    In case someone's affected by the same issue and is determined to actually solve it:

    When handling an exception passing C/Python boundary, libunwind tried to call a function stored in a struct as a pointer and in this case, the pointer was null. libunwind is not at fault, I tried various versions and even switched to LLVM's libunwind to make sure. Said struct seems to be at least partially based on info passed from libgcc_s.so and it was already malformed when received.

    The fixed, clang-compiled, mpl still links to the exact same libgcc_s.so, so I can't say that was the problem either. In any case it's almost certainly not a matplotlib problem, perhaps pybind11.

    Thank you for your help.

  11. tacaswell commented on Jul 7, 2025

    Member

    @mmatous To verify the thing you recompiled with clang was Matplotlib (not CPython)?

  12. mmatous commented on Jul 7, 2025

    Author

    MPL, yes. I tried recompiling python, libunwind and other possible suspects with different compilers or compiler options (all at once, to prevent possible incompatibilities) and that achieved nothing. Copying clang'ed ft2font.cpython-313-x86_64-linux-gnu.so into my venv served as a workaround.

  13. QuLogic commented on Jul 7, 2025

    Member

    Does your gcc default to -fno-exceptions or some similar option?

  14. 19 remaining items

  15. QuLogic commented on Jul 18, 2025

    Member

    They do.

    OK, that's both good and bad news. We can't really get rid of the exceptions in ft2font until the deprecations expire in 3.12, or possibly if pybind/pybind11#1853 were implemented first. But since it will also fail in other cases, that means I won't spend any time trying to workaround the deprecations.

    I can perhaps suspect that pybind/pybind11#5359 might be related, but I don't know that anything in pytest(-cov) would have loaded anything else that uses pybind11. But possibly this issue is still related as something may still not be specifying exception ABI somehow.

    pybind11 has a new major version. Might be worth giving it a try. Def. ping me once you have a version that's compatible with it, I'll see if it solves the issue.

    We've already been building main and v3.10.x against it since it came out, so I don't think there would be anything preventing you testing v3.10.3 with it. That being said, I did open #30291 to take advantage of the new features in pybind11 v3 which you may want to try, though I don't think there's anything exception-related there.

  16. modified the milestones: v3.10.4, v3.10.5 on Jul 25, 2025
  17. PhilipDeegan commented on Jul 27, 2025

    I should also add, that the exceptions from ft2font interferes with the use of ASAN, and forces an exit on the first exception , at least with default configurations

  18. modified the milestones: v3.10.6, v3.10.7 on Aug 29, 2025
  19. modified the milestones: v3.10.7, v3.10.8 on Oct 8, 2025
  20. modified the milestones: v3.10.8, v3.10.9 on Nov 13, 2025
  21. removed this from the v3.10.9 milestone on May 1, 2026
  22. QuLogic commented on Jul 10, 2026

    Member

    The module-level __getattr__ was removed in #31879, so there should no longer be any exceptions at import time with 3.12.

  23. added this to the v3.12.0 milestone on Jul 10, 2026
  24. QuLogic commented on Aug 20, 2026

    Member

    I've been investigating this again due to a downstream report in Fedora. This only affected ppc64le and no other architectures. It turns out that the problem there was that libunwind was compiled with its C++ exception support enabled on the one architecture (due to some autodetection).

    Upstream has also disabled C++ exception support by default, but this isn't in a release yet, so I suggest that wherever you got libunwind from probably is leaving it at the default autodetect and/or enabling it explicitly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL