Cross compile PHP with UCLIBC
Asked Answered
U

1

9

THIS IS A REPOST, PREVIOUS POST GOT CLOSED, MOVED TO SERVERFAULT AND CLOSED AGAIN. I think this post is a valid stackoverflow problem because i think its caused by some automake/compile/linking error. This is a programming problem not a server admin problem.

Cross compile PHP

https://serverfault.com/questions/418521/cross-compile-php

Start of post

I have downloaded the PHP 5.4.0 source, extracted it and moved into the source folder.

I do a configure with:

./configure --build=x86_64-unknown-linux-gnu --host=arm-linux-uclibcgnueabi --prefix=/usr/arm/www CC="arm-linux-uclibcgnueabi-gcc --sysroot=/toolchains/gnu_cortex-a9_tools/"  --disable-libxml --disable-dom  --without-iconv --without-openssl --disable-simplexml --disable-xml --disable-xmlreader --disable-xmlwriter --without-pear --without-sqlite3 --disable-pdo --without-pdo-sqlite --disable-phar  --with-config-file-path=/etc/

Followed by

make

no errors, everything runs fine. Next i do a make install.

make install

Again everything runs fine. i move it to the target platform and run

/usr/arm/www/bin/php -v
PHP 5.4.0 (cli) (built: Aug 15 2012 16:07:41) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

I test a simple home page with my webserver and directly with php.

<?php echo "hello" ?>
# php index.php
hello

it works as expected. next i test:

<?php
$output = shell_exec('ls -lart');
echo "<pre>$output</pre>";
?>

oh noes~

# php shell.php 

Segmentation fault

I teset another script:

#!/bin/php
<?php

echo "hello";
$handle = fopen("info.txt", "r");
echo $handle;
?>

Same result:

# php index.php 
helloSegmentation fault

do i have a php.ini?

# /usr/arm/www/bin/php --ini
Configuration File (php.ini) Path: /etc/
Loaded Configuration File:         /etc/php.ini

yes, and no disabled functions. testing strace /usr/arm/www/bin/php index.php

lstat("/srv/www/info.txt", {st_mode=S_IFREG|0644, st_size=20, ...}) = 0
open("/srv/www/info.txt", O_RDONLY)     = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=20, ...}) = 0
lseek(3, 10, SEEK_CUR)                  = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

the file info.txt exists and it got premission to read/write to it.

Testing strace /usr/arm/www/bin/php shell.php

