On 27/01/10 15:52, Martin Evans wrote:
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.
I am responsible for this change. It was part of a campaign to avoid warnings when compiling on 64-bit gcc platforms. All that is necessary to avoid the compiler warnings is that the format arguments match the casts (subject to integral promotion). I used (unsigned long long) in this case for maximum portability. I couldn't find any standard that said that (size_t) might not be wider than (unsigned long). If my change breaks PerlIO_vprintf, we must back off. Using (unsigned long) and %lu would work on all platforms I use. Using (unsigned int) and %u, would work in this case, but not for all uses of size_t. This is the only place where I used a %llu or %lld, so there is only one place to change. Martin, can you try changing the casts to (unsigned long) and the formats to %lu, and see if this fixes your problem.
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).
-- Charles Jardine - Computing Service, University of Cambridge [email protected] Tel: +44 1223 334506, Fax: +44 1223 334679
