Hi Folks.
Im seeing some nasty behaviour from DBD-Oracle with Oracle 9i that causes the
client to exit and core-dump with an Oracle internal error.
Below is a very simple program that illustrates the program. It connects to a
database (any Ora database will do, doesnt need any tables), then runs a
simple do query loop forever. OK so far, works fine. There is a conventional
exec/timeout around the do to catch network and server problems. If a timeout
occurs it disconnects from the database, but.... that causes an ORA internal
error, core dump and exit.
ORA reports something that looks like it complaining about a recursive
function call, even though the timed-out call was subsequently cancelled.
I suspect this is a Oracle bug, or maybe DBD-Oracle not driving Oracle quite
correctly. Can anyone confirm? Can anyone think of a workaround? Crashing in
the disconnect is causing lots of grief, and its not an option not to
disconnect. I dont think it happened with Ora 8.
Tried doing $sth->cancel in the timeout and elsewhere. Cancel runs OK but
doesnt make any difference to the internal error.
Relevant info:
DBI-1.20 or 1.30
DBD-Oracle-1.12
perl 5.6.1
Red Hat 7.3 Intel
Oracle 9i (9.0.1) for Linux.
Heres the program:
# Illustrates a problem with DBD Oracle 9i.
# A timeout in an execute, followed by a
# disconnect causes oracle internal error
# with DBI-1.20 or 1.30, DBD-Oracle-1.12, perl 5.6.1, Red Hat 7.3 Intel
# Run this for a few secs, then unplug from the network.
# the execute times out,tries
# to disconnect, get internal error
use DBI;
# Change to suit your system:
my $dbsource =
'dbi:Oracle:(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oscar.open.com.au)(PORT=1521))(CONNECT_DATA=(SID=osc)))';
my $dbuser = 'system';
my $dbauth = 'manager';
my $timeout = 2; # seconds
my $dbh = DBI->connect($dbsource, $dbuser, $dbauth) || die $DBI::errstr;
#DBI->trace(3);
while (1)
{
my $sth;
# Conventional timeout handling as recommended by DBI.pm
eval
{
# Makes no difference if you cancel in here or not. If run, it
# returns 1, indicating the Oracle cancel really got run.
local $SIG{ALRM} = sub {my $res;
$sth && ($res = $sth->cancel());
print "sigalrm $res\n";
die "timeout"};
alarm($timeout);
# The exact contents of the query make no difference
$sth = $dbh->prepare("begin dbms_output.enable(1000); end;");
$sth && $sth->execute();
};
alarm(0);
if ($@)
{
# There was a timeout:
print "about to disconnect\n";
# internal error and oracle core dump in here:
$dbh->disconnect();
exit;
}
print "done $sth\n";
sleep 1;
}
# end
If you run it for a few seconds, then disconnect the network between the
client and the server for a few seconds, you see this:
done DBI::st=HASH(0x8206a70)
done DBI::st=HASH(0x8206bb4)
done DBI::st=HASH(0x8206b18)
done DBI::st=HASH(0x8180974)
done DBI::st=HASH(0x8206aa0)
done DBI::st=HASH(0x8206a70)
sigalrm 1
about to disconnect
OCI-21500: internal error code, arguments: [ttcdrv-recursivecall], [], [], [],
[
], [], [], []
Errors in file :
OCI-21500: internal error code, arguments: [ttcdrv-recursivecall], [], [], [],
[
], [], [], []
----- Call Stack Trace -----
Cannot open /proc/15214/exe.
calling call entry argument values in hex
location type point (? means dubious value)
-------------------- -------- --------------------
----------------------------
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
Cannot find symbol in /proc/15214/exe.
402ECDEB CALL 401987A4 BFFFADE0 ? 402ECDAD ?
40825004 ? 40803AA0 ?
820DAC8 ? 82039A0 ?
4069463A CALLr 00000000 820D9EC ? 820D9EC ?
BFFFB268 ? 4000B230 ?
821B3C4 ? 821CFBC ?
4051584C CALL 40185104 405156B0 ? 4213030C ? 0 ?
407F2774 ?
403EF756 CALLr 00000000 821CFBC ? 4050746C ?
40825004 ? BFFFB888 ?
4027EE24 CALLr 00000000 821CFBC ? BFFFB300 ?
40825004 ? 0 ? 9 ? 4024F0C4
?
4027E786 CALL 4018E604 0 ? 0 ? 0 ? 0 ? 0 ?
4027E6D1 ?
40274AC5 CALL 40192D14 821ADF0 ? 821B4D4 ?
40274A90 ? 81F4958 ?
BFFFF408 ? 401D259F ?
401D259A CALL 40186A74 821AE5C ? 81F0E5C ? 81F3464
?
81F0DD8 ?
402633D4 CALL 40198C54 313 ? 821ADF0 ? 402633B0 ?
81F4620 ? BFFFF468 ?
400DBC9E ?
400DBC99 CALL 400D79D0 80FD208 ? 400EB2DC ?
817DC80 ? 8180938 ?
BFFFF4A8 ? 400D83D7 ?
400D83D2 CALL 400D75A0 80FD208 ? 1 ? 80FB7A0 ?
80FB7C0 ?
400CA455 CALLr 00000000 80 ? 8095B70 ? E ? E ?
BFFFF618 ? 80907E3 ?
Perl_pp_entersub CALLr 00000000 0 ? 4ED7FEA8 ? 8167418 ?
80803 ? A ? 80FD210 ?
Perl_runops_standar CALLr 00000000 BFFFF7A8 ? 805C04B ? 1 ? 1
?
BFFFF6F8 ? 1 ?
S_run_body()+193 CALLs 00000000
perl_run()+134 CALL S_run_body()+0 0 ? 1 ? 80FB3E0 ? 80FB9A0 ?
main()+108 CALL perl_run()+0 BFFFF808 ? 42017499 ? 2 ?
BFFFF834 ? BFFFF840 ?
.................
--
Mike McCauley [EMAIL PROTECTED]
Open System Consultants Pty. Ltd Unix, Perl, Motif, C++, WWW
24 Bateman St Hampton, VIC 3188 Australia http://www.open.com.au
Phone +61 3 9598-0985 Fax +61 3 9598-0955
Radiator: the most portable, flexible and configurable RADIUS server
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald,
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS,
TTLS etc on Unix, Windows, MacOS etc.