PHP扩展使用libpng出core

本文针对由fwrite标准库函数引发的core dump问题提供了一种解决方案。通过分析qrencode.c中libpng的使用方式及libpng-1.2.8源码,引入了一个自定义宏CUSTOMIZED_CHECK_PNG_PTR来检查png指针的有效性,以此避免了fwrite出现段错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

coredump是由php-cgi产生的,不好调式。一是无法对php-cgi充分请求,以复现core,二是我在lirui04的机器上,gdb run给php-cgi传参数时,提示--fpm这个参数有问题。


根据coredump的调用栈信息,core最终出在fwrite标准库函数,根据理论和经验,可能导致fwrite出core的,依次是其第4个参数和第1个参数。


根据qrencode.c中对libpng的使用,结合libpng-1.2.8的源码,得出以下临时的solution,理论上可以解决这个具体的问题:


/******************************
 * customized for libpng-1.2.8
 * to avoid fwrite's segmentation fault
 * @reference:
 *   pngwutil.c:133
 *   PngFile.c:419
 *   pngwio.c:52
 *   png.h:1073 1054 1130
 * XXX: this macro's augument was refered more than once
 ******************************/
#define CUSTOMIZED_CHECK_PNG_PTR(png_ptr) \
do { \
if (!(png_ptr) \
|| (int)((png_ptr)->sig_bytes) > 7 \
|| (int)((png_ptr)->sig_bytes) < 0 \
|| !(png_ptr)->io_ptr) { \
/* return from PHP method or throw an exception, and release related resources if any */ \
} \
} while (0)


在qrencode.c的546行之前,定义上面的宏,并在545行之后、546行之前,调用此宏,CUSTOMIZED_CHECK_PNG_PTR(png_ptr);。
### PHP 7.2 的下载与安装指南 #### 准备工作 在开始之前,需确认操作系统环境以及所需依赖项已准备就绪。对于 Linux 和 Windows 平台,具体操作略有不同。 --- #### 在 Debian 或 Ubuntu 上安装 PHP 7.2 ##### 安装必要的工具和依赖项 运行以下命令来更新包管理器并安装构建所需的开发工具链: ```bash sudo apt update && sudo apt upgrade -y sudo apt install build-essential libxml2-dev libssl-dev \ libcurl4-openssl-dev libjpeg-dev libpng-dev libfreetype6-dev \ libmysqlclient-dev libmcrypt-dev git-core checkinstall autoconf \ automake pkg-config re2c bison libc-client2007e-dev libkrb5-dev ``` ##### 获取 PHP 源码 通过 Git 克隆官方 `php-src` 版本库,并切换至对应标签: ```bash git clone https://github.com/php/php-src.git cd php-src git checkout tags/php-7.2.34 # 使用最新稳定版的 PHP 7.2 标签[^1] ``` ##### 配置编译选项 执行配置脚本来指定目标功能模块和支持的扩展: ```bash ./buildconf --force ./configure --prefix=/usr/local/php72 \ --with-config-file-path=/etc/php/7.2/cli \ --enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \ --with-curl --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir \ --enable-mbstring --enable-zip --enable-bcmath --enable-calendar --enable-exif \ --enable-soap --enable-ftp --enable-opcache --with-pear --with-gettext \ --with-kerberos --with-imap --with-imap-ssl --with-pspell --with-enchant \ --with-tidy --with-xsl --with-zlib --with-bz2 --with-recode --with-iconv \ --disable-debug --disable-rpath ``` ##### 编译与安装 完成上述配置后,启动编译过程并将结果部署到系统目录中: ```bash make -j$(nproc) sudo make install ``` ##### 创建配置文件 创建默认的 PHP 配置文件模板: ```bash cp php.ini-production /etc/php/7.2/cli/php.ini sed -i 's/^;date.timezone =$/date.timezone = Asia\/Shanghai/' /etc/php/7.2/cli/php.ini ``` 测试安装是否成功: ```bash /usr/local/php72/bin/php -v ``` --- #### 在 Windows 上安装 PHP 7.2 ##### 下载二进制分发包 访问官方网站或镜像站点获取预编译好的 ZIP 文件: [PHP Downloads](https://windows.php.net/download/) 选择适用于当前系统的线程安全 (TS) 或非线程安全 (NTS) 版本。 解压压缩包到本地路径(如 `C:\php72\`),确保其结构保持原样。 ##### 设置环境变量 将 PHP 可执行程序所在位置加入全局 PATH 中以便调用: ```cmd setx PATH "%PATH%;C:\php72" ``` 重启终端窗口使更改生效。 ##### 启用 SQL Server 扩展支持 如果计划连接 Microsoft 数据库,则需要额外加载驱动组件。编辑 `php.ini` 添加如下指令[^2]: ```ini extension=sqlsrv.dll extension=pdo_sqlsrv.dll ``` 同时复制相关 DLL 至扩展目录下并与 VC++ Redistributable 匹配版本一致。 验证设置无误的方法之一是运行简单的 PHP 脚本打印信息: ```php <?php phpinfo(); ?> ``` --- #### 常见问题排查 当遇到错误提示时可参照文档进一步分析原因;另外注意检查权限分配情况以免影响正常流程运转。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值