Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: Segfault when getting repr of enum which hasn't been bound #5101

Open
3 tasks done
ascended121 opened this issue Apr 12, 2024 · 0 comments
Open
3 tasks done

[BUG]: Segfault when getting repr of enum which hasn't been bound #5101

ascended121 opened this issue Apr 12, 2024 · 0 comments
Labels
triage New bug, unverified

Comments

@ascended121
Copy link

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

2.11.1

Problem description

When attempting to get the repr of a C++ enum which hasn't been bound, a segfault occurs:

Thread 1 "python3" received signal SIGSEGV, Segmentation fault.
0x00005555556b1e76 in PyObject_GetAttrString (v=0x0, name=0x7ffff6dcd847 "__repr__") at ../Objects/object.c:810
810     ../Objects/object.c: No such file or directory.
(gdb) bt
#0  0x00005555556b1e76 in PyObject_GetAttrString (v=0x0, name=0x7ffff6dcd847 "__repr__") at ../Objects/object.c:810
#1  0x00007ffff6d7e25b in pybind11::getattr (obj=..., name=0x7ffff6dcd847 "__repr__") at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:882
#2  0x00007ffff6d7e92d in pybind11::detail::accessor_policies::str_attr::get (obj=..., key=0x7ffff6dcd847 "__repr__") at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1055
#3  0x00007ffff6da389f in pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr>::get_cache (this=0x7fffffff8ae0) at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1034
#4  0x00007ffff6d9d9e6 in pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr>::ptr (this=0x7fffffff8ae0) at /home/myuser/mylib/.venv/include/pybind11/pytypes.h:1022
#5  0x00007ffff6da0659 in pybind11::detail::object_api<pybind11::detail::accessor<pybind11::detail::accessor_policies::str_attr> >::operator()<(pybind11::return_value_policy)1> (this=0x7fffffff8ae0)
    at /home/myuser/mylib/.venv/include/pybind11/cast.h:1672
#6  0x00007ffff6da081d in get_repr<TestEnum> (obj=@0x7fffffff8b44: TestEnum::One) at /home/myuser/mylib/cpp/agc/py_wrap/agc_wrap.cpp:14

It makes sense that pybind11 can't execute this code without the binding for the enum, but typically pybind11 is pretty good at providing clear error messages when one has forgotten to bind a type. I was surprised that pybind11::cast will happily cast an object which has not been bound.

It would be helpful if pybind11 could raise an exception/print an error message when interacting with an enum which hasn't been bound, rather than just segfaulting.

Note: I have not explored the limits of this case (if its specific to enums, if its a problem with pybind11::cast or some other part of the system, etc), but found this particular behavior very surprising.

Reproducible example code

wrapper:

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;
enum class TestEnum
{
    One,
    Two,
    Three,
};

template <class T> 
std::string get_repr(const T& obj){
    return pybind11::cast<std::string>(pybind11::cast(obj).attr("__repr__")());
}

std::string get_test_enum_repr(){
    return get_repr(TestEnum::One);
}

PYBIND11_MODULE(_agc, m)
{

    // Uncomment this and everything works as expected
    // py::enum_<TestEnum>(m, "TestEnum")
    //     .value("One", TestEnum::One)
    //     .value("Two", TestEnum::Two)
    //     .value("Three", TestEnum::Three);

    m.def("get_test_enum_repr", &get_test_enum_repr);
}

test code:

print(agc.get_test_enum_repr())


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

Not a regression
@ascended121 ascended121 added the triage New bug, unverified label Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage New bug, unverified
Projects
None yet
Development

No branches or pull requests

1 participant