Perl – IO::Socket::INET segmentation fault

Já há uns meses que tinha este problema pendurado e consegui resolvê-lo hoje.
Tenho 18 máquinas com o Linux Slackware instalado e todas elas têm um script, que corre no arranque e no crontab, e atualiza uma base de dados com as versões dos vários pacotes de software que estão instalados, incluindo a versão do kernel. Assim, consigo saber se me escapou alguma máquina durante as sessões de atualização de software.

Em duas máquinas a atualização da BD não era feita porque o script produzia um segmentation fault ao usar o pacote IO::Socket::INET.

Hoje andei pela net@ a ver como fazer debug de um programa em Perl e descobri que tinha uma diretoria com ficheiros antigos de Perl, nessas duas máquinas, que estavam a causar o problema.

Com o debug, encontrei a origem do erro:

# perl -d bat/kern2.pl

Loading DB routines from perl5db.pl version 1.51
Editor support available.

Enter h or 'h h' for help, or 'man perldebug' for more help.

Signal SEGV at /usr/local/lib64/perl5/Socket.pm line 858.
        require Socket.pm called at /usr/lib64/perl5/IO/Socket.pm line 13
        IO::Socket::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
        require IO/Socket.pm called at /usr/lib64/perl5/IO/Socket/INET.pm line 11
        IO::Socket::INET::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
        require IO/Socket/INET.pm called at bat/kern2.pl line 3
        main::BEGIN() called at /usr/local/lib64/perl5/Socket.pm line 0
        eval {...} called at /usr/local/lib64/perl5/Socket.pm line 0
Aborted

O erro estava na linha 858 do ficheiro /usr/local/lib64/perl5/Socket.pm.

Decidi ver se havia diferenças, entre máquinas, nas diretorias de INCLUDE e corri o comando seguinte:

# perl -E'say for @INC'
/usr/local/lib64/perl5
/usr/local/share/perl5
/usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl
/usr/lib64/perl5
/usr/share/perl5

Mas as diretorias eram as mesmas tanto nas máquinas que corriam o script, como nas que não corriam.

Então, fui ver se o ficheiro onde o erro ocorria – /usr/local/lib64/perl5/Socket.pm – era diferente entre máquinas, se, por exemplo, a linha 858 era igual entre ficheiros. E descobri que o ficheiro /usr/local/lib64/perl5/Socket.pm só existia nas máquinas que não corriam o script. Nas outras máquinas, a diretoria /usr/local/lib64/perl5/ estava vazia. Apaguei o conteúdo dessa diretoria nas máquinas-problema, e o problema desapareceu.

Há muitos anos atrás, tive que instalar o pacote IO::Socket::INET e outros, nessas máquinas, para poder comunicar pela rede, mas agora esses pacotes fazem parte do núcleo do Perl. Os pacotes antigos estavam a sobrepor-se aos do núcleo e estavam a gerar o erro.