1. 程式人生 > >mini2440開發板執行Qt程式出現Segmentation fault的另一種奇葩原因:Ubuntu下使用FileZilla通過FTP方式傳輸程式

mini2440開發板執行Qt程式出現Segmentation fault的另一種奇葩原因:Ubuntu下使用FileZilla通過FTP方式傳輸程式

使用QWT-6.1.2寫了一個名為dataplot的小程式,Ubuntu下執行正常,遂交叉編譯後傳到開發板上,執行,報錯:Segmentation fault。

主機環境:Ubuntu 12.04 + gcc 4.6.3 + Qt 4.8.1

開發環境:arm-linux-gcc 4.4.3 with EABI + QtE 4.6.3 (均為mini2440官方提供) 

解決過程

網上查閱一堆資料,各種重新編譯Qt庫、換交叉編譯器等等,實在有些繁瑣,也不能保證符合我的情況,因為前幾天交叉編譯的幾個小程式是可以執行的,應該不是qt庫和qwt庫的問題。

為了簡化問題,直接修改dataplot程式碼,只留下一個顯示提示資訊的label標籤,不能再簡單了。然後交叉編譯,傳到開發板上,仍然Segmentation fault,奇怪!開發板更復雜的Qt程式都執行過,為什麼今天不行了呢?

應該不是程式問題,為了進一步縮小範圍,將前幾天編譯並可以在2440上成功執行的qwt_test程式重新交叉編譯一下,傳到開發板,依然Segmentation fault,簡直不科學。

雖然很奇葩,但是卻也驗證了不是程式碼問題,也不是庫或編譯器的問題。

想到這次與前些天除錯程式的唯一區別就是使用的FTP傳輸軟體不同。博主一直使用FTP方式將程式傳輸到開發板上,之前一直是在windows下通過FlashFXP將Qt程式傳入開發板的,今天為了省事,直接在Ubuntu下使用FileZilla將程式傳入開發板。

試一試,開啟VMware的共享,在Ubuntu中將dataplot程式直接複製到/mnt/hgfs/ubuntu share目錄(這個目錄實際上是Win7宿主機E:/Ubuntu Share目錄,分割槽格式為NTFS)下,然後在Windows下開啟FlashFXP,將Ubuntu Share目錄下的dataplot程式傳入開發板,傳入的時候FlashFXP會提示出現同名但不同大小的新檔案(難道問題就在這裡?)覆蓋,確認覆蓋即可。在開發板上執行dataplot程式,成功執行!

問題雖然解決,但原因博主尚不知道,如果有哪位高人瞭解還請告知。

作為參考,博主Ubuntu下的FileZilla版本是直接apt-get的3.5.3版本,Windows下的FlashFXP是5.0.0版本

================================================================================

下面總結一些網路上解決Qt程式Segmentation fault的方法,以備不時之需

嘗試更換交叉編譯器

很多朋友在移植Qt-embedded 4.xx的時候都使用了友善之臂公司提供的交叉編譯器,
雖然Qt與Qt應用程式都編譯成功,但執行Qt應用程式時卻經常會出現段錯誤(Segmentation Fault),
可以嘗試使用openmoko(一個開源手機專案)提供的編譯器,同樣是EABI,版本為4.1.2
http://www.qtopia.net/modules/mydownloads/singlefile.php?lid=38
經測試,執行Qt應用程式時不會出現段錯誤(Segmentation Fault)。

更改Qt程式執行引數

”應該是QWS_SIZE設定的問題,我有一個程式QWS_SIZE=320x240的時候可以執行,然後設定為QWS_SIZE=320x480就報段錯誤了“

“中文字型問題,執行程式使用./myQtApp -qws -fn SIMHEI”

修改Qt庫並重新編譯

程式 qt-embedded-linux-opensource-src-4.5.0/src/gui/embedded/qscreenlinuxfb_qws.cpp
作如下修改:

410行:
/*            //EmbedSky_del start 20091208
    canaccel = useOffscreen();
    if(canaccel)
        setupOffScreen();
*/            //EmbedSky_del end 20091208
    canaccel = false;

706行:
/*                //EmbedSky_del start 20091208
    if (canaccel) {
        *entryp=0;
        *lowest = mapsize;
        insert_entry(*entryp, *lowest, *lowest);  // dummy entry to mark start
    }
*/                //EmbedSky_del end 20091208
    canaccel = false

可能解決segmentation fault問題,請大家測試

修改了qscreenlinuxfb_qws.h,用友善之臂提供的arm-linux-gcc-4.3.2.tgz重新編譯QT4.5.0-arm(release方式),試了2個程式可以正常執行。

NOTE: This is a HACK, and not a pretty one either. It makes sure that it hardcoded doesn't use off-chip graphic memory. I don't use off-chip graphic memory, but if you do, this hack is useless.

其他

  • “有的時候是因為 原始碼中有多餘的 空格 ,切忌!”
  • “我的是燒寫FLASH有誤導致的”
  • “”有時候是我們編寫的程式的問題,例如我寫了一個:char buff[7]="Hello";就會出現Segmentation Fault 段錯誤,但改成:strcpy(buff,"Hello");後就沒有了!奇怪不?”
  • “我以前遇見過,原因是QT的應用程式介面大小超出”
  • "程式損壞了,或者是開發程式用的Qt庫和部署用的Qt庫不一致。"(程式損壞,這個原因和博主的應該最接近了

參考資料