author:lihaiping1603@aliyun.com
date:2019-12-20
如何生成dump core文件?
當我們在linux下將ffmpeg編譯好之后,進入運行調試階段,突然ffmpeg就cash了,提示出現了一個莫名其妙的"segment fault(段錯誤)"。然后我們想找出他崩潰時候出現的堆棧信息,這時候我們想到了dump core文件,但ls一看,當前目錄下是空的,並沒有任何的core文件生成,這時候如何是好呢?
一般來說程序cash了,都會生成一個core文件的,但為什么生成不了呢?是不是被系統限制了啥?網上一查,果然如此。我們要判斷是不是系統限制,可以通過命令 ulimit -a 查看當前系統core文件的大小限制。
例如:


這種情況,說明core文件被限制,因為他限制生成core文件的大小為0,那也就是生成不了core文件。
如何解除這種限制呢?辦法是通過ulimit -a unlimited 來解除,運行這條命令以后,我們再ulimit -a查看一下:


這個時候,我們再運行ffmpeg,如果崩潰的話,就會在當前命令生成相應的core文件了。
通過gdb和core查看堆棧信息,堆棧信息中全是??,並不能找到代碼對應的堆棧函數信息
通過上一步,我們能生成cash當時的core文件了,但當gdb 該core文件的時候,堆棧信息卻是一堆??,這個是什么原因導致的?我們如何解決這個問題?
這個問題的主要原因是因為我們的ffmpeg在編譯的時候沒有開啟調試選項信息,如果我們需要生成的core文件能有效的話,我們需要在編譯ffmpeg的時候,不能去掉strip符號信息,而ffmpeg默認是去掉strip符號 信息的,所以我們編譯配置的時候,需要加上./configure --enable-debug --disable-optimizations --disable-asm --disable-stripping 。
這時候生成的core文件堆棧信息就能顯示相關詳細函數了。
例如:


ffmpeg filter中,關於frame的釋放出現的一個bug
最近在開發filter的時候,出現了一個frame釋放的bug,其實這個是一個個人人為造成的bug,但還是在這里記錄一下。
在filter中,我們經常從prev filter拿到幀數據以后,可能在current filter中直接對幀數據進行修改,也可能需要對這個幀數據需要進行先拷貝,然后再修改的過程(可參考writing_filter.txt或者我翻譯的writing_filter_zh.md )。
而我在自己開發的這個filter中,我是先從緩沖器中獲取到一個src frame之后,先對他進行一個scale,然后scale以后,我就把src frame給free了,因為我覺得這個frame,我后續用不到了,所以選擇釋放掉,防止內存釋放,但就因為我這個釋放,導致ffmpeg在用到這個filter的時候,就崩潰了,你說尷尬不,一開始我還莫名其妙。
后面再閱讀了一次writing_filter.txt中的內容,我就知道我犯了啥錯誤,我這個地方從緩沖器中獲取到的frame,不應該由我釋放,因為他被其他地方引用了,所以這里有兩個方式,
1,修改之前先拷貝一次,然后去scale
2,不拷貝,那也就不用釋放
這個過程可以多參考幾個源碼中的filter寫法。
一般來說,如果我們獲取到的這個frame,先拋棄掉我們自己的處理過程(假如我們啥都不做的話),如果這個frame是直接被傳遞到next filter當中的話,那么我們就需要對這個frame釋放,我們有它的所有管理權限,例如crop中的frame。如果不是直接被傳遞到next filter的話,那我們就需要更加謹慎處理了,需要判斷我們可以釋放the frame,例如overlay濾鏡當中的do blend函數,通過ff_framesync_dualinput_get_writable 函數獲取到的mainpic 和second 兩個frame,因為mainpic ,我們是直接后續會傳遞給next filter的,所以我們在當前filter中進行釋放,他是沒有問題的,但second 這個frame,我們是不能進行釋放的,他被緩存了,所以如果選擇釋放的話,就會出現崩潰cash的可能。
diff 生成補丁文件
在開發一個filter之后,我們需要通過diff 命令:diff -Naru file_old file_new > differences.patch
來生成補丁文件,后續再其他的場景下,我們直接用這個補丁文件,進行打補丁就OK,防止人為的二次修改導致出現的bug。
轉載請注明出處:https://www.cnblogs.com/lihaiping/p/12072323.html
