Issue
I'm using GCC 3.4.3. The device is a POS terminal PAX S80 based on ARM9/ARM11. The next test code compiles okay, but during runtime when calling an overridden function I get an exception.
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;
}
It means that I cannot use static objects (Derived2). Yes, I can create objects in the code (Derived), but it complicates the code as I need to instantiate objects with a "new" operator.
Are there any tricks to avoid this problem?
By the way, I don't have this issue on the Keil compiler for ARM926. Unfortunately, I cannot choose a compiler for this device, only GCC 3.4.3.
Thanks for any ideas!
Solution
The reason was that the initialization of static objects didn't occur. So, I decided to do it manually.
Firstly, I added the next lines to the linker script (source):
__ctors_start__ = .;
KEEP(SORT(*)(.ctors))
__ctors_end__ = .;
Secondly, I invoke a function which calls all the constructors of static objects (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;
}
Eventually, overridden functions work and static objects operate as usual. Thanks to all!
Answered By - ko80