背景
如果你是一個FFmpeg的使用者,那麼絕大部分情況下只需要在你的程式中引用FFmpeg的libav*
相關的標頭檔案,然後在編譯階段連結相關的庫即可。但是如果你想除錯FFmpeg內部相關的邏輯,或者分析FFmpeg原始碼,那麼有一個可供單步除錯FFmpeg的環境往往能使你事半功倍。
步驟
本文將介紹如何在Linux下(以Ubuntu 18.04 LTS為例)通過FFmpeg原始碼(以4.4版本為例)編譯出一個相對簡潔的FFmpeg可執行程式,並通過gdb
或者VS Code
對其進行單點除錯。
獲取原始碼
首先從FFmpeg的官方github獲取對應的原始碼:
本文將以release/4.4
分支版本的原始碼為例:
git clone https://github.com/FFmpeg/FFmpeg.git -b 4.4/release
編譯
如上文所說,既然是要編譯FFmpeg的相對簡潔的版本,就意味著編譯出來的庫的功能並非大而全,本文也僅僅是為了演示如何編譯與除錯FFmpeg,不希望有太多額外的庫依賴步驟(以免擾亂初學者的學習節奏)。
若有需要除錯額外的功能(如x264),只需要在編譯FFmpeg的時候開啟對應的功能(如 --enable-x264
)再重新編譯即可,本文不做贅述。
和Linux下絕大多數編譯步驟一樣,先執行./configure
來配置專案;在執行FFmpeg的./configure
的時候記得開啟除錯選項--enable-debug
以保留除錯符號,方便我們後續除錯:
cd FFmpeg
./configure --disable-shared --enable-static --disable-asm --enable-debug
make
# ☕ 編譯相對耗時,請耐心等待..
好了,經過漫長的編譯等待過程,我們可以看到當前目錄下有多了ffmpeg_g
和ffprobe_g
2個檔案,這2個結尾帶_g
的便是攜帶了編譯符號可除錯的可執行檔案。
除錯
我們以最簡單的檢視ffmpeg版本的命令為例:
./ffmpeg_g -version
來分別介紹如何使用gdb或者VS Code對程式進行單步除錯。
使用gdb除錯ffmpeg
首先執行gdb
,指定除錯程式:
gdb ./ffmpeg_g
好了,接下來的命令都是在gdb的互動中進行。
先設定執行引數為-version
:
set args -version
將斷點打在main
函式入口處:
b main
設定顯示原始碼佈局:
layout src
開始執行程式:
run
此時遇到斷點main
會自動停下:
關於gdb的相關操作不是本文的重點,請自行搜尋學習,如果本文不做贅述。
如果希望能夠更方便地在gdb除錯過程中參照原始碼,可以嘗試使用
cgdb
這個工具,它其實就是基於gdb
包裝多了一層命令列視覺化互動介面,方便在除錯過程中邊看原始碼邊除錯,詳情可以檢視本號的文章:cgdb | 一起邊看原始碼邊除錯gdb吧
使用VS Code除錯ffmpeg
如今的VS Code經過多個版本的迭代,已經不僅僅是一個簡單的編輯器,開發者通過各個強大的外掛可以把它打造成一個類IDE的工具。
在Ubuntu的環境下你可以通過直接安裝Linux版本的VS Code來使用,當然你也可以在其他系統上安裝好VS Code然後通過Remote - SSH外掛來遠端開啟你的原始碼工程。
言歸正傳,要使用VS Code來除錯C/C++專案,需要至少先安裝如下2個VS Code外掛:
- C/C++
- C/C++ Runner
首先,你需要在VS Code中開啟你的ffmpeg目錄。
然後在VS Code中同時按下Ctrl + Shift + P開啟輸入"launch.json",選擇Open 'launch.json' 來開啟除錯的啟動配置檔案,主要修改以下關鍵地方:
// 把要除錯的程式路徑填好:
"program": "${fileDirname}/../ffmpeg_g",
// 執行引數為 -version:
"args": ["-version"],
註釋掉"preLaunchTask"一行,因為我們已經編譯過了,也不想使用它預設的編譯步驟
// "preLaunchTask": "C/C++: gcc 生成活動檔案",
總體的配置如下,修改完記得儲存檔案:
{
"version": "0.2.0",
"configurations": [
{
"name": "gcc - 生成和除錯活動檔案",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/../ffmpeg_g",
"args": ["-version"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "為 gdb 啟用整齊列印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
// "preLaunchTask": "C/C++: gcc 生成活動檔案",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
好了,此時你可以開啟想要除錯的檔案,以本次要除錯的ffmpeg_g
為例,開啟ffmpeg.c
檔案,然後把滑鼠挪到行號的左邊會出現一個淡淡的小紅點,點下之後會顯示紅點,代表你在本行打了一個斷點。
此時按下F5
鍵,會啟動除錯模式,並把斷點停留在你打的斷點處:
你可以點選上方的工具欄來執行相關除錯操作,也可以使用快捷鍵來進行操作:
F5
:繼續執行F10
:單步跳過F11
:單步除錯Shift + F11
:單步跳出Shift + F5
:停止除錯
左邊的DEBUG工具欄可以讓你輕鬆地檢視本地變數和暫存器,可以新增相關的變數監視,也可以檢視函式的呼叫堆疊等資訊。
關於VS Code除錯C/C++的步驟非本文重點,網上有很多教程,請自行搜尋學習。
歡迎關注我的公眾號^^