[freetds] MS-SQL ntext fields?

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Fri Jan 12 05:50:09 EST 2007


> 
> I finally had a chance to run through these instructions on using gdb.
> I have more than one script failing, so I'm pasting in backtrace info
> for two examples. After running the backtrace, I followed the
> instructions at http://bugs.php.net/bugs-generating-backtrace.php to
> determine which function was responsible for the last execute() call.
> 
> #############################################
> #Here are the results of the first backtrace:
> #############################################
> 
> (gdb) r test.php
> 	<a bunch of HTML code comes out here, and then...>
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 182894185888 (LWP 21325)]
> 0x0000003f6fd71f07 in memcpy () from /lib64/tls/libc.so.6
> (gdb) bt
> #0  0x0000003f6fd71f07 in memcpy () from /lib64/tls/libc.so.6
> #1  0x00000000004f8030 in _estrndup ()
> #2  0x0000002a98a82b2b in zif_odbc_result () from
> /usr/lib64/php4/odbc.so

so SIGSEGV occurred in memcpy called by odbc_result 
http://cvs.php.net/viewvc.cgi/php-src/ext/odbc/
specifically for 4.3.9
http://cvs.php.net/viewvc.cgi/php-src/ext/odbc/php_odbc.c?revision=1.143
.2.17&view=markup
(search "PHP_FUNCTION(odbc_result)")
estrndup should be called by PHPWRITE or RETURN_STRINGL so it would be
better if you could add some debugging line.
Are you sure the problem is ntext??

Add these line before

---- start ----
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

static void
tds_log(const char *fmt, ...)
{
        static FILE* log = NULL;
        va_list ap;

        if (!log)
                log = fopen("/tmp/ftdsphp.log", "a");
        if (!log)
                return;

        va_start(ap, fmt);
        vfprintf(log, fmt, ap);
        va_end(ap);
        fflush(log);
}

---- end ----

replace

---- start ----
	/* Don't duplicate result, saves one emalloc.
	   For SQL_SUCCESS, the length is in vallen.
	 */
	RETURN_STRINGL(field, (rc == SQL_SUCCESS_WITH_INFO) ? fieldsize
:
				   result->values[field_ind].vallen, 0);
---- end ----

with

---- start ----
	/* Don't duplicate result, saves one emalloc.
	   For SQL_SUCCESS, the length is in vallen.
	 */
	tds_log("string 1 rc %d fieldsize %d vallen %d\n", (int) rc, 
		  (int) fieldsize, (int)
result->values[field_ind].vallen);
	RETURN_STRINGL(field, (rc == SQL_SUCCESS_WITH_INFO) ? fieldsize
:
				   result->values[field_ind].vallen, 0);
---- end ----

replace 

---- start ----
	} else {
		RETURN_STRINGL(result->values[field_ind].value,
result->values[field_ind].vallen, 1);
	}
---- end ----

with

---- start ----
	} else {
		tds_log("string 2 vallen %d\n", (int)
result->values[field_ind].vallen);
		RETURN_STRINGL(result->values[field_ind].value,
result->values[field_ind].vallen, 1);
	}
---- end ----

replace 

---- start ----
	/* chop the trailing \0 by outputing only 4095 bytes */
	PHPWRITE(field,(rc == SQL_SUCCESS_WITH_INFO) ? 4095 :
	
result->values[field_ind].vallen);
---- end ----

with

---- start ----
	/* chop the trailing \0 by outputing only 4095 bytes */
	tds_log("string 3 rc %d vallen %d\n", (int) rc, 
		  (int) result->values[field_ind].vallen);
	PHPWRITE(field,(rc == SQL_SUCCESS_WITH_INFO) ? 4095 :
	
result->values[field_ind].vallen);
---- end ----

obviosly you have to recompile PHP and reinstall it.

after the core script shold create a /tmp/ftdsphp.log  with some useful
informations.

Another way is to enable odbc trace adding 

[ODBC]
Trace           = Yes
TraceFile       = /tmp/sql.log
ForceTrace      = No
Pooling         = No

to /etc/odbcinst.ini (or whatever patgh). Remember to disable it in
production !!!

> #3  0x0000000000519ed8 in execute ()
> #4  0x00000000005082ad in zend_execute_scripts ()
> #5  0x00000000004dcc0a in php_execute_script ()
> #6  0x000000000052198a in main ()
> (gdb) frame 3
> #3  0x0000000000519ed8 in execute ()
> (gdb) print (char
> *)(executor_globals.function_state_ptr->function)->common.func
> tion_name
> Attempt to extract a component of a value that is not a structure.
> (gdb)
> 
> ############################################
> #And here are the results of the second backtrace:
> ############################################
> 
> (gdb) r itin.php
> 	<a bunch of HTML code comes out here, and then...>
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 182894185888 (LWP 21364)]
> 0x0000003f6fd71f07 in memcpy () from /lib64/tls/libc.so.6
> (gdb) bt
> #0  0x0000003f6fd71f07 in memcpy () from /lib64/tls/libc.so.6
> #1  0x00000000004f8030 in _estrndup ()
> #2  0x0000002a98a82b2b in zif_odbc_result () from
> /usr/lib64/php4/odbc.so
> #3  0x0000000000519ed8 in execute ()
> #4  0x00000000005082ad in zend_execute_scripts ()
> #5  0x00000000004dcc0a in php_execute_script ()
> #6  0x000000000052198a in main ()
> (gdb) frame 3
> #3  0x0000000000519ed8 in execute ()
> (gdb) print (char
> *)(executor_globals.function_state_ptr->function)->common.func
> tion_name
> Attempt to extract a component of a value that is not a structure.
> (gdb)
> 
> Apparently, it's the same problem affecting both scripts.
> Unfortunately, I'm enough of a newbie here that I still don't 
> understand
> whether this is a PHP or FreeTDS bug.  Any insight?
> 

bye
  freddy77



More information about the FreeTDS mailing list