Bug 174373

Summary: Perl program crashes on end if prepared statements are used
Product: [Fedora] Fedora Reporter: Peter Bieringer <pb>
Component: perl-DBD-PgAssignee: Jason Vas Dias <jvdias>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 4CC: perl-devel
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-02-20 23:37:24 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Peter Bieringer 2005-11-28 16:58:28 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.12) Gecko/20050919 Firefox/1.0.7

Description of problem:
A specific (not so big) Perl program crashes crashes on a special scenario

Version-Release number of selected component (if applicable):
perl-DBD-Pg-1.41-2  perl-5.8.6-16.fc4 postgresql-8.0.4-2.FC4.1

How reproducible:
Always

Steps to Reproduce:
1. create a Perl program
2. use DBD::Pg
3. connect to database
4. create some prepare statements like
 my $statement = "SELECT * FROM table WHERE number = ?";
 my $sth_test_select = $dbh->prepare($statement) || die $DBI::errstr;
5. use statements
6. disconnect from database
7. exit
  

Actual Results:  Crash:

rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0
send(3, "Q\0\0\0\rrollback\0", 14, 0)   = 14
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
poll([{fd=3, events=POLLIN|POLLERR, revents=POLLIN}], 1, -1) = 1
recv(3, "C\0\0\0\rROLLBACK\0Z\0\0\0\5I", 16384, 0) = 20
rt_sigprocmask(SIG_BLOCK, [PIPE], [], 8) = 0
send(3, "X\0\0\0\4", 5, 0)              = 5
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(3)                                = 0
stat64("/usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0x94ce0c8) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2528, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d6c000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2528
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7d6c000, 4096)                = 0
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.6/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.5/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.4/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/5.8.3/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/site_perl/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.6/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.5/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.4/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/5.8.3/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/vendor_perl/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.6/auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("./auto/DBI/DESTROY.al", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
exit_group(0)                           = ?


Expected Results:  If prepare variable would be undef'ed before exit (before oder after disconnect), the crash would no longer occur.

Additional info:

Comment 1 Peter Bieringer 2005-11-28 17:00:22 UTC
I forgot to mentionend, that if I connect to database with "pg_server_prepare =>
0", also no crash occurs. So problem mut be related to the new feature of
PostgreSQL 7.4/8.0.

Comment 2 Jason Vas Dias 2005-12-07 21:48:15 UTC
Hi - sorry for the delay in processing this bug. 

I've tried to reproduce the problem, with perl-5.8.6-16, perl-DBD-Pg-1.41-2
and postgresql-8.0.4-2.FC4.1 installed, using this example program:

---
#!/usr/bin/perl
use DBI;
use DBD::Pg;

$dbh = DBI->connect('dbi:Pg:dbname=test;', 'root', '',
		    { pg_server_prepare => 1 }
		   ) || die("can't connect: $! $?");

my $stmt = $dbh->prepare("SELECT * FROM t WHERE c = ?");

$stmt->{pg_server_prepare}=1;

my $rv = $stmt->execute("A");

while (my $data = $stmt->fetchrow_hashref) 
{
    print join(" ",values %{$data}),"\n";
};

$stmt->finish();

$dbh->disconnect();

print "STILL HERE\n";
---

In all cases, this program completes normally and prints out "STILL HERE" .

I've tried:
 o running the program on FC5 with perl-5.8.7-0.8.fc5, perl-DBD-Pg-1.43-2,
   postgresql-8.1.0-4 
 o running the program with or without { pg_server_prepare => 1 } in the 
   connect
 o running the program with or without $stmt->{pg_server_prepare}=1;
 o running the program with or without $stmt->finish ;
 o using 'undef $stmt' instead of $stmt->finish ;
 o connecting to a remote postgresql-8.1.0-4 server instead of the local server

If you can still reproduce this problem, please send me an example program such
as the above (and possibly an example database dump) which exhibits the problem
- otherwise I'll have to close as NOTABUG - thanks .

Comment 3 Jason Vas Dias 2005-12-20 21:13:35 UTC
I still cannot reproduce this problem. 
As no further information was forthcoming, closing as NOTABUG .

Comment 4 Peter Bieringer 2005-12-22 10:10:36 UTC
Sorry, was busy, but I've tracked it more down by reducing my crashing program
to the essential code and can now reproduce this using your example.

-my $stmt = $dbh->prepare("SELECT * FROM t WHERE c = ?");
+my $stmt;
+
+sub prepare_statements() {
+       $stmt = $dbh->prepare("SELECT * FROM t WHERE c = ?");
+};

 $stmt->{pg_server_prepare}=1;

+prepare_statements();
+


So the reason is that the statements are prepared in a subroutine and not
undefined before program ends.

Comment 5 Peter Bieringer 2005-12-22 10:12:02 UTC
Forgot to mention that upper modifications are required to cause the crash...

Comment 6 Jason Vas Dias 2006-02-20 23:37:24 UTC
I still really cannot reproduce this bug, using the following program,
modified as you suggested:
---
#!/usr/bin/perl
use DBI;
use DBD::Pg;
($host,$db,$user)=($ARGV[1],$ARGV[2]);
$dbh = DBI->connect('dbi:Pg:dbname=$db;host=$host;', $user, '',
                    { pg_server_prepare => 1 }
                   ) || die("can't connect: $! $?");
my $stmt;
sub prepare_stmt
{
    $stmt = $dbh->prepare("SELECT * FROM t WHERE c = ?");
}

$stmt->{pg_server_prepare}=1;

prepare_stmt();

my $rv = $stmt->execute("A");

while (my $data = $stmt->fetchrow_hashref)
{
    print join(" ",values %{$data}),"\n";
};
---

NOTE: The '$stmt->{pg_server_prepare}=1;' statement has no effect.

The program above runs without errors and exits with 0 exit status.

Concluding that this is 'NOTABUG'. If you can still reproduce this problem,
please append the complete perl program that causes the bug, and a pg_dump(1)
of the database the program connects to when the problem occurs, and re-open
this bug - thanks.