Отладка Python и С++

Я могу отлаживать код Python с помощью ddd -pydb prog.py. Все аргументы командной строки python могут быть переданы также после prog.py. В моем случае многие классы были реализованы на С++, которые подвержены python, используя boost-python. Хотелось бы, чтобы я мог отлаживать код Python и С++ вместе. Например, я хочу установить точки останова следующим образом:

break my_python.py:123
break my_cpp.cpp:456
cont

Конечно, я пытаюсь это сделать после компиляции С++ кодов с опцией debug, но отладчик не пересекает границу boost. Есть ли способ?

ИЗМЕНИТЬ: Я видел http://www.boost.org/doc/libs/1_61_0/libs/python/doc/html/faq/how_do_i_debug_my_python_extensi.html. Я последовал за ним, и я могу сделать отладку как для python, так и для С++. Но я предпочитаю делать визуальную отладку с помощью DDD, но я не знаю, как передать команду "target exec python" внутри DDD. Если нет (просто используя gdb как в ссылке), я должен уметь отлаживать для Python script, не интерактивно предоставляя команды python, как в ссылке.

Ответы

Ответ 1

Я узнал, как отлаживать часть С++ во время запуска python. (понял это, читая об обнаружении идентификатора процесса в книге Python..).
Сначала вы запускаете программу python, которая включает в себя программы на С++. В начале программы python используйте raw_input(), чтобы программа ожидала ввода данных. Но перед этим сделайте print os.getpid() (конечно, вы должны импортировать пакет os). Когда вы запустите программу python, она напечатает pid программы python, в которой вы работаете, и будет ждать ввода вашей клавиатуры.

код остановки python:

import os

def w1(str):
    print (str)
    wait = raw_input()
    return

print os.getpid()
w1('starting main..press a key')

результат:

27352
starting main..press a key

Или вы можете использовать import pdb, pdb.set_trace() в качестве комментария ниже (спасибо @AndyG) и посмотреть EDIT *, чтобы получить pid с помощью ps -aux.

Теперь предположим, что общая библиотека С++ - это _caffe.so(это мой случай. Эта библиотека _caffe.so имеет все коды С++ и повышает функции оболочки python). 27352 - это pid. Затем в другой оболочке запускается gdb, например

gdb caffe-fast-rcnn/python/caffe/_caffe.so 27352

или если вы хотите использовать графическую отладку, используя DDD, сделайте

ddd caffe-fast-rcnn/python/caffe/_caffe.so 27352

Затем вы увидите, что gdb запускается и ждет с подсказкой. Программа python прерывается gdb и ждет в остановленном режиме (он ждал ввода вашего ключа, но теперь он действительно находится в режиме stopeed, и ему требуется команда gdb continue от второго отладчика, чтобы продолжить ожидание ключа).
Теперь вы можете дать команду точки останова в gdb, например

br solver.cpp:225

и вы можете видеть сообщение типа

Breakpoint 1 at 0x7f2cccf70397: file src/caffe/solver.cpp, line 226. (2 locations)

Когда вы даете команду continue во втором окне gdb (который удерживает программу), код python запускается снова. Конечно, вы должны дать ключевой ввод в первом окне gdb, чтобы он продолжался.
Теперь, по крайней мере, вы можете отлаживать код С++ во время работы программы python (это то, что я хотел сделать)!

Я позже проверил, могу ли я одновременно выполнять отладку python и С++, и это работает. Вы запускаете отладчик (DDD), например ddd -pydb prog1.py options.., и присоединяете другое DDD, используя метод, описанный выше. Теперь вы можете установить точки останова для python и С++ и использовать другие функции отладки в каждом окне (хотелось бы, чтобы я знал это пару месяцев назад.. Это должно было помочь тоннам).

введите описание изображения здесь

EDIT: чтобы получить pid, вы можете сделать ps -aux | grep python. Этот pid является следующим из ddd pid.

Ответ 2

У меня была аналогичная проблема, но мне не удалось найти решения в Chan answer для работы (на MAC OS X 10.12.4). Вместо этого для меня работали.

  • Напишите python script test.py, который импортирует и использует модуль boost.Python.
  • запустить python в отладчике

    lldb python3 test.py
    

    дает

    > lldb python3 test.py
    (lldb) target create "python3"
    Current executable set to 'python3' (x86_64).
    (lldb) settings set -- target.run-args  "test.py"
    (lldb) run
    Process 46189 launched: '/Users/me/anaconda/bin/python3' (x86_64)
    test.cpython-36m-darwin.so was compiled with optimization - stepping may behave oddly; variables may not be available.
    Process 46189 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10d4b3000)
    frame #0: 0x00000001019f49c2 test.cpython-36m-darwin.so`std::__1::enable_if<true, void>::type (anonymous namespace)::Render2D<double>::add_particle<true, 5ul>(float*, float, float, float, float) const [inlined] mylib::SSE::packed<8ul, float>::loadu(
       944        { return {_mm256_load_ps(p)}; }
       945        /// load from unaligned memory location
       946        static __always__inline packed loadu(const element_type*p) noexcept
    -> 947        { return {_mm256_loadu_ps(p)}; }
       948        /// load from aligned memory location, using template arg for alignment
       949        template<bool aligned>
    
       950        static __always_inline enable_if_t< aligned, packed>
    

Не нужно получать pid и запускать отладчик из отдельного окна или устанавливать точки останова.