新技巧GET: 使用gdbserver來調試Linux CMake工程

2021-01-11 漫漫開發路

關於Gdbserver

Gdbserver是一個運行在Linux上的調試工具,用於調試Linux上運行的應用程式。當目標系統是一個嵌入式系統時,可能因為資源的限制而不能運行全功能版本的gdb,這個時候gdbserver就顯得格外的有用了。

Visual Studio 2019 v16.5 Preview 1添加了一項新的特性:使用gdbserver對CMake工程進行遠程調試。在之前的一篇文章中,我們描述了如何在Linux docker容器中編譯CMake應用程式。在今天的文章中,我們將在前篇文章的基礎上涵蓋如下的內容:

1. 在Linux docker容器中進行ARM交叉編譯。

2. 拷貝編譯生成的文件到本機。

3. 部署生成的程序到另外一個獨立的ARM linux系統(通過SSH進行連接),並藉助ARM系統上的gdbserver和本機上的gdb來進行遠程調試。

通過在本機上使用一個特定版本的gdb,可以避免在遠程(嵌入式)系統上施一公全功能版本的gdb。

請注意,以上流程目前只是VS2019 v16.5 Preview 1中的一項實驗特性,並需要一些手動的配置才能工作。

在Linux docker容器中進行ARM交叉編譯

這篇文章假設你已經成功配置了VS2019並可以在一個Linux docker容器(Ubuntu)中編譯一個CMake工程。如果你對這塊還有點不明白,可以參考我之前的一篇文章。

為這個流程所進行的配置是比較通用的,也就是說,你可以在任何Linux環境(一臺VM,或者一臺遠程Linux伺服器等)來做相同的配置步驟。

第一件事,是需要修改我們的配置文件來進行ARM的交叉編譯。在之前的文章中,我們創建了一個Dockerfile,我們基於這個Dockerfile做了如下的改動:

在以上的Dockerfile中,我使用apt-get來安裝了一個交叉編譯器並從本機拷貝了一個CMake配置文件到Docker容器中。CMakeCMake是一個需要安裝的依賴項,但是從上一篇文章中我們可以通過部署一個靜態連結的版本來解決這個依賴問題。

CMake工具鏈文件指定了有關編譯器和相關工具的路徑信息。我在這裡使用了一個CMake的例子文件來在Windows上創建一個配置文件,其內容如下:

保存這個文件為」arm_toolchain.cmake」到Dockerfile所在的文件夾。另外,我們也可以通過在上面COPY命令中添加到此文件的相對路徑。

至此,我們可以編譯一個Docker映像並執行了。

最後,我們可以通過SSH來直接和Docker容器進行交互,並創建一個用戶帳號。請注意再次提醒,你可以在Dockerfile中啟用root登錄,這樣可以避免所有的手動操作。只需要替換為你想要使用的用戶帳號即可,如下圖所示:

這樣,你就可以準備好從Visual Studio中進行編譯了。

配置CMake實現ARM交叉編譯

首先請確保你安裝了VS2019 v16.5 Preview 1或更高版本,並且安裝了Linux development with C++ workload。打開VS並創建一個新的CMake工程。

接下來,我們將會在VS中創建一個新的CMake配置。導航至CMake Settings編輯器並創建一個名外」Linux-Debug」的配置。我們將會在這個配置中做出如下的修改,實現ARM的交叉編譯。

1. 修改configuration name為arm-Debug(這個改動不會影響編譯,但是它可以讓我們方便的引用一些工程特定的配置)。

2. 確保remote machine name被設定為你的Linux Docker容器對應的名稱。

3. 修改toolset為linux_arm。

4. 指定CMake toolchain file為工具鏈配置文件在Linux Docker中的全路徑(/opt/toolchains/arm_toolchain.cmake)。

5. 通過在配置編輯器中打開」CMakeSettings.json」來打開CMakeSettings.json文件,然後在arm-Debug配置中,設置remoteCopyBuildOutput為true。這將可以讓我們可以拷貝編譯輸出到本機,方便後面的gdb調試。

請注意,每次你修改以上配置,都需要記得刪除配置文件的緩存版本(Project > CMake Cache (arm-Debug only) > Delete Cache)。如果你沒有安裝CMake,VS會提示你在遠程機器上安裝一個靜態連結的版本,作為配置過程的一部分。

