{"id":1788,"date":"2023-09-15T10:24:12","date_gmt":"2023-09-15T17:24:12","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=1788"},"modified":"2023-09-20T09:39:40","modified_gmt":"2023-09-20T16:39:40","slug":"debugging-programs-built-with-linux-cross-compilers","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/linux\/3machine\/","title":{"rendered":"Debugging programs built with Linux cross-compilers"},"content":{"rendered":"<p>This tutorial shows how to develop and debug applications built with a cross-compiler on one Linux machine and then deployed to another one.<\/p>\n<p>We will show how to configure VisualGDB to build a simple Raspberry Pi application on an x86 Linux machine, deploy it to Raspberry Pi and debug it there. Before you begin, install VisualGDB and ensure that your x86 Linux machine has the <strong>arm-linux-ghueabihf<\/strong> cross-compiler and a matching gdb.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Linux Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2023\/09\/01-linux.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8378\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2023\/09\/01-linux.png\" alt=\"\" width=\"890\" height=\"625\" \/><\/a><\/li>\n<li>Enter the name and location for your project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/01-name.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8402\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/01-name.png\" alt=\"\" width=\"890\" height=\"625\" \/><\/a><\/li>\n<li>Proceed with the default &#8220;Create a new project -&gt; Application&#8221; setting. For most new projects we recommend using the Advanced CMake Project Subsystem:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/02-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8403\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/02-cmake.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select &#8220;Build the project under Linux over network&#8221; and select the build computer with the cross-toolchain. Then click &#8220;<strong>Specify toolchain manually by locating gdb<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/specify.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8405\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/specify.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>VisualGDB will ask for the location of the gdb. Find it and click &#8220;Open&#8221;. In this example the gdb binary is called <strong>arm-linux-gnueabihf-gdb<\/strong> and is located in <strong>\/usr\/bin<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/03-gdb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8404\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/03-gdb.png\" alt=\"\" width=\"1069\" height=\"737\" \/><\/a>Note that if you installed a cross-toolchain via a package manager (e.g. <strong>apt install gcc-arm-linux-gnueabihf <\/strong>or <strong>apt install g++-arm-linux-gnueabihf<\/strong>), it may not include a gdb executable. You can then install it via &#8220;<strong>apt install gdb-multiarch<\/strong>&#8221; and create a symbolic link to it via &#8220;<strong>sudo ln -s \/usr\/bin\/gdb-multiarch \/usr\/bin\/arm-linux-gnueabihf-gdb<\/strong>&#8220;.<\/li>\n<li>Enable the &#8220;Deploy&#8221; the project to another Linux computer checkbox and select your Raspberry Pi in the &#8220;Deployment computer&#8221; field:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/05-deploy.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8406\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/05-deploy.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page select where should VisualGDB store your source files on the Linux machine. The easiest way is to proceed with the default settings and let VisualGDB manage the source file locations:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/06-sources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8407\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/06-sources.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to generate your project. VisualGDB will automatically detect the include directories used by the cross-toolchain and cache them on the Windows machine to setup IntelilSense:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/07-sync.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8408\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/07-sync.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Now we will slightly modify the project to actually print the hostname of the machine where it is running. Replace the contents of the main file with the following:\n<pre class=\"\">#include &lt;iostream&gt;\r\n#include &lt;unistd.h&gt;\r\n\r\nusing namespace std;\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n\u00a0\u00a0\u00a0 char hostname[1024] = { 0, };\r\n\u00a0\u00a0\u00a0 gethostname(hostname, sizeof(hostname));\r\n\u00a0\u00a0 \u00a0cout &lt;&lt; \"The host name is \" &lt;&lt; hostname &lt;&lt; endl;\u00a0\u00a0 \u00a0\/\/&lt;================= Put a breakpoint here\r\n\u00a0\u00a0 \u00a0return 0;\r\n}<\/pre>\n<p>Then press F5 to build your project and start debugging it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/08-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8409\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/08-bkpt.png\" alt=\"\" width=\"1069\" height=\"737\" \/><\/a>You will see that the project is built, deployed and the hostname matches the name of the deployment machine.<\/li>\n<li>Sometimes the build machine cannot connect to the deployment machine because it cannot resolve the host name or it needs to use a different IP address. You can override this by opening VisualGDB Project Properties on the Debug Settings page and switching the target selection command to &#8220;<strong>target remote &lt;IP&gt;:&lt;port&gt;<\/strong>&#8220;. Ensure you set the &#8220;<strong>debugging start mode<\/strong>&#8221; to &#8220;<strong>Use &#8216;continue&#8217; command<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/09-ipaddr.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8410\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/09-ipaddr.png\" alt=\"\" width=\"1077\" height=\"756\" \/><\/a>You can double-check the command that VisualGDB uses to connect to the target by switching the GDB Session window to the &#8220;<strong>All GDB interaction<\/strong>&#8221; or &#8220;<strong>Raw output from GDB&#8221;<\/strong> mode and then searching for &#8220;target&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/10-var.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8411\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/05\/10-var.png\" alt=\"\" width=\"1069\" height=\"737\" \/><\/a><\/li>\n<\/ol>\n<p>Note that normally VisualGDB would require the target to be accessible from the Windows machine via SSH. If there is no direct connection between the Windows machine and the target, but the target is accessible from the build machine, see <a href=\"https:\/\/visualgdb.com\/tutorials\/linux\/3machine\/indirect\/\">this tutorial<\/a> for detailed steps on configuring VisualGDB to handle it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to develop and debug applications built with a cross-compiler on one Linux machine and then deployed<\/p>\n","protected":false},"author":1,"featured_media":1800,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[72,33,43],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1788"}],"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=1788"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1788\/revisions"}],"predecessor-version":[{"id":8413,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/1788\/revisions\/8413"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/1800"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=1788"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=1788"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=1788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}