[BUG]: Constructor for type_caster<std::vector<std::shared_ptr<T>>> Never Called
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
8d16d2084a37adc5ce400dc3411386ae38bfd365
Problem description
I ran across an odd problem in my project which is resulting in segfaults on both Windows and MacOS. I finally realized that I could reproduce same problem on Fedora 44 when building in Debug mode. In GDB, it appeared that in the list_caster::convert_elements method, when trying to call value.clear(), the vector value has a size which is very large, but value.data() = 0. Of course, when trying to clear, it de-references nullptr and gives the segfault. I made a special branch of pybind11 where all I did was add print statements into the constructors and destructors of type_caster<std::vector<Type, Alloc>>, and a message in list_caster::convert_elements. When running the attached test file with my project, I get the following output:
[<scarabee._scarabee.CrossSection object at 0x7efd1e5d48f0>, <scarabee._scarabee.CrossSection object at 0x7efd1e5d48f0>, <scarabee._scarabee.CrossSection object at 0x7efd1e402970>, <scarabee._scarabee.CrossSection object at 0x7efd1e402970>]
pre build U2
>>> VECTOR TYPE_CASTER CTOR
Type = St10shared_ptrIN8scarabee12CrossSectionEE
this = 0x7fff4def7850
>>> VECTOR TYPE_CASTER CTOR
Type = d
this = 0x7fff4def7868
>>> N8pybind116detail11list_casterISt6vectorIdSaIdEEdEE::convert_elements
this = 0x7fff4def7868, value.size() = 0, value.data() = 0
>>> N8pybind116detail11list_casterISt6vectorISt10shared_ptrIN8scarabee12CrossSectionEESaIS6_EES6_EE::convert_elements
this = 0x7fff4def7850, value.size() = 0, value.data() = 0
>>> Pre PinCell construction <<<
>>> Post PinCell construction <<<
>>> VECTOR TYPE_CASTER DTOR
Type = d
this = 0x7fff4def7868
>>> VECTOR TYPE_CASTER DTOR
Type = St10shared_ptrIN8scarabee12CrossSectionEE
this = 0x7fff4def7850
post build U2
This makes perfect sense, as I see the constructor for both vector type_casters which appear in the bindings for PinCell() as can been seen in this file. However, when I compile in Debug mode, I get the following output:
[<scarabee._scarabee.CrossSection object at 0x7faf8f9d48f0>, <scarabee._scarabee.CrossSection object at 0x7faf8f9d48f0>, <scarabee._scarabee.CrossSection object at 0x7faf8f802970>, <scarabee._scarabee.CrossSection object at 0x7faf8f802970>]
pre build U2
>>> VECTOR TYPE_CASTER CTOR
Type = d
this = 0x7fff1dd22b88
>>> N8pybind116detail11list_casterISt6vectorIdSaIdEEdEE::convert_elements
this = 0x7fff1dd22b88, value.size() = 0, value.data() = 0
>>> N8pybind116detail11list_casterISt6vectorISt10shared_ptrIN8scarabee12CrossSectionEESaIS6_EES6_EE::convert_elements
this = 0x7fff1dd22b70, value.size() = 8774500071021, value.data() = 0
Segmentation fault (core dumped) python test.py
Here, we can see that the constructor for type_caster<std::vector<std::shared_ptr<CrossSection>>> was never called, but we try to use it anyway ! This is of course why the value vector is holding nonsense, as the memory has not been initialized. I tried building my project with the undefined behavior sanitizers, and I do not get any flags, apart from when the never constructed type caster tries to de-reference memory it does not actually have. I believe that this is also the reason why my GitHub action is failing on Windows (thought I don't have ready access to a Windows machine at the moment to test and confirm).
I would have initially thought this was a compiler bug, but given Windows also seems to be having an issue, I am not sure that is the case. I am also very surprised that on Fedora, this only happens in Debug mode, and not Release (I would have been less surprised in the other case).
I must apologize for not being able to provide a smaller working example. I tried several times to break out only one or two classes into a single .cpp, but whenever I do this, the bug does not appear. Using the branch of my project in the linked PR along with the provided script on a Linux machine will hopefully reproduce the problem (I am on Fedora 44 with g++ 16.2.1). I tried using older 3.0.x versions of Pybind11, and also got this same error.
Reproducible example code
Is this a regression? Put the last known working version here if it is.
Not a regression
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with the linked scarabee branch and test.py, then inspect list_caster::convert_elements and the vector type_caster constructors. Compare the Debug and Release output and use the pin_cell.cpp bindings as the entry point; done requires an isolated reproduction and a validated fix for the unconstructed caster failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100