develooper Front page | perl.dbd.pg | Postings from April 2008

segfault with pg_getcopydata in DBD::Pg 2.6.1

Thread Next
From:
David Harris
Date:
April 30, 2008 08:48
Subject:
segfault with pg_getcopydata in DBD::Pg 2.6.1
Hi,

I've tracked down a segfault in DBD::Pg 2.6.1, and I've got a patch.

Version: DBD-Pg-2.6.1 (also had problem with DBD-Pg-2.1.3)
Other versions: Perl-5.8.8, DBI-1.602
System: CentOS release 5 (Final), Linux centos5.drh.net 2.6.18-8.el5

With this perl code:

 >>>
         $dbh->do(q[ COPY ( SELECT * FROM table_with_no_rows ) TO  
STDOUT WITH DELIMITER ',' ]);
         my $data;
         my $last = 0;
         while ( ! $last )
         {
             $last = $dbh->pg_getcopydata($data) == -1;

             # do stuff.
         }
<<<

I got a segfault from pg_getcopydata when the query returned no rows.  
It worked fine when the query did return rows.

Here's the info from gdb on the segfault:

 >>>
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208076608 (LWP 24340)]
0x00f8bb56 in pg_db_getcopydata (dbh=0x8ca9534, dataline=0x8de7320,  
async=0) at dbdimp.c:3672
3672                    SvCUR_set(dataline, 0);
(gdb) p dataline
$1 = (SV *) 0x8de7320
(gdb) p *dataline
$2 = {sv_any = 0x0, sv_refcnt = 1, sv_flags = 1280}
<<<

Here's the patch:

 >>>
--- DBD-Pg-2.6.1.orig/dbdimp.c  2008-04-22 12:56:32.000000000 -0500
+++ DBD-Pg-2.6.1/dbdimp.c       2008-04-30 05:03:22.000000000 -0500
@@ -3664,7 +3664,7 @@
         else if (-1 == copystatus) {
                 PGresult * result;
                 ExecStatusType status;
-               SvCUR_set(dataline, 0);
+               sv_setpv(dataline, "");
                 imp_dbh->copystate=0;
                 TRACE_PQGETRESULT;
                 result = PQgetResult(imp_dbh->conn);
<<<

If pg_getcopydata is called and the buffer variable is a freshly  
defined variable and copystatus == -1, then the SvCUR_set call  
segfaults because there is no string component allocated for this SV,  
so the length of the string component can't be set to zero. I changed  
to using the sv_setpv() call to just set it to a zero length string.  
This fixes the segfault in my case.

I'm not a perl internals expert, so you might want to double check this.

Thanks!

David



Thread Next


Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About