Fedora Account System
Red Hat Associate
Red Hat Customer
python-contourpy failed to build from source in Fedora rawhide/f44 https://koji.fedoraproject.org/koji/taskinfo?taskID=141193041 For details on the mass rebuild see: https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild Please fix python-contourpy at your earliest convenience and set the bug's status to ASSIGNED when you start fixing it. If the bug remains in NEW state for 8 weeks, python-contourpy will be orphaned. Before branching of Fedora 45, python-contourpy will be retired, if it still fails to build. For more details on the FTBFS policy, please visit: https://docs.fedoraproject.org/en-US/fesco/Fails_to_build_from_source_Fails_to_install/
Created attachment 2126664 [details] build.log file build.log too big, will only attach last 32768 bytes
Created attachment 2126665 [details] root.log file root.log too big, will only attach last 32768 bytes
Created attachment 2126666 [details] state.log
I have skipped the tests for now in https://src.fedoraproject.org/rpms/python-contourpy/pull-request/9 but leaving this open.
I'm reassigning to gcc, not because I'm certain it's a compiler bug, but because it's architecture specific and I have run out of other ideas. You can see my other investigations on the linked upstream bug report, but the last thing I've found is this: the crash occurs in `cntr_trace` which does two pass. The first pass calls `curve_tracer` repeatedly until it returns 0, sums up the results, allocates a buffer of that size, and then the second pass calls `curve_tracer` again and fills up the buffers. It is on the second pass that something goes wrong and more entries seem to be needed than originally thought. if I look at this in gdb: # gdb /usr/bin/python3 (gdb) br curve_tracer (gdb) run /usr/bin/pytest tests/test_minimal.py ... tests/test_minimal.py::test_minimal_lines[mpl2005-SeparateCode] Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1474 1474 if (!n) Value returned is $1 = 5 (gdb) c Continuing. Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1474 1474 if (!n) Value returned is $2 = 2 (gdb) c Continuing. Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=0) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1474 1474 if (!n) Value returned is $3 = 0 (gdb) c Continuing. the first pass returns 5, 2, 0, then: Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1500 1500 if (ntotal2 + n > ntotal) Value returned is $4 = 5 (gdb) c Continuing. Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1500 1500 if (ntotal2 + n > ntotal) Value returned is $5 = 2 (gdb) c Continuing. Thread 1 "python3" hit Breakpoint 1, contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 780 { (gdb) fin Run till exit from #0 contourpy::curve_tracer (site=site@entry=0x2aa0051f060, pass2=pass2@entry=1) at ../../src/mpl2005_original.cpp:780 contourpy::cntr_trace (site=<optimized out>, levels=levels@entry=0x3ffffff4900, nlevels=nlevels@entry=1) at ../../src/mpl2005_original.cpp:1500 1500 if (ntotal2 + n > ntotal) Value returned is $6 = 0 and the second pass return 5, 2, 0, but if I continue on: (gdb) s 1504 if (n == 0) (gdb) s 1506 if (n > 0) (gdb) s 1509 nseg0[iseg] = n; (gdb) p n $7 = 0 The lines referenced above are: 1500 if (ntotal2 + n > ntotal) 1501 { 1502 throw std::runtime_error("curve_tracer: ntotal2, pass 2 exceeds ntotal, pass 1"); 1503 } 1504 if (n == 0) 1505 break; 1506 if (n > 0) 1507 { 1508 /* could add array bounds checking */ Even though n is supposedly 0, the condition on line 1504 doesn't trigger to break out of the loop. As noted in the upstream issue, this only occurs at -O2 level, but works fine at -O1. If there is any undefined behaviour being triggered, there are no warnings being produced that could indicate it (with either gcc or clang). Unfortunately, I don't really have a way to pare this down into a pure C++ test case.
Of course, after writing all that up, I found bug 2491178, which is a similar thing in veusz. In fact, they bundle the same code that came from Matplotlib and was spun out into contourpy (and maybe they should use that, but that's not relevant here.) So I'll just link to the same upstream gcc bug.
Based on the upstream bug report and current builds of gcc, I think this should have been fixed in Rawhide. I do not believe a corresponding backport/build was made in F44.
This bug appears to have been reported against 'rawhide' during the Fedora Linux 45 development cycle. Changing version to 45.
FEDORA-2026-1882746a40 (python-contourpy-1.3.3-9.fc44) has been submitted as an update to Fedora 44. https://bodhi.fedoraproject.org/updates/FEDORA-2026-1882746a40
FEDORA-2026-1882746a40 has been pushed to the Fedora 44 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-1882746a40` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-1882746a40 See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2026-12a5c4eff1 has been pushed to the Fedora 44 testing repository. Soon you'll be able to install the update with the following command: `sudo dnf upgrade --enablerepo=updates-testing --refresh --advisory=FEDORA-2026-12a5c4eff1` You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2026-12a5c4eff1 See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.
FEDORA-2026-12a5c4eff1 (python-contourpy-1.4.0-1.fc44) has been pushed to the Fedora 44 stable repository. If problem still persists, please make note of it in this bug report.