2009-12-07 50 views
0

我有一個C++應用程序(嚴重縮短,如下所示);從特定庫實例化對象時出現分段錯誤

#include <iostream> 
#include "MyClass.h" 

void foobar() 
{ 
MyClass a; 
} 

int main(int argc, char** argv) 
{ 
std::cout << "Hello world!\n"; 

return 0; 
} 

其中「MyClass」是在靜態鏈接庫(.a)中定義的。

但是,這個應用程序Segfaults開始的瞬間,我永遠不會到達「Hello world」。

我可以從同一個庫中創建一個接口的實例,但我無法創建實現該接口的類的實例。即;

void foobar() 
{ 
IMyClass a; // Having this in the application works. 
MyClass b; // Segfault if this is in. 
} 

正如您從上面看到的,代碼甚至不需要爲應用程序調用segfault。

我使用Netbeans 6.7.1和GCC 4.3.2。

現在,我假設有鏈接的圖書館有問題,但我不知道是什麼。我也鏈接到其他庫(全部靜態鏈接)。上面的類來自第一個鏈接庫(至少在列表中是第一個)。如果我從第二個列出的庫創建一個類的實例,一切運行良好。

這有可能是這個問題是相似的(或相關)到我的其他問題:https://stackoverflow.com/questions/1844190/linking-with-apache-xml-security-causes-unresolved-references

沒有人有可能是什麼問題,有什麼建議?

回答

3

MyClass庫內部可能存在一些靜態初始化錯誤,如果您沒有源代碼,它將很難找到並修復。

+0

我有所有的源代碼,所以如果確實如此,這應該不是問題。我會看一下。 – 2009-12-07 10:09:44

+0

Ahhhhhhhh。找到錯誤的代碼;對swscanf的調用導致出錯。 (我不知道代碼有什麼問題,但這是不同的時間。) – 2009-12-07 11:28:32

0

一個Stackoverflow。

MyClass可能會很大以適應堆棧。

+0

呃,好嗎?我如何解決這個問題?儘管如此,我不太確定這是否是問題。如果我在同一個庫中創建一個虛擬類並嘗試引用它,我會得到相同的錯誤。 – 2009-12-07 10:03:05

+2

但他沒有調用foobar,所以MyClass從未放在堆棧上 – 2009-12-07 10:03:13

+0

如果是這種情況,請聲明一個指向MyClass的指針,並從堆中取出新的指針。如果這個問題解決了。 – rerun 2009-12-07 10:04:18

1

如果您正在Linux或OS X上開發,您可以通過在調試模式下編譯並使用valgrind運行,獲得更多有關此類錯誤的信息。

在調試模式下編譯並不是絕對必要的,但會給出關於哪裏出錯和在哪裏的更好的信息。

我也會在調試模式下編譯包含MyClass的庫。

另一件需要注意的事情是庫編譯時使用相同的編譯器標誌,因爲在兩種編譯器設置下,靜態對象具有不同的內部佈局時會發生這種類型的崩潰。 (我花了很長時間在使用-DREENTRANT部分代碼編譯部分應用程序時進行跟蹤,而不是在另一部分代碼中,第三方組件在兩種情況下以不同佈局結束。)

+0

謝謝。使用Valgrind允許我在幾秒鐘內找出問題。 (如果可以的話,我也會將你的回答設置爲答案。) – 2009-12-07 11:30:23

0

As far ,正如我從代碼中瞭解到的,foobar永遠不會被調用?只是聲明它會導致段錯誤?

我可以想象,聲明一個MyClass變量會導致一些模板實例化,它實現了一些靜態初始化,失敗。比如說,MyClass從SomeBase <&gt;派生,並且不可能在SomeBase <>中執行一些靜態成員的初始化。當你刪除MyClass變量的聲明時,模板沒有實例化,並且一切順利......

class MyClass : public SomeBase<MyClass>{}; 

template<typename TYPE> 
class SomeBase<TYPE> { static CauseASegfault* m_casf; }; 

// some bad m_casf initialization here... 
+0

是的,代碼永遠不會被調用。另外,我是否聲明瞭一個基本上爲空的類的實例並不重要。 – 2009-12-07 11:06:22