2017-08-25 396 views
2

我有一個很奇怪的問題。我們的公司應用程序是一個用C++編寫的桌面應用程序,並使用Visual Studio 2017進行編譯。在過去的幾個星期裏,有時應用程序在進入main之前會崩潰。我知道這一點,因爲我在main的第一行放置了斷點,並且它永遠不會被調用。碰撞不會很快發生,所以我有時間在診斷工具中全部按下休息。但是我只收到一條消息'你的應用程序已進入休息狀態,但沒有代碼顯示,因爲所有線程都在執行外部代碼(通常是系統或框架代碼)「。有時清理所有東西並重建會使代碼正常工作,但有時候不會。在進入main之前程序崩潰時該怎麼辦?

我甚至不知道如何開始調查此問題,代碼已有幾年的歷史,並且從未遇到過這個問題。

不知道該怎麼辦?

編輯

至於建議,我在WinMainCRTStartup設置斷點,我跟蹤這個問題到線224功能__scrt_common_main_seh()在exe_common.inl:

如果(_initterm_e(__ xi_a,__xi_z)= 0) return 255;

該行失敗,所以該函數返回255,我的主永遠不會被調用。還有什麼想法?

+2

*任何*崩潰通常要做的就是在調試器中捕捉它,並找到它發生的代碼的位置。如果它不是源自你的代碼,那麼你應該在'main'函數中尋找大數組,因爲Windows每個進程只有一個默認的一兆字節的堆棧,並且在'main'之前似乎崩潰了,通常是你有一個符號由於存在多個或大型局部變量(局部變量,包括數組),導致堆棧溢出通常存儲在堆棧中。 –

+1

如果你不*有任何大型數組,那麼調試器應該已經捕捉到了崩潰,並且很可能指出了一些全局變量的初始化。 –

+1

我會檢查的一個選項是一些缺失的依賴關係。如果您擁有所有依賴的dll驗證工作目錄是否設置正確 – Dusteh

回答

0

我終於讓我的程序再次運行。原因是該程序現在使用Visual Studio 2017進行編譯,但是一些與我的程序靜態鏈接的庫是使用以前的Visual Studio構建的,在使用Visual Studio 2017重新編譯它們之後,我的程序運行良好。

因此,如果程序在退出之前崩潰,則要檢查是否確保使用相同的編譯器和使用相同的編譯器開關構建所有庫。

2

假設調試器在捕獲方面有問題,我有一個想法,只有可能工作。 如何通過set_terminate設置您自己的terminate功能? http://www.cplusplus.com/reference/exception/set_terminate/ 你可以在靜態全局變量的構造函數中完成它,它可能在崩潰你的軟件之前被調用。不確定的初始化靜態變量的順序是不確定的。 嘗試在其中設置斷點。

int main() 
{ 
    throw 0; 
    return 0; 
} 

struct reterminator 
{ 
    static void myterminate() { 
     std::cerr << "terminate handler called\n"; 
     abort(); // forces abnormal termination 
    } 

    reterminator() 
    { 
     std::set_terminate(myterminate); 
    } 
} static reterminator_; 
相關問題