在尝试初始化Compress :: Raw :: Zlib :: _ deflateInit中的deflate对象时出现流错误

问题描述 投票:2回答:1

在CentOS 7系统上使用PDF::API2 Perl模块的应用程序中遇到了一个奇怪的问题(perl-5.16)。每当它试图使用openpage()函数时它会得到:

Can't call method "inflate" on an undefined value at /usr/share/perl5/vendor_perl/PDF/API2/Basic/PDF/Filter/FlateDecode.pm line 49.

我尝试使用对PDF::API2的简单调用重现该问题,但无法触发错误:

#!/usr/bin/perl

use strict;
use warnings;
use PDF::API2;

print "Content-Type: application/pdf\n\n";

my $pdf = PDF::API2->open('/tmp/test.pdf');

my $page = $pdf->openpage(1);

print $pdf->stringify();

接下来,我在我的简单脚本中使用了应用程序自己的高级调用,并且我能够触发该问题。好吧,我决定使用Perl调试器找到任何差异,最后在Zlib的deflateInit子程序(/usr/share/perl5/Compress/Zlib.pm)中,特别是在Compress::Raw::Zlib::_deflateInit中:

my $obj ;

my $status = 0 ;
($obj, $status) = 
  Compress::Raw::Zlib::_deflateInit(0,
            $got->getValue('level'), 
            $got->getValue('method'), 
            $got->getValue('windowbits'), 
            $got->getValue('memlevel'), 
            $got->getValue('strategy'), 
            $got->getValue('bufsize'),
            $got->getValue('dictionary')) ;

my $x = ($status == Z_OK() ? bless $obj, "Zlib::OldDeflate"  : undef) ;

据我了解,这是对zlib C库的低级调用。在这里,我发现当我使用应用程序的高级调用时,由于'stream error'$status而没有创建对象。虽然,传递的参数(级别,方法等)在两种情况下都是完全相同的。我无法在Compress::Raw::Zlib::_deflateInit中进一步使用Perl调试器,所以现在它对我来说是一个黑盒子。

我坚信应用程序会改变Perl行为的某些方面,但我找不到任何方面。我发现当第一个参数是NULL(在C上下文中)或者传递了无效的level值时,会返回'stream error'。我确信水平是正确的,并且在两种情况下都是相同的(成功和失败)。接下来,我想到了第一个参数,即零(0)。

应用程序是否有可能在Perl中更改某些内容,因此它会以不同方式处理传递的0(零)参数?如何在Compress::Raw::Zlib::_deflateInit中进一步调试问题?

更新:

我继续使用Compress::Raw::Zlib::_deflateInit调试gdb调用的C代码,发现/usr/lib64/perl5/vendor_perl/auto/Compress/Raw/Zlib/Zlib.sodeflateReset库而不是/usr/lib64/mysql/libmysqlclient.so.18.1.0调用/usr/lib64/libz.so.1.2.7函数。

现在很明显为什么我的测试代码无法触发错误,它不使用MySQL函数。但是,应用程序中的代码在PDF::API2函数之前使用了大量的MySQL调用。

我使用从官方存储库安装的MySQL社区服务器:

$ rpm -qa | grep mysql
mysql-community-libs-5.6.43-2.el7.x86_64
mysql-community-server-5.6.43-2.el7.x86_64
mysql80-community-release-el7-2.noarch
mysql-community-common-5.6.43-2.el7.x86_64
mysql-community-client-5.6.43-2.el7.x86_64

现在我有了新的问题。 MySQL社区错误地将Zlib代码捆绑到libmysqlclient.so吗?作为系统管理员,我可以做些什么来解决问题?谢谢。

mysql perl zlib
1个回答
1
投票

好吧,经过几天的调试后,很明显核心问题出现在libmysqlclient.so库中,由MySQL社区服务器提供。该库与zlib静态链接,并在全球范围内导出所有zlib符号。因此,任何同时加载zlib.solibmysqlclient.so的二进制文件都有机会从zlib调用libmysqlclient.so函数,而不是从zlib.so调用。

相关的bug report现已开放并获得批准(不幸的是,作为功能要求)。

当我解决方法时,我从Red Hat Software Collections切换到MariaDB 10.2。

© www.soinside.com 2019 - 2024. All rights reserved.