使用 UCLIBC 交叉编译 PHP [英] Cross compile PHP with UCLIBC

查看:32
本文介绍了使用 UCLIBC 交叉编译 PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个重新发布的帖子,之前的帖子被关闭,移动到服务器故障并再次关闭.我认为这篇文章是一个有效的计算器溢出问题,因为我认为它是由一些自动制作/编译/链接错误.这是编程问题而不是服务器管理员问题.

交叉编译 PHP

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

文章开始

我已经下载了 PHP 5.4.0 源代码,将其解压缩并移动到源文件夹中.

我做了一个配置:

./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/

关注

制作

没有错误,一切正常.接下来我做一个make install.

make install

再次一切正常.我将它移动到目标平台并运行

/usr/arm/www/bin/php -vPHP 5.4.0 (cli)(构建时间:2012 年 8 月 15 日 16:07:41)版权所有 (c) 1997-2012 PHP GroupZend Engine v2.4.0,版权所有 (c) 1998-2012 Zend Technologies

我用我的网络服务器和直接用 php 测试了一个简单的主页.

它按预期工作.接下来我测试:

哦不~

# php shell.php分段故障

我测试了另一个脚本:

#!/bin/php<?phpecho "你好";$handle = fopen("info.txt", "r");回声 $handle;?>

相同的结果:

# php index.php你好分段错误

我有 php.ini 吗?

#/usr/arm/www/bin/php --ini配置文件(php.ini)路径:/etc/加载的配置文件:/etc/php.ini

是的,并且没有禁用的功能.测试strace/usr/arm/www/bin/php index.php

lstat("/srv/www/info.txt", {st_mode=S_IFREG|0644, st_size=20, ...}) = 0打开(/srv/www/info.txt",O_RDONLY)= 3fstat(3, {st_mode=S_IFREG|0644, st_size=20, ...}) = 0lseek(3, 10, SEEK_CUR) = 0--- SIGSEGV(分段错误)@ 0 (0) ---+++ 被 SIGSEGV 杀死 +++

文件 info.txt 存在并且它有读/写的权限.

测试strace/usr/arm/www/bin/php shell.php

fcntl64(3, F_GETFL) = 0(标志 O_RDONLY)ioctl(3, SNDCTL_TMR_TIMEBASE 或 TCGETS, 0x7e31fddc) = -1 EINVAL(无效参数)vfork()= 3324关闭(4)= 0fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0读取(3,总共 24\n-rw-rw-r-- 1 1001"...,8192)= 468阅读(3,"...,8192)= 0--- SIGCHLD(孩子退出)@ 0 (0) ---关闭(3)= 0wait4(3324, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 3324--- SIGSEGV(分段错误)@ 0 (0) ---+++ 被 SIGSEGV 杀死 +++

如果我通过 gdb 运行 index.php,它会给我:

启动程序:/usr/arm/www/bin/php index.php你好程序收到信号 SIGSEGV,分段错误.zend_do_fcall_common_helper_SPEC (execute_data=0x2ac7a040) 在/home/maiden/Downloads/php-5.4.0/Zend/zend.h:391391/home/maiden/Downloads/php-5.4.0/Zend/zend.h:没有那个文件或目录.在/home/maiden/Downloads/php-5.4.0/Zend/zend.h

gdb 从 shell.php 给了我这个启动程序:/usr/arm/www/bin/php shell.php

程序接收信号SIGSEGV,分段错误.zend_do_fcall_common_helper_SPEC (execute_data=0x2ab76040) at/home/maiden/Downloads/php-5.4.0/Zend/zend.h:391391 在/home/maiden/Downloads/php-5.4.0/Zend/zend.h

zend.h 位于/usr/arm/www/include/php/Zend/显然在交叉编译过程中出了点问题.我错过了什么?我没有找到任何配置标志来纠正这个问题,并创建指向所需位置的符号链接会删除 gdb 输出,但 php 仍然存在段错误.

感谢您的帮助!

更新:

# valgrind php test.php==2181== Memcheck,内存错误检测器==2181== 版权所有 (C) 2002-2012 和 GNU GPL,由 Julian Seward 等人所有.==2181== 使用 Valgrind-3.8.0 和 LibVEX;使用 -h 重新运行以获取版权信息==2181== 命令:php test.php==2181====2181== 条件跳转或移动取决于未初始化的值==2181== 在 0x4004EC8:???(在/lib/ld-uClibc-0.9.30-nptl.so 中)==2181====2181== 大小 4 的无效读取==2181== 在 0x4004D48:_dl_get_ready_to_run(在/lib/ld-uClibc-0.9.30-nptl.so)==2181== 地址 0x7d4cc304 就在堆栈 ptr 的下方.要抑制,请使用:--workaround-gcc296-bugs=yes==2181====2181== 大小 4 的无效读取==2181== 在 0x48C348C:__uClibc_main(在/lib/libuClibc-0.9.30-nptl.so 中)==2181== 地址 0x7d4cc554 就在堆栈 ptr 的下方.要抑制,请使用:--workaround-gcc296-bugs=yes==2181====2181== 大小 4 的无效写入==2181== 在 0x233010:__eqdf2 (ieee754-df.S:1120)==2181== 地址 0x7d4cb0bc 就在堆栈 ptr 的下方.要抑制,请使用:--workaround-gcc296-bugs=yes==2181==警告:shell_exec():无法在第 3 行的/test.php 中执行ls -lart"==2181== 大小 4 的无效读取==2181== 在 0x1FF1AC:zend_do_fcall_common_helper_SPEC (zend.h:391)==2181== 由 0x1F3D17: 执行 (zend_vm_execute.h:410)==2181== 由 0x18B217: zend_execute_scripts (zend.c:1279)==2181== 由 0x1365BB: php_execute_script (main.c:2473)==2181== 由 0x22B52B: do_cli (php_cli.c:988)==2181== 由 0x22BD4B: main (php_cli.c:1364)==2181== 地址 0x8 未堆栈、malloc 或(最近)释放==2181==分段故障

更新 2

使用 memcheck 重新运行 valgrind,得到与以前大致相同的输出,但这是新的:

php: 无法解析符号__libc_freeres"

更新 3

虽然 valgrind 失败了,但我继续使用 gdb,我在目标系统上创建了文件夹/home/maiden/..etc 并复制了我的 php/include 文件夹的内容并重新运行 gdb.现在我收到此错误消息:

(gdb) 运行 index.php启动程序:/bin/php index.php你好程序收到信号 SIGSEGV,分段错误.zend_do_fcall_common_helper_SPEC (execute_data=0x2ab34040) 在/home/maiden/Downloads/php-5.4.5/Zend/zend.h:391警告:源文件比可执行文件更新.第391回

这与sixeightzero昨天在评论中所写的非常相似.我现在已经尝试过 PHP 版本 5.3.5、5.4.0、5.4.5 都出现了同样的错误.

更新 4

我为 glibc 下载了一个新的工具链,用 glibc 交叉编译了一个新的 busybox,创建了一个 chroot jail,用 glibc 而不是 uclibc 交叉编译了 php,并在我的 uclibc box 上的 chroot jail 中测试了它,它工作正常!但我仍然需要让 php 在我的 uclibc 环境中工作....

解决方案

我会检查 uClibc 的 configure.log 以查看是否启用了 ARCH_USE_MMU 和 fork.如果不是,vfork 将替换为可能被 shell_exec 使用的 fork.vfork 的主要问题是,父母和孩子使用相同的内存空间,这会导致奇怪的崩溃.

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....

解决方案

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.

这篇关于使用 UCLIBC 交叉编译 PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