DBD::mysql 4.006 SEGVing on Solaris sparc

[email protected] Tue, 26 Feb 2008 13:08:24 +0000 (GMT)
Newsgroups gmane.comp.db.mysql.perl
Message-ID <[email protected]>
We're having a problem with DBD::mysql SEGVing on Solaris sparc - both
with Solaris 9 and Solaris 10.  Solaris x86 is working OK.

With a tiny test script:

"""
use strict;
use warnings;

use DBI;
use DBD::mysql;

my $server = "something";
my $user   = "root";
my $pass   = "foobar";

my $dbh = DBI->connect( "DBI:mysql:mysql:$server", $user, $pass,
             { AutoCommit => 1, PrintError => 0 } )
           or die "Cannot connect - " . DBI->errstr;

print "Have a DB handle: $dbh\n";
"""


we get "Segmentation Fault (core dumped)" rather than the expected
"Cannot connect - Unknown MySQL server host 'something' (1)"

This is with our own builds of Perl 5.8.8, DBI 1.602, and DBD-mysql 4.006
Perl is built with threading enabled.

A backtrace reveals:

ffbfec58 mysql.so`XS_DBD__mysql__db__login+0x228(0, 1af6dc, 4, 4, fffeee90, 0)
ffbfecc0 libperl.so`Perl_pp_entersub+0x888(23778, 1418d0, 0, 0, 1b06c4, 1c0d40)
ffbfed78 libperl.so`Perl_runops_debug+0x464(23778, ffbfef64, ff2b7884, ff38a950,
ff393838, 
40000)
ffbfede0 libperl.so`Perl_call_sv+0x314(23778, d5748, 0, 0, fef36f90, 1b8768)
ffbfef98 DBI.so`XS_DBI_dispatch+0x24b4(23778, 1ecf08, 5, 1e60e0, 0, 0)
ffbff4e0 libperl.so`Perl_pp_entersub+0x888(23778, f1a80, 0, 0, 80000, 19c07c)
ffbff598 libperl.so`Perl_runops_debug+0x464(23778, 1, ff2b7884, ff38a950,
ff393838, 40000)
ffbff600 libperl.so`S_run_body+0x1f8(39600, 244d8, 0, 1, 2397c, 23778)
ffbff660 libperl.so`perl_run+0x2a8(23778, ffbff6e0, 2, 23778, 0, 2397c)
ffbff760 main+0xf0(2, ffbff824, 11800, 14, 0, 233d4)
ffbff7c0 _start+0x108(0, 0, 0, 0, 0, 0)

and looking at the code around mysql.so`XS_DBD__mysql__db__login+0x228
we see:

/* 0x0218         88 */         call    Perl_get_sv     ! params =  %o0 %o1 %o2
! Result =  %o0
/* 0x021c            */         ld      [%l0+%i4],%o1,%gdop(.L114)
/* 0x0220            */         ld      [%o0],%g5
/* 0x0224            */         ld      [%g5+16],%i5
/* 0x0228            */         ld      [%i5+24],%g4                  <=====
/* 0x022c            */         jmpl    %g4,%o7
/* 0x0230            */         or      %g0,%l4,%o0

Note that on the Sparc processor the code at 0x021c is actually
executed BEFORE the call.

We're calling Perl_get_sv() with an argument of 'DBI::_dbistate'
which returns a structure in register o0.
We then load from o0 with an offset of 16 into register i5, and
this is a null pointer. The load at 0x0228 is then attempting to read
from a small offset from 0x00000000 - hence the segment violation.

Well, we can debug this far but now we're stuck.

If we build Perl 5.8.8 without threading, then the problem is not
present - but this looks like a workaround rather than a fix.

Seems like the lookup of 'DBI::_dbistate' fails on a threaded
Perl, and the code isn't expecting that.

Any ideas please ?

-- 
Andrew Benham               Demon@Thus          [email protected]
Finchley, London N3 2QQ, U.K.   Tel: 020 8495 6343  Fax: 020 8495 6037

-- 
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe:    http://lists.mysql.com/[email protected]