{"id":1647,"date":"2016-04-18T21:59:51","date_gmt":"2016-04-19T04:59:51","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=1647"},"modified":"2016-04-18T21:59:51","modified_gmt":"2016-04-19T04:59:51","slug":"using-python-quick-debug-to-debug-external-python-scripts","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/linux\/python\/quickdebug\/","title":{"rendered":"Using Python Quick Debug to debug external Python scripts"},"content":{"rendered":"<p>This tutorial shows how to quickly debug Python scripts and C++ modules built outside VisualGDB without creating a project for them. We will create a simple Python C++ module on a Linux machine via SSH and show how to quickly debug it with VisualGDB.<\/p>\n<p>Before you begin, install VisualGDB 5.1 or later.<\/p>\n<ol>\n<li>First of all, connect to your Linux machine using SmarTTY and create a C++ file (e.g. test.cpp) with the following contents:\n<pre class=\"\">#include &lt;Python.h&gt;\r\n#include &lt;stdio.h&gt;\r\n\r\nstatic PyObject *HelloMethod(PyObject *self, PyObject *args)\r\n{\r\n\u00a0\u00a0 \u00a0const char *pName = NULL;\r\n\r\n\u00a0\u00a0 \u00a0\/\/if (!PyArg_ParseTuple(args, \"s\", &amp;pName))\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/return NULL;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 if (pName[0])\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0 printf(\"Hello, %s\\n\", pName);\r\n\u00a0\u00a0 \u00a0return Py_BuildValue(\"i\", 1);\r\n}\r\n\r\nstatic PyMethodDef testMethods[] = \r\n{\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\"hello\",\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0HelloMethod,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0METH_VARARGS,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\"Displays a \\\"Hello\\\" message.\" \r\n\u00a0\u00a0 \u00a0},\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0{ NULL, NULL, 0, NULL }\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* End of list *\/\r\n};\r\n\r\n\r\nPyMODINIT_FUNC inittest(void)\r\n{\r\n\u00a0\u00a0 \u00a0PyObject *m = Py_InitModule(\"test\", testMethods);\r\n\u00a0\u00a0 \u00a0if (!m)\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return;\r\n}<\/pre>\n<p>This defines a very basic Python module called &#8220;test&#8221; with a single method called &#8220;hello&#8221; that will crash the program as we commented out the actual parsing of the input arguments and are trying to dereference a NULL pointer.<\/li>\n<li>In the same directory create a basic Python script that will call the module:\n<pre class=\"\">import test\r\ntest.hello(\"World\")<\/pre>\n<\/li>\n<li>Now build the module, set PYTHONPATH to point at the current directory and run the script:\n<pre class=\"\">g++ test.cpp -ggdb -o test.so -lpython2.7 -I\/usr\/include\/python2.7 -shared\r\nexport PYTHONPATH=$PYTHONPATH:.\r\npython main.py\r\n<\/pre>\n<p>Observe how the Python process crashes without printing any details:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/segfault.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1649\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/segfault.png\" alt=\"segfault\" width=\"1157\" height=\"350\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/segfault.png 1157w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/segfault-300x91.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/segfault-1024x310.png 1024w\" sizes=\"(max-width: 1157px) 100vw, 1157px\" \/><\/a><\/li>\n<li>Now we will use Visual Studio to quickly diagnose the crash without creating any projects. Start Visual Studio and select Debug-&gt;Quick Debug with GDB:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/qdwnd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1650\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/qdwnd.png\" alt=\"qdwnd\" width=\"956\" height=\"676\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/qdwnd.png 956w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/qdwnd-300x212.png 300w\" sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/a><\/li>\n<li>In the &#8220;Quick Debug&#8221; window select &#8220;Python Script&#8221; -&gt; &#8221; Linux System&#8221; and enter the following settings:\n<ul>\n<li>Debugged script: the full path to the Python script<\/li>\n<li>Working directory: the directory with the script and the .so module causing the crash<\/li>\n<li>Additional environment: PYTHONPATH=%PYTHONPATH%:.<\/li>\n<li>Python executable &#8211; python<\/li>\n<\/ul>\n<p>Save the preset for future use by checking a checkbox at the bottom of the window:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/01-qd.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1658\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/01-qd.png\" alt=\"01-qd\" width=\"631\" height=\"701\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/01-qd.png 631w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/01-qd-270x300.png 270w\" sizes=\"(max-width: 631px) 100vw, 631px\" \/><\/a><\/li>\n<li>Press &#8220;Debug&#8221;. VisualGDB will start debugging the script, automatically download it to the Windows machine and stop at the first line:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/02-py.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1657\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/02-py.png\" alt=\"02-py\" width=\"956\" height=\"676\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/02-py.png 956w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/02-py-300x212.png 300w\" sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/a><\/li>\n<li>Press F5 to continue debugging. Visual Studio will report that it has received a SIGSEGV signal corresponding to a segmentation fault:<br \/>\n<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/03-sigsegv.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1656\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/03-sigsegv.png\" alt=\"03-sigsegv\" width=\"956\" height=\"676\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/03-sigsegv.png 956w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/03-sigsegv-300x212.png 300w\" sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/a><\/li>\n<li>Press &#8220;Break&#8221; to see the code location that caused the crash:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/04-readonly.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1655\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/04-readonly.png\" alt=\"04-readonly\" width=\"956\" height=\"676\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/04-readonly.png 956w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/04-readonly-300x212.png 300w\" sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/a>Note that the source file will be read-only and you won&#8217;t be able to modify it as it&#8217;s not a part of a VisualGDB project and VisualGDB does not how how and when to upload it.<\/li>\n<li>Open the file on the Linux side with SmarTTY and uncomment the call to PyArg_ParseTuple():<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/05-uncomment.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1654\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/05-uncomment.png\" alt=\"05-uncomment\" width=\"836\" height=\"400\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/05-uncomment.png 836w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/05-uncomment-300x144.png 300w\" sizes=\"(max-width: 836px) 100vw, 836px\" \/><\/a><\/li>\n<li>Build the module again:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/06-rebuild.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1653\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/06-rebuild.png\" alt=\"06-rebuild\" width=\"1185\" height=\"303\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/06-rebuild.png 1185w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/06-rebuild-300x77.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/06-rebuild-1024x262.png 1024w\" sizes=\"(max-width: 1185px) 100vw, 1185px\" \/><\/a><\/li>\n<li>Now if you select Debug-&gt;Quick Debug with GDB, VisualGDB will automatically load the previously saved preset, so you won&#8217;t need to re-enter anything. Simply click &#8220;Debug&#8221; to start debugging:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/07-qd2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1652\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/07-qd2.png\" alt=\"07-qd2\" width=\"631\" height=\"701\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/07-qd2.png 631w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/07-qd2-270x300.png 270w\" sizes=\"(max-width: 631px) 100vw, 631px\" \/><\/a><\/li>\n<li>Observe how the script now exits without any errors and outputs the &#8220;Hello, World &#8220;message:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/08-output.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1651\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/08-output.png\" alt=\"08-output\" width=\"956\" height=\"676\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/08-output.png 956w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/03\/08-output-300x212.png 300w\" sizes=\"(max-width: 956px) 100vw, 956px\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to quickly debug Python scripts and C++ modules built outside VisualGDB without creating a project for<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[33,122,82],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1647"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=1647"}],"version-history":[{"count":3,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1647\/revisions"}],"predecessor-version":[{"id":1660,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1647\/revisions\/1660"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=1647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=1647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=1647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}