關於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都給安排的明明白白了?