Charles Jardine wrote:
> 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.

That is what I did in effect (nearly).

I took the casts of 0 to size_t out of the 2 calls in dbdimp.c and added
a cast to size_t on the real call to oracle in the macro. Then I change
the format in the PerlIO_printf to %lu and change the cast to (unsigned
long). This works for me and I guess it will work without warning for
you too.

This isn't exactly what John has in subversion at the moment.

>> 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).
> 

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to