Search code examples
pythonarmcross-compilingscratchbox

Python on Arm, Illegal Instructions


I am trying to compile Python 3.2 for an ARM920T (architecture 4T) but I am getting some strange errors.

I am compiling Python inside a Scratchbox environment, configured to use the following compiler: "gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)" which is an arm cross compiler.

When compiling I have made sure to set the -march=armv4t architecture flag, in the following environment variables: CFLAGS, CPPFLAGS, SBOX_EXTRA_COMPILER_FLAGS.

It compiles fine in scratchbox, and I am able to run the python interpreter with the scratchbox arm emulator.

When I move it to my ARM920T however, I get an Illegal Instruction error immeadiately after running the python exe.

A core dump yeilds the following output:

Program terminated with signal 4, Illegal instruction.
#0 0x00138810 in __aeabi_dadd ()

And the first few lines of the back-trace:

#0  0x00138810 in __aeabi_dadd ()
#1  0x001134f4 in PyLong_FromString (str=0x402de300 "3644798167", pend=0x0, base=10) at Objects/longobject.c:2001
#2  0x00132478 in parsenumber (s=<value optimized out>, c=<value optimized out>) at Python/ast.c:3189
#3  ast_for_atom (n=<value optimized out>, c=<value optimized out>) at Python/ast.c:1396
#4  ast_for_power (n=<value optimized out>, c=<value optimized out>) at Python/ast.c:1726
#5  ast_for_expr (c=0xbeaf7f50, n=0x402f5b78) at Python/ast.c:191

As far as I have been able to research, the __aeabi_dadd call is a library call for adding two floating point numbers (Double Add).

I looked up the python code which the backtrace reports is causing the error (longobject.c line 2001):

if (log_base_BASE[base] == 0.0) {
            twodigits convmax = base;
            int i = 1;

            log_base_BASE[base] = (log((double)base) /        // Line 2001
                                   log((double)PyLong_BASE));
            for (;;) {
                twodigits next = convmax * base;
                if (next > PyLong_BASE)
                    break;
                convmax = next;
                ++i;
            }

I dont really see why this code should cause any errors. I tried making a small C++ program which added/subtracted/divided e.t.c a lot of doubles, like in the code above, and it ran fine on the device.


Any help would be much appreciated. The only things I can think of is that perhaps the wrong floating point library is being compiled into the exe. The ARM920T does not have hardware floating point support as far as I could tell from Google.

Another cause could be alignment errors. When compiling Python with the -Wcast-align flag, it does report a few casting warnings. The ARM doesn't like it when certain data-types are not aligned at even addresses in memory. /proc/cpu/alignment does not report anything however.

Sorry for the wall of text, thanks if you read this far :)


Solution

  • I found the solution!

    I made a file-dump of everything spewed out on the console during the make call, and I noticed that a few calls to gcc did not contain the -march=armv4t option.

    I noticed that I had spelled the SBOX_EXTRA_COMPILER_FLAGS wrong. It should be SBOX_EXTRA_COMPILER_ARGS. With that set, and CFLAGS set to -march=armv4t Python now successfully builds and runs without illegal instructions.

    Thanks Leo, for pointing me in the right direction!