你的CMake工程已經完成配置,準備可以在Linux Docker容器中進行ARM交叉編譯了。當你編譯程序的時候,你將會在遠程機器(/home//.vs/…)和本機上看到編譯輸出的文件。

添加第二個遠程連接

接下來,我們將在連接管理器中創建一個新的遠程連接。這個是我們將要部署的目標系統,其運行的是OS Raspbian (ARM)系統。請確保ssh正常運行在這個系統上。

請注意:VS2019 v16.5 Preview 1中的」separate your build system from your deploy system」目前還不支持VS native support for WSL。而且它還不支持多個localhost連接。這個限制主要是因為一個bug,我們會在VS的下一個版本中得到修復。在這種情況下,你的Docker連接將會是唯一一個localhost連接,並且可以通過SSH來連接ARM系統。

配置launch.vs.json來啟用gdbserve調試

最後,我們來配置一下調試器。在CMakeLists.txt上右鍵,然後點擊」Debug and Launch Settings」並選擇」C/C++ Attach for Linux (gdb)」調試器類型。

我們將會手動的配置這個文件(包括添加或刪除一些屬性)來啟用gdbserver調試。

以下是配置文件的一個例子,供參考。請注意,這項支持還比較新,仍然需要一些手動的配置步驟。

現在可以在程序中設置一個斷點,並確保arm-Debug是當前激活的配置項,並且當前的調試器為gdbserver,如下圖所示:

當按下F5時,工程將會在CMakeSettings.json中配置的遠程系統上開始編譯,並部署到launch.vs.json中指定的系統中。同時,本機調試會話也將會啟動。

可能遇到的問題

1. 如果launch配置沒有正確配置,那麼你將可能不能連接遠程機器。所以,請確保清除掉你將要部署的系統上的所有gdbserver進程。

2. 如果你沒有修改CMake配置中的remote build root,則在遠程系統上的程序的相對路徑將和遠程編譯環境中的相對路徑一致。

3. 你可以啟用交叉編譯日誌(Tools > Options > Cross Platform > Logging)來查看在遠程機器上執行的命令,方便進行錯誤排除。

總結

所以說:編譯,部署,調試,一切的一切,Visual Studio都給安排的明明白白了?

相關焦點

  • 建立ARM平臺上的交叉調試器gdb和gdbserver
    其中:host指定了運行環境為i386機器,target指定了需要調試的目標機環境(我使用的ARM toolchain是armv5-linux-uclibc-gcc,因此這樣指定,如果是用arm-linux-gcc,則 --target=arm-linux),prefix指定了編譯後的結果存放的位置,也就是安裝目錄。
  • 一文入門Linux下gdb調試(一)
    剛開始不習慣,使用多了我們就會喜歡上他,程序調試的單步執行,跳入函數,跳出函數,設置斷點,設置觀察點,查看變量。GDB都有,此外gdb還可以生成程序非法執行後core dump文件,這個文件有快照功能,在程序崩潰的時候保存了程序的堆棧等信息,我們執行core文件就可以方便的找程序崩潰的原因了。
  • 一文入門Linux下gdb調試(一)
    gdb,GNU提供的開源調試工具。剛開始不習慣,使用多了我們就會喜歡上他,程序調試的單步執行,跳入函數,跳出函數,設置斷點,設置觀察點,查看變量。GDB都有,此外gdb還可以生成程序非法執行後core dump文件,這個文件有快照功能,在程序崩潰的時候保存了程序的堆棧等信息,我們執行core文件就可以方便的找程序崩潰的原因了。
  • gdb實用的調試技巧:啟動方式、堆棧信息、單步調試
    對於很多開發者來說,開發過程中難免會遇到各種各樣的bug, 所以,每個開發者應該考慮如何快速高效定位問題原因,而gdb是linux上很實用的調試工具,熟練掌握其調試技巧,將有助於提高解決問題的效率,也是開發者應該掌握的基本技能。
  • gdb實用的調試技巧:啟動方式、堆棧信息、單步調試
    對於很多開發者來說,開發過程中難免會遇到各種各樣的bug, 所以,每個開發者應該考慮的如何快速高效定位問題原因,而gdb是linux上很實用的調試工具,熟練掌握其調試技巧,將有助於提高解決問題的效率,也是開發者應該掌握的基本技能。
  • GDB 10.1版本發布了
    更多網際網路新鮮資訊、工作奇淫技巧關注原創【飛魚在浪嶼】(日更新)可以從以下目錄的GNU FTP伺服器下載GDB: ftp://ftp.gnu.org/gnu/gdbGDB的網頁位於: http://www.gnu.org/software/gdb/GDB 10.1包括以下更改和增強功能:支持調試新目標:-BPF(bpf-unknown-none
  • 在Linux上利用core dump和GDB調試segfault
    日常碼農生活中,尤其是C/C++碼農,時常會遇到段錯誤(segfault),調試非常費勁,除了單元測試和基本測試外,有些時候是在在線環境下,沒有基本開發和測試工具,這就需要調試的技能。以前蟲蟲文章中介紹過使用strace進行系統調試和追蹤《linux動態追蹤神器——Strace實例介紹》。
  • 使用VS 2019進行Linux遠程開發
    隨後vs將會在console的gdb或gdbserver中運行你的程序,在此期間你可以充分享受vs debugger帶來的高效和便利。經過上述步驟之後你就可以在vs裡調試自己編寫的跨平臺程序了。使用 VS 2019進行Linux遠程開發簡介到此結束了,下面我們來看看在VS 2019進行Linux開發的圖文教程。
  • gdb工具對mysql進行源碼調試
    目前有很多文章描述如何源碼調試MySQL,主要過程是通過源碼編譯一個Debug版的MySQL出來,然後使用gdb工具進行調試。關於如何編譯一個Debug的MySQL,過程比較繁瑣,下載源碼,安裝c/c++開發環境,安裝cmake等等,很容易出錯,並且可能編譯出來的版本與官方發行的版本,在編譯選項和參數上存在不一致。本文介紹一種更加簡便的調試MySQL的方法。
  • Linux C/C++ 開發人員要熟練掌握 GDB 調試代碼塊
    一、啟動GDB調試使用 GDB 調試程序一般有三種方式: gdb filename gdb attach pid gdb filename corename1、直接調試目標程序2、附加進程3、調試 core
  • Ubuntu12.10 使用JLink連接開發板用arm-gdb調試ARM程序
    Part1 環境搭建和工具安裝1.1 設置交叉編譯環境安裝相關的編譯工具:sudo apt-get install  build-essential gcc-arm-linux-gnueabi這裡我使用的是ubuntu系統源中含有的gcc-arm-linux-gnueabi系列工具
  • linux下GDB使用方法
    list+ 函數名:查看具體函數),簡寫l(gdb)set:設置變量的值(gdb)next:單步調試(逐過程,函數直接執行),簡寫n(gdb)step:單步調試(逐語句:跳入自定義函數內部執行),簡寫s(gdb)backtrace:查看函數的調用的棧幀和層級關係,簡寫bt(gdb)bt full:不僅顯示backtrace,還顯示局部變量
  • Ubuntu配置安裝ARM Linux交叉編譯環境完整流程
    所以來重新安裝配置arm linux交叉編譯環境。順便記下.....,很簡單啦3.安裝交叉編譯器,網上去下載一個好的交叉編譯工具鏈吧,我用的3.4.1,這個更簡單了,解壓之,然後將其中的arm文件夾移動到你想放的地方,譬如/usr/local/ 下,再將其bin文件路徑/usr/local/arm/3.4.1/bin添加進/etc/environment 下,我們就可以直接使用arm-linux-gcc了4.安裝insight,也是今天的重點
  • 大道至簡:調試遠程系統和WSL的新模板來了
    現在,在Visual Studio 2019 v16.6 Preview 2中,我們引入了一個新模板,用來簡化GDB調試工作。要點如下:> 現有的所有調試配置(關於cppdbg)都可以一如既往地正常使用。> 當你添加一臺新的Linux主機或者WSL的調試配置時,cppgdb的新模板將會默認被使用。
  • GNU發布GDB新版本 10.1和 mtools 4.025
    67b01c95c88ab8e05a08680904bd6c92 gdb-10.1.tar.gzGDB 10.1功能增強GDB 10.1版本包括以下更改和增強功能:支持調試新目標:- BPF (bpf-unknown-none)
  • 乾貨分享丨關於GDB 調試入門,看這篇就夠了
    概述通常用C/C++來開發應用程式,會使用GCC交叉工具編譯鏈來把程序編譯成對應平臺的二進位文件,才能在開發板的Linux平臺上運行。但一般的應用開發動輒幾千,上萬行的工程代碼,程序中的一些錯誤往往是我們在寫程序的時候無法檢測到的,例如邏輯類錯誤。等程序實際運行起來後,會發現程序雖然錯了,但不知道到底什麼地方出錯了。這就需要一個方法或者一種工具來幫助我們實時分析所寫的程序,既能定位,又能調試。業內非常有名的GDB就是這樣的輔助工具。
  • 一文入門Linux下gdb調試(二)
    該文件也是二進位文件,可以使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb進行打開分析裡面的具體內容。 基於core文件的快照功能,我們就可以專門調試分析程序崩潰原因了,gdb同時調試一個運行程序和core文件,然後進行gdb調試的步驟,然後查看代碼崩潰瞬間系統信息。使用如下:gdb ./abort .
  • 一文入門Linux下gdb調試(二)
    該文件也是二進位文件,可以使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb進行打開分析裡面的具體內容。基於core文件的快照功能,我們就可以專門調試分析程序崩潰原因了,gdb同時調試一個運行程序和core文件,然後進行gdb調試的步驟,然後查看代碼崩潰瞬間系統信息。
  • 手把手教你用gdb調試mongod
    本文,介紹如何編譯MongoDB源碼、如何用GDB調試MongoDB。編譯安裝MongoDB因為線上使用的是3.4.24版本,所以本文也採用該版本作為例子。使用info threads命令, 顯示當前可調試的所有線程,每個線程會有一個GDB為其分配的ID,後面操作線程的時候會用到這個ID。
  • eclipse調試arm裸機程序
    串口連接3.nand啟動二、安裝GDB Server解壓:tar xvzf arm-linux-gdb-7.5.tar.gz進入目錄:cd arm-linux-gdb-7.5編譯安裝:./build-all上面執行好後,gdb工具就安裝好了,安裝在/opt/arm-linux-gdb為了方便使用,需要添加環境變量:vim /root/.bashrc在交叉編譯鏈的前面添加gdb的環境變量:export PATH=$PATH:/opt/arm-linux-gdb/bin/export PATH=$PATH:/usr/