1

最近あまり変更されていないクラスのコンストラクターで奇妙なクラッシュが発生しています。かなり省略しましたが、要点は以下の通りです。

#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

GCss の現在のクラスとはまったく関係のない GDom クラスで何かを行っているようです。私にはコンパイラのバグのようなにおいがしますが、結論に飛びつきたくありません。ところで、Valgrind は破損を発見しませんでした。

4

1 に答える 1

0

「答え」は、異なるバイナリに同じ名前の 2 つのクラスがあったことです。1 つは実行可能ファイルにあり、もう 1 つは exe がロードするプライベート フレームワークにあります。どういうわけか、XCode 4.5 のコンパイラ/リンカーはそれを検出できず、プロセスのリンクまたはロードに失敗します。Visual Studio / Windows は、何らかの理由でこの罰金を管理します。

そのため、アプリのクラスの名前を変更しましたが、正常に動作しています。はぁ

cppcheck などを使用するという David の提案は、長期的なアドバイスのように聞こえます。

于 2013-04-28T09:34:35.617 に答える