Re: 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]>
Charles Jardine wrote:
> On 27/01/10 17:38, Martin Evans wrote:
>> 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:
> 
> [snip]
> 
>>>> 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.
> 
> John seems to have corrected my over-zealous cast, and produced
> a version which complies without warning and works on both 32-
> and 64-bit platforms. Thank you John.
> 
> I prefer his version, with the cast to site_t left where it was,
> rather than imported into the macro.

I'm not that comfortable with the cast to size_t in dbdimp.c because
then it is later cast back to unsigned long and I'd guess on platforms
where size_t is an unsigned long long the compiler might whine about that.

The best fix would be if there was a reliable format for size_t but I
don't know of one.

However, I don't think we need to get this out of proportion after all
it is only two calls and in both cases the size_t is 0 anyway as the
requested attributes are integers and not strings.

> If the current SVN version works for Martin, I suggest that no
> more needs to be done.

It does work.


> I an sorry to have caused this bother.
> 

Didn't cost me much bother and was done for all the right reasons.

I am considerably more bothered about this serious problem:

oci8.c
======
/*line 1897 */
	if (DBIS->debug >= 3 || dbd_verbose >= 3 || oci_warn){
		char buf[10];
		sprintf(buf,"bytes");

		if (ftype == ORA_CLOB)
           sprintf(buf,"characters");

		PerlIO_printf(DBILOGFP,
		"		OCILobRead %s %s: csform %d (%s), LOBlen %lu(%s), LongReadLen
%lu(%s), BufLen %lu(%s), Got %lu(%s)\n",
				name, oci_status_name(status), csform,oci_csform_name(csform),
ul_t(loblen),buf ,
				ul_t(imp_sth->long_readlen),buf, ul_t(buflen),buf, ul_t(amtp),buf);

    }

That sprintf will always overflow buf as buf is 10 chrs long and does
not have room for the trailing NUL.

The attached patch fixes above and a few other ones I saw.

I suggest we try very hard to get someone with a 64bit platform to try
the next RC.

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
1.dif (video/dv, 2 KB) - not displayed
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.