Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python on Arm, Illegal Instructions [closed]

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 :)

like image 209
Daniel Avatar asked Mar 12 '12 07:03

Daniel


2 Answers

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!

like image 162
Daniel Avatar answered Sep 20 '22 19:09

Daniel


It sounds like you are linking to some library that is compiled for a higher architecture than the one on the device. We had the same problem when compiling with CodeSourcery for a device with a ARMv4 CPU. Apparantly the CodeSourcery libraries were compiled for ARMv5. It might be the floating point library like you said, or it might be some other library. Can you find the place in the build-script where the file in question is being compiled and check exactly which libraries are used?

like image 36
Leo Avatar answered Sep 20 '22 19:09

Leo