【问题标题】:Cross compile PHP with UCLIBC使用 UCLIBC 交叉编译 PHP
【发布时间】:2012-08-13 19:55:00
【问题描述】:

这是一个重新发布的帖子,之前的帖子已关闭,移至服务器故障并再次关闭。 我认为这篇帖子是一个有效的 stackoverflow 问题,因为我认为它是由某些问题引起的自动制作/编译/链接错误。这是一个编程问题,而不是服务器管理问题。

Cross compile 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

没有错误,一切正常。 接下来我进行make安装。

make install

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

/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

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

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

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

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

哦不~

# php shell.php 

Segmentation fault

我测试了另一个脚本:

#!/bin/php
<?php

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

同样的结果:

# php index.php 
helloSegmentation fault

我有 php.ini 吗?

# /usr/arm/www/bin/php --ini
Configuration File (php.ini) Path: /etc/
Loaded Configuration File:         /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
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 +++

文件 info.txt 存在,并且有读/写权限。

测试 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 +++

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

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 从 shell.php 给我这个 启动程序:/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 位于 /usr/arm/www/include/php/Zend/ 显然在交叉编译过程中出了点问题。我错过了什么?我没有找到任何配置标志来纠正这个问题,并且创建到所需位置的符号链接会删除 gdb 输出,但 php 仍然存在段错误。

感谢您的帮助!

更新:

# 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

更新2

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

php: can't resolve symbol '__libc_freeres'

更新3

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

(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;

这与 Sixeightzero 昨天在 cmets 中所写的非常相似。 我现在已经尝试过 PHP 版本 5.3.5、5.4.0、5.4.5 全部相同的错误。

更新4

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

【问题讨论】:

  • 对不起,伙计,我建议移动它,因为我认为它会为您提供更多答案,因为您之前的问题在这里没有任何意义。我的坏:(
  • 哇哇哇!!!咆哮!!距离赏金还有 6 小时,现在我还要再等 2 天。 >_
  • 你能在任何 arm 模拟器上重现吗?即 armware、qemu、ARMphethamine。如果是,您可以向我们提供有关如何复制主机和目标环境的详细说明,其中包含您正在执行的操作的详细说明,不遗余力,必须提供下载链接或准确的版本号。不幸的是,这不是解决如此多变量问题的合适渠道,充其量只是在黑暗中刺伤。很抱歉,您已经为此苦苦挣扎了这么久,我知道一定很沮丧,也许如果我们可以按照您的指示重现问题,我们实际上可能会有所收获。
  • 我不知道它是否有帮助,但是如果您想了解另一个嵌入式项目如何使用 uClibc 编译 PHP,请查看 freetz.org/browser/trunk/make/php。它在 MIPS 上,但一些配置和工具链问题可能相似。在 repo 中,您还可以找到 uClibc 的工具链 makefile 和补丁。
  • 只是一个提示:列出文件名的 gdb 错误和 valgrind 错误不会在这些位置查找文件;这些位置是您在编译时将它们放在原始主机上的位置。 php运行时不需要包含文件...

标签: php linux arm glibc uclibc


【解决方案1】:

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

【讨论】:

  • 我也想检查一下。但我只从我的 CPU 制造商那里得到二进制 blob。但如果它被禁用,我会感到惊讶。我们有一个 webkit 浏览器,Qt 和 DirectFB 使用相同的工具链。
猜你喜欢
  • 2021-02-10
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多