我得到了一個奇怪的崩潰在最近沒有改變太多的類的構造函數。我已經削去了很多東西,但這裏是它的要點:C++虛擬表崩潰LLVM/XCode
#define Accessor(PropName, Type, Default) \
Type PropName() { Type *Member = (Type*)Props.Find(Prop##PropName); \
if (Member) return *Member; \
return Default; } \
void PropName(Type t) { Type *Member = (Type*)Props.Find(Prop##PropName); \
if (Member) *Member = t; \
else { Props.Add(Prop##PropName, Member = new Type); \
*Member = t; } \
OnChange(Prop##PropName); }
class GCss
{
GHashTbl<int, void*> Props;
public:
virtual ~GCss() {}
virtual void OnChange(PropType p) {}
Accessor(TextAlign, Len, Len()); // and lots of others obviously
};
class GDom : virtual public GDomI
{
public:
virtual ~GDom() {}
virtual bool GetVariant(const char *Name, GVariant &Value, char *Array = 0) { return false; }
virtual bool SetVariant(const char *Name, GVariant &Value, char *Array = 0) { return false; }
};
class GLayoutCell : public GDom, public GCss
{
public:
};
class TableCell : public GLayoutCell
{
public:
TableCell(GTableLayout *t, int Cx, int Cy)
{
TextAlign(AlignLeft); // this call crashes trying to call 'OnChange'
}
};
看來,vtable中的OnChange方法指針爲NULL。現在我已經做了很多事情來檢查我是不是在做一些愚蠢的事情。使用相當默認的項目設置在XCode 4.5中重新構建代碼,也嘗試了XCode 3.x,並得到了類似的結果。我試過從GLayoutCell繼承一個測試對象,並沒有崩潰。崩潰本身位於名爲Lgi的私人框架中。它是開源的,所以你可以看看這裏:
- GDom.h
- GTableLayout.h,GTableLayout.cpp
- GCss.h,GCss.cpp
我現在敢堅持。我不知道接下來要做什麼。哦堆棧的樣子:
#0 0x00341880 in typeinfo for GDom()
#1 0x00252698 in TableCell::TableCell(GTableLayout*, int, int) at /Users/matthew/Code/Lgi/trunk/src/mac/carbon/../../common/Widgets/GTableLayout.cpp:394
#2 0x0024d9cb in GTableLayout::GetCell(int, int, bool, int, int) at /Users/matthew/Code/Lgi/trunk/src/mac/carbon/../../common/Widgets/GTableLayout.cpp:1562
#3 0x0023f8eb in GProgressPane::GProgressPane() at /Users/matthew/Code/Lgi/trunk/src/mac/carbon/../../common/Widgets/GProgressDlg.cpp:129
#4 0x00241ff8 in GProgressDlg::Push() at /Users/matthew/Code/Lgi/trunk/src/mac/carbon/../../common/Widgets/GProgressDlg.cpp:407
#5 0x00241fb8 in GProgressDlg::OnCreate() at /Users/matthew/Code/Lgi/trunk/src/mac/carbon/../../common/Widgets/GProgressDlg.cpp:366
它似乎是在做與GDom類,它真的沒有任何與GCSS當前類的東西。聞起來像是一個編譯器bug,但我不想跳到結論。順便說一句Valgrind沒有發現任何腐敗。
我敢打賭,它會在一個文件中微妙地改變它的類定義,而這個文件在另一個文件中被理解。如果您在包含頭文件之前更改包含順序或包含不同頭文件,則宏中的錯誤可以爲您執行此操作。這會導致一段代碼期望一個不同於另一個構建的vtable。 – 2013-04-27 07:40:47
@david:我有一個想法,並將該類分成定義和實現,然後將defn移動到文件頂部。所以它是在定義基類的頭文件後面定義的。你猜怎麼着?沒有崩潰......所以現在我只需要繼續將它放在下面的頭部/ defns中,直到它崩潰,然後我隔離了流氓定義。謝謝。 – fret 2013-04-27 08:50:54
好的進一步調查顯示,有兩個同名的類,一個在主App中,另一個在私有框架中。不知何故,編譯器不會標記這一點,或者保留一個錯誤或者正常工作。 – fret 2013-04-27 09:27:37