fcntl64(3, F_GETFL)                     = 0 (flags O_RDONLY)
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7e31fddc) = -1 EINVAL (Invalid argument)
vfork()                                 = 3324
close(4)                                = 0
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
read(3, "total 24\n-rw-rw-r--    1 1001    "..., 8192) = 468
read(3, ""..., 8192)                    = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
close(3)                                = 0
wait4(3324, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 3324
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

if i run the index.php through gdb it gives me:

Starting program: /usr/arm/www/bin/php index.php
hello
Program received signal SIGSEGV, Segmentation fault.
zend_do_fcall_common_helper_SPEC (execute_data=0x2ac7a040) at /home/maiden/Downloads/php-5.4.0/Zend/zend.h:391
391 /home/maiden/Downloads/php-5.4.0/Zend/zend.h: No such file or directory.
    in /home/maiden/Downloads/php-5.4.0/Zend/zend.h

gdb gives me this from shell.php Starting program: /usr/arm/www/bin/php shell.php

Program received signal SIGSEGV, Segmentation fault.

zend_do_fcall_common_helper_SPEC (execute_data=0x2ab76040) at /home/maiden/Downloads/php-5.4.0/Zend/zend.h:391
391 in /home/maiden/Downloads/php-5.4.0/Zend/zend.h

zend.h is located in /usr/arm/www/include/php/Zend/ obviously something went wrong during cross compilation. what have i missed? i do not find any configure flag to correct this and creating a symlink to the desired location removes the gdb output but php still segfaults.

Thanks for any help!

UPDATE:

# valgrind php test.php
==2181== Memcheck, a memory error detector
==2181== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==2181== Using Valgrind-3.8.0 and LibVEX; rerun with -h for copyright info
==2181== Command: php test.php
==2181==
==2181== Conditional jump or move depends on uninitialised value(s)
==2181==    at 0x4004EC8: ??? (in /lib/ld-uClibc-0.9.30-nptl.so)
==2181==
==2181== Invalid read of size 4
==2181==    at 0x4004D48: _dl_get_ready_to_run (in /lib/ld-uClibc-0.9.30-nptl.so)
==2181==  Address 0x7d4cc304 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==2181==
==2181== Invalid read of size 4
==2181==    at 0x48C348C: __uClibc_main (in /lib/libuClibc-0.9.30-nptl.so)
==2181==  Address 0x7d4cc554 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==2181==
==2181== Invalid write of size 4
==2181==    at 0x233010: __eqdf2 (ieee754-df.S:1120)
==2181==  Address 0x7d4cb0bc is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==2181==
Warning: shell_exec(): Unable to execute 'ls -lart' in /test.php on line 3
==2181== Invalid read of size 4
==2181==    at 0x1FF1AC: zend_do_fcall_common_helper_SPEC (zend.h:391)
==2181==    by 0x1F3D17: execute (zend_vm_execute.h:410)
==2181==    by 0x18B217: zend_execute_scripts (zend.c:1279)
==2181==    by 0x1365BB: php_execute_script (main.c:2473)
==2181==    by 0x22B52B: do_cli (php_cli.c:988)
==2181==    by 0x22BD4B: main (php_cli.c:1364)
==2181==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==2181==
Segmentation fault

Update2

re-run valgrind with memcheck, got about the same output as before but this was new:

php: can't resolve symbol '__libc_freeres'

Update3

While valgrind have failed me, i continued with gdb, i created the folder /home/maiden/..etc on my target system and copied over the content of my php/include folder and re-run gdb. now i get this error message:

(gdb) run index.php 
Starting program: /bin/php index.php
hello
Program received signal SIGSEGV, Segmentation fault.
zend_do_fcall_common_helper_SPEC (execute_data=0x2ab34040) at /home/maiden/Downloads/php-5.4.5/Zend/zend.h:391
warning: Source file is more recent than executable.
391     return --pz->refcount__gc;

this is very similar to what sixeightzero wrote in the comments yesterday. I have now tried PHP version 5.3.5, 5.4.0, 5.4.5 same error on all.

Update4

I downloaded a new toolchain for glibc, cross compiled a new busybox with glibc, created a chroot jail, cross compiled php with glibc instead of uclibc and tested it inside my chroot jail on my uclibc box, and it works! But i still need to get php to work in my uclibc environment....

Urania answered 17/8, 2012 at 11:4 Comment(12)
Sorry mate, I suggested it be moved as I thought it would get you more answers as your previous question wasn't going anywhere here. My bad :(Dysplasia
GAAHWAAAH!!! RAAAGE!! was 6h from bounty, now i have to wait 2 more days. >_< , a well no hard feelings, you had a good intent. I left a bugreport @ PHP.net, lets see where that will take me. ^_^Urania
@Maidenone, on the bright side, now is an excellent time to suggest a more embedded friendly language, like Embedded Lua eluaproject.net or some other #191722 instead of PHP, Fractal of Bad Design... ;-)Lux
Sorry mate, if it helps, I did promote it and catch it with three close votes already :(Dysplasia
Some ideas. Switch to eglibc.org/faq . There are also some settings for uclibc to make it slightly more compatible with glibc, such are allocating memory when you call it with malloc(0)Lux
Sadly i do not have any option in this case.. I am stuck with linux 2.6.34 with uclibc. >_< Temporary solution: have php and lighttpd installed in my glibc chroot jail and have the backend system running in my uclibc env.Urania
Temporary solutions are the most permanent. Go for it. :-)Lux
70Mb overhead on a embedded system just to get PHP to work? i do not think so. but it will have to do for now..Urania
Can you check binaries with a tool like readelf and see their version, endianness, etc is same? and have you tried with a newer version of uClibc? I would also experiment with --enable-shared --disable-static (toggle enable/disable) as well as --with-gnu-ld.Hellkite
Can you reproduce on any arm emulators? i.e. armware, qemu, ARMphethamine. If yes and you can give us detailed instructions on how to duplicate both host and target environments with exact instructions of what you are doing step by step spare no detail, links to downloads or exact version numbers a must. Unfortunately this is not a suitable channel to solve problems with so many variables, stabs in the dark at best. I'm sorry that you've been battling with this for so long, must be frustrating I know, maybe if we can reproduce the problem with your instruction, we might actually get somewhere.Celestina
I do not know if it helps at all, but if you want to see how another embedded project compiles PHP with uClibc, check freetz.org/browser/trunk/make/php. It is on MIPS, but some configure and toolchain issues might be similar. In the repo you also find the toolchain makefiles and patches for uClibc.Perish
Just a hint: the gdb errors and valgrind errors which list filenames are not looking for the files in those locations; the locations are where you had them on your original host when compiling. php doesn't need the include files when running...Circumvent
C
3

i would check configure.log of uClibc to see if ARCH_USE_MMU and fork is enabled. if not vfork is replaced with fork which is likely to be used by shell_exec. the main problem with vfork is, parent and child uses same memory space which leads to weird crashes.

Cornetist answered 17/8, 2012 at 13:6 Comment(1)
I would like to check that as well. but i only got binary blobs from my CPU manufacturer. But i would be surprised if it was disabled. We got a webkit browser, Qt and DirectFB going with the same toolchain.Urania

© 2022 - 2024 — McMap. All rights reserved.