Ошибка потока при попытке инициализации объекта deflate в Compress :: Raw :: Zlib :: _ deflateInit - PullRequest
2 голосов
/ 19 марта 2019

Я столкнулся со странной проблемой в приложении, использующем PDF::API2 модуль Perl в системе CentOS 7 (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-отладчик, чтобы найти какие-либо различия, и оказался в подпрограмме deflateInit Zlib (/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. Здесь я обнаружил, что объект не создается из-за «потоковой ошибки» $status, когда я использую высокоуровневые вызовы приложения. Хотя передаваемые аргументы (уровень, метод и т. Д.) Абсолютно одинаковы в обоих случаях. Я не мог больше использовать Perl-отладчик внутри Compress::Raw::Zlib::_deflateInit, поэтому для меня это черный ящик.

Я твердо верю, что приложение меняет некоторые аспекты поведения Perl, но я не смог их найти. Я обнаружил, что «ошибка потока» возвращается, когда первый аргумент равен NULL (в контексте C) или передано недопустимое значение для уровня. Я уверен, что уровень правильный и фактически одинаковый в обоих случаях (успешный и неудачный). Затем я подумал о первом аргументе, который равен нулю (0).

Возможно ли, что приложение изменяет что-то в Perl, чтобы оно по-разному обрабатывало переданный 0 (нулевой) аргумент? Как я могу отладить проблему дальше внутри Compress::Raw::Zlib::_deflateInit?

ОБНОВЛЕНИЕ:

Я продолжил отладку кода C, вызываемого Compress::Raw::Zlib::_deflateInit с использованием gdb, и обнаружил, что /usr/lib64/perl5/vendor_perl/auto/Compress/Raw/Zlib/Zlib.so вызывает deflateReset функцию из библиотеки /usr/lib64/mysql/libmysqlclient.so.18.1.0 вместо /usr/lib64/libz.so.1.2.7.

Теперь понятно, почему мой тестовый код не может вызвать ошибку, он не использует функции MySQL. Однако код в приложении использует много вызовов MySQL перед PDF::API2 функциями.

Я использую сервер сообщества 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? Что я могу сделать как системный администратор для решения проблемы? Спасибо.

1 Ответ

1 голос
/ 22 марта 2019

Что ж, после нескольких дней отладки стало очевидно, что основная проблема заключается в библиотеке libmysqlclient.so, предоставляемой сервером сообщества MySQL. Библиотека статически связана с zlib и экспортирует все символы zlib по всему миру. В результате любой двоичный файл с одновременно загруженными zlib.so и libmysqlclient.so будет иметь возможность вызвать функцию zlib из libmysqlclient.so, а не из zlib.so.

Соответствующий отчет об ошибке был открыт и одобрен (теперь, к сожалению, как запрос функции).

Во время обходного пути я переключился на MariaDB 10.2 из Red Hat Software Collections.

...