I'm stumped. The following simple C++ program runs fine on i386 Linux, but when compiled with 4.3.2 version of arm-none-linux-gnueabi-g++ and executed on the arm platform, it crashes with an "Illegal Instruction" when it tries to call the virtual function. Output on i386: main Made it! Output on arm: main Illegal instruction The program is as follows: ------------------ CUT HERE ------------------ #include <stdio.h> #include <stdlib.h> class Illegal { public: virtual void Crash(); }; void Illegal::Crash() { printf("Made it!\n"); } int main() { printf("main\n"); Illegal* i=new Illegal(); i->Crash(); delete i; } ------------------ CUT HERE ------------------ Anything I'm missing? Is there a version of the compiler that fixes this apparent compiler bug?
Illegal Instruction using virtual function
As a follow up, I tried using a function pointer instead of a virtual method. Same result: It works on i386 and produces an "Illegal Instruction" on arm. On the off chance it might be a cache-coherency issue on the arm platform, I tried using a volatile function pointer, but the problem remains.
Is toolchain compiled only for arm920 or it is multi? If multi you need to specify cpu type something like : -march=armv4t when cross compile. Seems to me it's compiled for wrong cpu. thanks, marek
Warren, Seeing as I didn't have a clue I searched the post title and found this: http://www.artima.com/cppsource/pure_virtual.html All I can say is good luck, it looks like you found a real knarly problem! Dave
open-nandra, you were on the right track. The default CPU for my compiler turns out to be arm10tdmi, and while the instructions produced worked fine for most of my nearly 5000 line program, when I tried virtual functions, or function pointers (same underlying logic), I ran into the problem. I didn't even suspect the CPU being the issue because I hadn't noticed what the target CPU was (since it "just worked" until now). When I compiled to assembly source I noticed the use of the BLX instruction was causing the crash. Then I noticed the target CPU comment in the assembly source. Adding the -mcpu=arm9 flag fixes the problem nicely. For those who might not know how to go about this (compile to assembly, examine the source, then assemble and link), here are the steps: -------- CUT HERE ------------ # Define path to cross-compiling toolchain X=/path/to/arch-arm/gcc/usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi- # Compile to assembly source ${X}g++ -mcpu=arm9 -S -Werror -Wl,-export-dynamic -o test.a test.c # Here you can examine test.a to see what actual assembly code is # produced. Feel free to modify and experiment at this stage, # then continue. # Assemble to object code ${X}as --gstabs -L -o test.o test.a # Link ${X}g++ -o test test.o -------- CUT HERE ------------ Thanks all for your replies.
Hi Warren, I'm not an expert, but try to use this flags too: -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t