C ++虚拟表崩溃LLVM / XCode

时间:2013-04-27 07:24:44

标签: xcode crash llvm

我在最近没有太大变化的类的构造函数中遇到了一个奇怪的崩溃。我已经删除了很多东西,但这是它的要点:

#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.hGTableLayout.cpp
- GCss.hGCss.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当前类无关。闻起来像编译器错误,但我不想妄下结论。 Btw Valgrind没有发现任何腐败。

1 个答案:

答案 0 :(得分:0)

“答案”是在不同的二进制文件中有两个具有相同名称的类。一个在可执行文件中,一个在exe加载的私有框架中。不知何故,XCode 4.5中的编译器/链接器无法检测到这种情况,并且无法链接或加载进程。无论出于何种原因,Visual Studio / Windows都能正常管理。

所以我在App中重命名了这个类,它运行正常。 叹息

大卫建议使用cppcheck或类似的声音,如良好的长期建议。