pybind / pybind/pybind11

[BUG]: Constructor for type_caster<std::vector<std::shared_ptr<T>>> Never Called

Open
#6,178 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

Required prerequisites
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.

test.py

Reproducible example code

Is this a regression? Put the last known working version here if it is.

Not a regression

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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.