【问题标题】:GCC: exception when calling an overridden function of a static objectGCC:调用静态对象的覆盖函数时出现异常
【发布时间】:2015-11-02 07:15:18
【问题描述】:

我使用的是 GCC 3.4.3。该设备是基于ARM9/ARM11的POS终端PAX S80。下一个测试代码编译正常,但在运行时调用覆盖函数时出现异常。

class TBase {
public:
    int a;
    virtual void Foo()  {a = 1;}
            void Exec() {Foo();}
};

class TDerived : public TBase {
public:
    virtual void Foo()  {a = 2;}
};

TBase    *Base;       //pointer to object in heap
TBase    Base2;       //static object

TDerived *Derived;    //pointer to object in heap
TDerived Derived2;    //static object

int main() {

    Base = new TBase;
    Base->Exec();              //this passes okay

    Base2.Exec();              //this passes okay

    Derived = new TDerived;
    Derived->Exec();           //this passes okay

    Derived2.Exec();           //here I get an exception and the app crashes

    return 0;
}

这意味着我不能使用静态对象(Derived2)。是的,我可以在代码中创建对象(Derived),但它会使代码复杂化,因为我需要使用“new”运算符来实例化对象。

有什么技巧可以避免这个问题吗?

顺便说一句,我在 ARM926 的 Keil 编译器上没有这个问题。不幸的是,我无法为此设备选择编译器,只能选择 GCC 3.4.3。

感谢您的任何想法!

【问题讨论】:

  • 你得到了什么异常?
  • 顺便说一句,你确定//static object in application stack 吗?我不声称对“PAX S80”一无所知,但通常全局变量在堆上的分配方式与通过new 相同。
  • 是的,你是对的。我已经更新了我的问题。
  • 异常的信息是这样的:“WARNING! APP EXCEPTION DFSR:000000fd IFSR:00000000 2821e954 80000010, 80000197”
  • 这在 i386-64 上工作得非常好,而且这个功能非常基本,在任何拱门上都不应该有区别。我怀疑它可能是一个编译器错误 - 你应该搜索 GCC 的错误数据库,看看你是否找到类似的东西。

标签: c++ gcc heap-memory virtual


【解决方案1】:

原因是静态对象的初始化没有发生。所以,我决定手动完成。

首先,我将下一行添加到链接器脚本 (source):

__ctors_start__ = .;
KEEP(SORT(*)(.ctors))
__ctors_end__ = .;

其次,我调用了一个函数,该函数调用了静态对象的所有构造函数 (source):

void do_ctor_calls() {

    typedef void (*call_ctor_t)(void);
    extern call_ctor_t __ctors_start__[];
    extern call_ctor_t __ctors_end__[];

    call_ctor_t * ctor_call = __ctors_start__;
    while ((ctor_call < __ctors_end__)&&((unsigned int)*ctor_call!=0xFFFFFFFF)&&((unsigned int)*ctor_call!=0x00000000)) {
        (*ctor_call)();
        ctor_call++;
    }
}

int main() {
    do_ctor_calls();

    /* My code here */

    return 0;
}

最终,被覆盖的函数可以正常工作,静态对象也照常运行。 谢谢大家!

【讨论】:

  • 终端厂商对此问题有何评论?
  • @Matt,很遗憾,我没有直接询问 PAX,因为我们公司与当地的 PAX 经销商有协议。公司规则,你知道的。
  • 呃。在没有直接供应商支持的终端上编码是非常不愉快的,尤其是当您发现错误时
  • @Matt 我习惯于在没有调试器和任何支持的情况下进行开发。所以,这很有趣;-)
猜你喜欢
  • 1970-01-01
  • 2015-05-27
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多