pythonc++gdbbad-alloc

Debug Python/C++ program with bad_alloc


I have a Python program that interfaces with a PyBind11 C++ library.

Somewhere in the library, something is throwing an std::bad_alloc. Python catches this and handily raises an exception:

MemoryError: std::bad_alloc

Running it all in GDB:

gdb --ex run --args python3 ./my_program

Doesn't result in a break at the point of bad allocation.

If I could get Python to segfault on the bad allocation or tell GDB to catch the exception before Python does, I'd be able to debug this. Unfortunately, I'm not sure how to do either.


Solution

  • Debugging this requires a few steps. First, we're going to need debugging symbols. PyBind11 strips these, so we have to get them back.

    My CMake file looked like this:

    cmake_minimum_required(VERSION 3.10)
    
    find_package(pybind11 REQUIRED)
    
    pybind11_add_module(my_python_module my_python_module.cpp)
    target_compile_features(my_python_module PUBLIC cxx_std_17)
    

    to get symbols back I need it to look like this:

    cmake_minimum_required(VERSION 3.10)
    
    find_package(pybind11 REQUIRED)
    
    pybind11_add_module(my_python_module my_python_module.cpp)
    target_compile_features(my_python_module PUBLIC cxx_std_17)
    
    target_link_libraries(my_python_module PRIVATE pybind11::module)
    add_library(restore_default_visibility INTERFACE)
    target_compile_options(restore_default_visibility INTERFACE -fvisibility=default)
    target_link_libraries(my_python_module PRIVATE restore_default_visibility)
    

    I also need to get a Debug build:

    cmake -DCMAKE_BUILD_TYPE=Debug ..
    

    Now, I can start my Python program:

    gdb --args python3 ./my_program
    

    One GDB starts, I set a breakpoint for the std::bad_alloc:

    catch throw std::bad_alloc
    

    Now I can run my program by typing c.

    Later, when it crashes, I can use the bt command to get a backtrace, up and down to navigate the stack, print show the contents of variables, and Ctrl+X+A to see the source code.