diff options
author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2021-12-13 09:41:57 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-23 17:12:55 +0000 |
commit | 347e8d72602a1e7c451f3ef18ef168d4c463af94 (patch) | |
tree | f07dddca12d862e8ba50570224ed47eddb474f00 | |
parent | 64563474fb46aaceab7d12ad53c8c9ce9e97e304 (diff) |
Add Debugging Tutorial
Add tutorial to debug C++ counterpart of PySide application. This commit provides general instructions to setup everything for debugging and
debugging using either QtCreator/VSCode.
Task-number: PYSIDE-841
Change-Id: I6a95ab64507a304fc19a2cdcdf6d29b6c96cca03
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Tismer <tismer@stackless.com>
(cherry picked from commit d727a69e2f58be167845b8179edf1735df6ccf1e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
12 files changed, 309 insertions, 0 deletions
diff --git a/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst b/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst new file mode 100644 index 000000000..82b34d919 --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst @@ -0,0 +1,126 @@ +How To Debug a C++ Extension of a PySide6 Application? +****************************************************** + +When debugging PySide code, very often you would also like to debug the +corresponding C++ extension of the PySide module. This is done by attaching your +debugger to the Python interpreter. In this tutorial, we are going to take you +through a comprehensive guide in building Qt 6, using the built Qt 6 to build +PySide6, and then starting a debugging process in either Qt Creator or VSCode. + +With VSCode, you should be able to see the combined call stacks for both C++ and +Python together. With Qt Creator, unfortunately you would only be able to +debug the native C++ code of the PySide module; that is you won't be able to set +breakpoints inside the Python code. + +.. note:: This tutorial is created on Ubuntu 20.04 LTS with the debugger as GDB. + As such, this tutorial is mainly focused on Linux users. Nevertheless, links to + setup everything in other platforms are mentioned along with each + sub-section. + +Let's get started. + +Install All The Library Dependencies Based on Your Platform +----------------------------------------------------------- + +.. code-block:: bash + + sudo apt install libfontconfig1-dev libfreetype6-dev \ + libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev \ + libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev \ + libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev \ + libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev \ + libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev \ + libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev \ + libxkbcommon-dev libxkbcommon-x11-dev libatspi2.0-dev \ + libopengl0 -y + +If you have to use the Qt Multimedia module, you have to install gstreamer also. + +.. code-block:: bash + + sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ + libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base \ + gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc \ + gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl \ + gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio + +Generally, any information on missing packages can be found by inspecting the +config.summary in you CMake build folder. + +.. note:: For other platforms install the same packages using the instructions + mentioned here `Qt Install on Linux <https://doc.qt.io/qt-6/linux-requirements.html>`_ + +Build Qt +-------- + +This is an optional step in case you only want to debug the CPython bindings or if you have DEBUG_SYMBOLS for Qt 6 already. + +There are multiple ways to build Qt - configure script or manually with CMake. +Find the build system information `Qt 6 Build System +<https://www.qt.io/blog/qt-6-build-system>`_. + +1. Get the source code. + + .. code-block:: bash + + git clone git://code.qt.io/qt/qt5.git + # Get submodules + cd qt5 + perl init-repository + +2. Once you have the source code, the next step is to generate the build using + CMake, then building and installing it. + + .. code-block:: bash + + cmake -GNinja -DMCAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX=/path/to/install/Qt -DBUILD_qtwebengine=OFF .. + cmake --build . --parallel + cmake --install . + + As you notice here, we are skipping the Qt WebEngine module because this greatly + decreases the build time. However, PySide6 supports Qt WebEngine + features. So feel free to add it, if you need it. + +More instructions on building Qt 6 can be found in the following links: + +* https://wiki.qt.io/Building_Qt_6_from_Git +* https://code.qt.io/cgit/qt/qtbase.git/tree/cmake/README.md +* https://code.qt.io/cgit/qt/qtbase.git/tree/cmake/configure-cmake-mapping.md + +Add the **bin** and **lib** path to the environment variables +-------------------------------------------------------------- + +.. code-block:: bash + + export PATH="/path/to/custom/qt/bin:$PATH" + export LD_LIBRARY_PATH="/path/to/custom/qt/lib:$LD_LIBRARY_PATH" + +Build PySide6 using the Qt 6 that you built earlier +---------------------------------------------------- + +Follow the steps mentioned `Getting Started - Qt for Python +<https://doc.qt.io/qtforpython/gettingstarted.html>`_ + +You may manually select the modules to install using the ``--module-subset`` cli +argument for `setup.py`. This was my installation script + +.. code-block:: bash + + python setup.py install --qpaths=/path/to/qpaths --debug \ + --ignore-git --reuse-build + +It is recommended to use a Python virtual environment rather than installing in the global Python. + +Debugging the process using your preferred IDE +---------------------------------------------- + +The following sections guide you through the setup for Qt Creator or VSCode. + +.. toctree:: + :glob: + :titlesonly: + + qtcreator/qtcreator + vscode/vscode diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png Binary files differnew file mode 100644 index 000000000..c8197118e --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png Binary files differnew file mode 100644 index 000000000..8362c3310 --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png Binary files differnew file mode 100644 index 000000000..4f0bbe3d4 --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst b/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst new file mode 100644 index 000000000..06783e1bb --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst @@ -0,0 +1,39 @@ +Debugging PySide with Qt Creator (Linux) +*************************************** + +As opposed to VSCode, presently Qt Creator does not support mixed mode debugging. +However, we can debug the C++ implementation of the corresponding Python PySide +code. Unlike VSCode, Qt Creator provides a very easy interface to attach GDB to +the Python interpreter. It saves you from doing all the extra configuration +steps, that have to be done with VSCode. + +Here are the steps: + +1. Set a breakpoint on the C++ code. + +2. Go to Projects -> Run -> Run Configuration -> Add. This is going to open a + new window shown below. + + .. image:: custom_executable_create.png + :alt: creation of custom executable + :align: center + +3. Click on Custom Executable and `Create' a new configuration. Feed in the +details like shown below. + + .. image:: custom_executable_run_config.png + :alt: run configuration of custom executable + :align: center + +4. Debug -> Start Debugging -> Start Debugging Without Deployment. + + .. image:: start_debugging_without_deployment.png + :alt: start debugging without deployment + :align: center + +You will now hit you breakpoint and can start debugging your code. + + .. image:: breakpoint_cpp.png + :alt: breakpoint cpp + :align: center + diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png Binary files differnew file mode 100644 index 000000000..9ce0688d3 --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png Binary files differnew file mode 100644 index 000000000..57577eea4 --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png Binary files differnew file mode 100644 index 000000000..319577fea --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png b/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png Binary files differnew file mode 100644 index 000000000..b9bc4acde --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png b/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png Binary files differnew file mode 100644 index 000000000..65176d9bb --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst b/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst new file mode 100644 index 000000000..59579e7cf --- /dev/null +++ b/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst @@ -0,0 +1,136 @@ +Debugging PySide with VSCode (Linux) +************************************ + +VSCode enables you to use more than one debugger in a single debugging session. +This means that we can use GDB and Python PDB in a single session. With VSCode +you would be able to do the following: + +* See the call stacks for both Python and C++ together. +* Put breakpoints in both the Python and the C++ code. +* Step from Python to C++ code and vice versa. + +Let's get started with setting up everything and debugging a Python process. + +Creating Configurations in launch.json +-------------------------------------- + +Run -> Add Configuration -> Python -> Python File + +This should create a launch.json file which looks like this: + +.. code-block:: json + + { + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] + } + +It should already consist of a configuration named "Python: Current File", which +allows us to debug the current open Python file. With a Python virtual +environment, make sure to change the value of "program" to refer to the path of the Python +interpreter inside the virtual environment. + +Now, we need to add a configuration to attach the GDB debugger to the Python +process that is already running in debug mode. Let's call it "(gdb) Attach" + +.. code-block:: json + + { + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + }, { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "program": "/path/to/python", + "processId": "${command:pickProcess}", + "MIMode": "gdb", "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] + } + +Here also make sure that the value of "program" refers to your Python interpreter. We need the +processId to attach the gdb debugger to the process. With +"${command:pickProcess}", we find the processId on the go, as we will see later. + +Now, we are ready to debug. + +Debug The Process +----------------- + +1. Set a breakpoint in the Python code. + +2. Go to `Run And Debug` (Ctrl + Shift + D) and run the "python: Current File" + by clicking the run symbol (green right-arrow). This will hit the breakpoint and + will halt the Python debugger. + +3. Using the drop-down menu change from "python: + Current File" to "(gdb) Attach". Your setup should now look like this. + + .. image:: breakpoint_gdb.png + :alt: breakpoint before attach gdb + :align: center + +4. Run "(gdb) Attach" and this should ask you for the processId of the Python + process to which you want to attach gdb. VSCode also lets you to search for the + process by its name. .. tip:: You can find the processId by running `ps aux | + grep python` + + .. image:: find_process_gdb.png + :alt: find process vscode + :align: center + +5. VSCode will now ask you for superuser permissions. Type 'y' and enter your + password. + + .. code-block:: bash + + Superuser access is required to attach to a process. Attaching as + superuser can potentially harm your computer. Do you want to continue? + [y/N]_ + +6. That is it. You should now be able to hit the breakpoints that you have set + on the C++ counterparts. + + .. figure:: audioformat_wrapper.png + :alt: Breakpoint set on the shiboken wrapper class + :align: left + + Breakpoint set on the shiboken wrapper class + + .. figure:: audioformat_cpp.png + :alt: Breakpoint set on C++ implementation + :align: left + + Breakpoint set on C++ implementation + + + + + diff --git a/sources/pyside6/doc/tutorials/index.rst b/sources/pyside6/doc/tutorials/index.rst index 2403b6d6b..ae29da9d9 100644 --- a/sources/pyside6/doc/tutorials/index.rst +++ b/sources/pyside6/doc/tutorials/index.rst @@ -251,3 +251,11 @@ C++ and Python :maxdepth: 1 portingguide/index.rst + +Debug a PySide6 Application +--------------------------- +.. toctree:: + :maxdepth: 1 + + debugging/mixed_debugging.rst + |