Bug in tracing in DBD::Oracle

Martin Evans <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.sybase.devel
Organization Easysoft Limited
Message-ID <[email protected]>
Hi,

I was asked to enable ora_verbose and send a trace a few days ago.

I'm getting a segfault with DBD::Oracle when ora_verbose or dbd_verbose
is set to 15 in the connect method call. The stack trace is:

(gdb) bt
#0  0x080be45c in Perl_sv_vcatpvfn ()
#1  0x080ccd6d in Perl_vnewSVpvf ()
#2  0x0811cb54 in PerlIO_vprintf ()
#3  0x0811cbdf in PerlIO_printf ()
#4  0x007e961c in ora_db_login6 (dbh=0x830f6a0, imp_dbh=0x834b0b0,
dbname=<value optimised out>, uid=0x81aedf8 "bet",
    pwd=0x81aee08 "b3t", attr=0x830ee20) at dbdimp.c:546
#5  0x007dd0e0 in XS_DBD__Oracle__db__login (my_perl=0x8188008,
cv=0x8344b88) at ./Oracle.xsi:100
#6  0x080b12c0 in Perl_pp_entersub ()
#7  0x080af688 in Perl_runops_standard ()
#8  0x080acf4b in Perl_call_sv ()
#9  0x00575f0a in XS_DBI_dispatch (my_perl=0x8188008, cv=0x82bfa88) at
DBI.xs:3442
#10 0x080b12c0 in Perl_pp_entersub ()
#11 0x080af688 in Perl_runops_standard ()
#12 0x080adbb2 in perl_run ()
#13 0x08063ffd in main ()

and that refers to the following line in dbdimp.c:

OCINlsEnvironmentVariableGet_log_stat( &ncharsetid,(size_t)  0,
OCI_NLS_NCHARSET_ID, 0, &rsize ,status );

Oracle defines the second argument as size_t so I guess that cast of 0
to size_t is ok but ocitrace.h then goes on to cast it again to
(unsigned long long) and the format argument has been changed to %llu.
Although these match it segfaults.

This segfaults on my Linux machine described with the Perl -V output
below. I cannot believe the size of the first argument passed to
OCINlsEnvironmentVariableGet is every going to need a size_t and in any
case it has a max size of OCI_NLS_MAXBUFSZ (100 in Instant Client 11.1
for Linux X86).

I imagine this got changed by someone with a 64 bit system where size_t
was possibly unsigned long long and that generated a warning on the call
to PerlIO_printf.

I changed my version to remove the cast to size_t from the call to
OCINlsEnvironmentVariableGet and put this cast in the real call in the
macro instead. I then changed the format for the size in the
PerlIO_printf to %lu and cast to (unsigned long)

I believe this should work for 64bit machines too since
OCINlsEnvironmentVariableGet is only currently used for integer types
and not string types so all the calls pass 0 anyway. Perhaps someone who
has a 64bit machine could check this out.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.6.24-23-server,
archname=i486-linux-gnu-thread-multi
    uname='linux vernadsky 2.6.24-23-server #1 smp wed apr 1 22:22:14
utc 2009 i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr
-Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5
-Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl/5.10.0
-Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
-Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio
-Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib
-Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN
-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing
-pipe -I/usr/local/include'
    ccversion='', gccversion='4.4.1', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib /usr/lib64
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.10.1.so, so=so, useshrplib=true,
libperl=libperl.so.5.10.0
    gnulibc_version='2.10.1'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'


Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_ITHREADS
                        USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
  Built under linux
  Compiled at Oct  1 2009 22:19:26
  %ENV:
    PERL5LIB="/home/martin/xxx/tools/modules/XXX/lib:/home/martin/xxx/cgi"
  @INC:
    /home/martin/xxx/tools/modules/XXX/lib
    /home/martin/xxx/cgi
    /etc/perl
    /usr/local/lib/perl/5.10.0
    /usr/local/share/perl/5.10.0
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.10
    /usr/share/perl/5.10
    /usr/local/lib/site_perl
    .

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.