ID: 39756
Updated by: [EMAIL PROTECTED]
Reported By: tobias dot barth at web-arts dot com
-Status: Assigned
+Status: Open
Bug Type: ODBC related
Operating System: SuSE Linux 10.1
PHP Version: 6.0 (snapshot 2007-04-28 10:30)
Assigned To: kalowsky
Previous Comments:
------------------------------------------------------------------------
[2007-04-28 19:56:47] tobias dot barth at web-arts dot com
I know a bit more about it now. Trying to do select queries on MaxDB
tables with the unixODBC-Tool "isql" only returned the first column of
the first row full with data, the rest was empty. I contacted the author
of unixODBC, Nick Gorham, and was told to get the latest snapshot of
unixODBC. With that snapshot, isql works. The reason: In 64 Bit systems,
length parameters and pointers are 64-Bit. There is a new symbol
"SQLLEN" in the header files of unixODBC now. But the problem persists
in php. I got the latest php6 snapshot and got many compilation warnings
in php_odbc.c because of incompatible pointer types. php_odbc.c uses
SDWORD as length attributes and int variables as numeric representation
of pointers - e.g. for creating connection names. I tried to fix that
and put SQLLEN in each data structure where 4 byte datatypes where used
and produces a compiler warning - now the warnings are gone. But I still
get glibc errors, when doing select queries in MaxDB:
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560c3e90 ***
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560609c0 ***
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x000055555605e660 ***
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x0000555556052700 ***
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x0000555556064400 ***
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560cad60 ***
Perhaps I did something wrong with those SQLLEN things or just did not
enough - would you please take a look at it?
The diff between the snapshot and my modified version is:
lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u php_odbc.c
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c
--- php_odbc.c 2007-04-28 15:23:07.000000000 +0200
+++ /tmp/php6.0-200704281030/ext/odbc/php_odbc.c 2007-03-13
02:30:20.000000000 +0100
@@ -642,7 +642,7 @@
RETCODE rc;
int i;
SWORD colnamelen; /* Not used */
- SQLLEN displaysize;
+ SDWORD displaysize;
result->values = (odbc_result_value *)
safe_emalloc(sizeof(odbc_result_value), result->numcols, 0);
@@ -736,7 +736,7 @@
*/
SDWORD len;
#else
- SQLLEN len;
+ SQLINTEGER len;
#endif
zval **pv_res, **pv_num;
@@ -932,15 +932,15 @@
{
zval **pv_res, **pv_param_arr, **tmp;
typedef struct params_t {
- SQLLEN vallen;
- SQLLEN fp;
+ SDWORD vallen;
+ int fp;
} params_t;
params_t *params = NULL;
char *filename;
unsigned char otype;
SWORD sqltype, ctype, scale;
SWORD nullable;
- SQLLEN precision;
+ UDWORD precision;
odbc_result *result;
int numArgs, i, ne;
RETCODE rc;
@@ -1154,7 +1154,7 @@
result->stmt, state,
&error, errormsg,
sizeof(errormsg)-1,
&errormsgsize);
if (!strncmp(state,"S1015",5)) {
- snprintf(cursorname, max_len+1,
"php_curs_%d", (SQLLEN)result->stmt);
+ snprintf(cursorname, max_len+1,
"php_curs_%d", (int)result->stmt);
if
(SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {
odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName");
RETVAL_FALSE;
@@ -1726,7 +1726,7 @@
odbc_result *result;
int i = 0;
RETCODE rc;
- SQLLEN fieldsize;
+ SDWORD fieldsize;
zval **pv_res, **pv_field;
#ifdef HAVE_SQL_EXTENDED_FETCH
UDWORD crow;
@@ -2334,13 +2334,12 @@
if (zend_hash_find(&EG(regular_list), hashed_details,
hashed_len + 1,
(void **) &index_ptr) ==
SUCCESS) {
- int type;
- SQLLEN conn_id;
+ int type, conn_id;
void *ptr;
if (Z_TYPE_P(index_ptr) != le_index_ptr) {
RETURN_FALSE;
}
- conn_id = (SQLLEN)index_ptr->ptr;
+ conn_id = (int)index_ptr->ptr;
ptr = zend_list_find(conn_id, &type); /*
check if the connection is still there */
if (ptr && (type == le_conn || type ==
le_pconn)) {
zend_list_addref(conn_id);
@@ -2426,7 +2425,7 @@
PHP_FUNCTION(odbc_num_rows)
{
odbc_result *result;
- SQLROWCOUNT rows;
+ SDWORD rows;
zval **pv_res;
if (zend_get_parameters_ex(1, &pv_res) == FAILURE) {
lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c php_oodbc.c
diff: php_oodbc.c: Datei oder Verzeichnis nicht gefunden
lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c php_odbc.c
--- /tmp/php6.0-200704281030/ext/odbc/php_odbc.c 2007-03-13
02:30:20.000000000 +0100
+++ php_odbc.c 2007-04-28 15:23:07.000000000 +0200
@@ -642,7 +642,7 @@
RETCODE rc;
int i;
SWORD colnamelen; /* Not used */
- SDWORD displaysize;
+ SQLLEN displaysize;
result->values = (odbc_result_value *)
safe_emalloc(sizeof(odbc_result_value), result->numcols, 0);
@@ -736,7 +736,7 @@
*/
SDWORD len;
#else
- SQLINTEGER len;
+ SQLLEN len;
#endif
zval **pv_res, **pv_num;
@@ -932,15 +932,15 @@
{
zval **pv_res, **pv_param_arr, **tmp;
typedef struct params_t {
- SDWORD vallen;
- int fp;
+ SQLLEN vallen;
+ SQLLEN fp;
} params_t;
params_t *params = NULL;
char *filename;
unsigned char otype;
SWORD sqltype, ctype, scale;
SWORD nullable;
- UDWORD precision;
+ SQLLEN precision;
odbc_result *result;
int numArgs, i, ne;
RETCODE rc;
@@ -1154,7 +1154,7 @@
result->stmt, state,
&error, errormsg,
sizeof(errormsg)-1,
&errormsgsize);
if (!strncmp(state,"S1015",5)) {
- snprintf(cursorname, max_len+1,
"php_curs_%d", (int)result->stmt);
+ snprintf(cursorname, max_len+1,
"php_curs_%d", (SQLLEN)result->stmt);
if
(SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {
odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName");
RETVAL_FALSE;
@@ -1726,7 +1726,7 @@
odbc_result *result;
int i = 0;
RETCODE rc;
- SDWORD fieldsize;
+ SQLLEN fieldsize;
zval **pv_res, **pv_field;
#ifdef HAVE_SQL_EXTENDED_FETCH
UDWORD crow;
@@ -2334,12 +2334,13 @@
if (zend_hash_find(&EG(regular_list), hashed_details,
hashed_len + 1,
(void **) &index_ptr) ==
SUCCESS) {
- int type, conn_id;
+ int type;
+ SQLLEN conn_id;
void *ptr;
if (Z_TYPE_P(index_ptr) != le_index_ptr) {
RETURN_FALSE;
}
- conn_id = (int)index_ptr->ptr;
+ conn_id = (SQLLEN)index_ptr->ptr;
ptr = zend_list_find(conn_id, &type); /*
check if the connection is still there */
if (ptr && (type == le_conn || type ==
le_pconn)) {
zend_list_addref(conn_id);
@@ -2425,7 +2426,7 @@
PHP_FUNCTION(odbc_num_rows)
{
odbc_result *result;
- SDWORD rows;
+ SQLROWCOUNT rows;
zval **pv_res;
if (zend_get_parameters_ex(1, &pv_res) == FAILURE) {
lxdevel:/usr/src/php6.0-200704281030/ext/odbc #
------------------------------------------------------------------------
[2006-12-09 02:44:47] tobias dot barth at web-arts dot com
I reviewed the compiler output when compiling php_odbc.c today, and I
saw the following warnings:
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'zif_odbc_execute':
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:1042: warning:
cast to pointer from integer of different size
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'zif_odbc_cursor':
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:1157: warning:
cast from pointer to integer of different size
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'odbc_do_connect':
/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:2302: warning:
cast from pointer to integer of different size
In line 1042, you use the field "fp" as if it was a pointer:
rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,
ctype, sqltype, precision, scale,
(void
*)params[i-1].fp, 0,
¶ms[i-1].vallen);
on 32 Bit-Machines that may work, on 64 Bit machines, where the field
"fp" is declared as "int" (which is 32 Bit on SuSE Linux 10.1), and a
void* is a 64 Bit-Pointer, that will not work.
In line 2302, you do it the other way:
conn_id = (int)index_ptr->ptr;
Here, a pointer ("ptr") is treated as if it was an int value - cutting
off the high 32 bits.
In line 1157, there is:
sprintf(cursorname,"php_curs_%d",
(int)result->stmt);
maybe "stmt" is chopped off here, too - maybe that is harmful, too.
I think those "treat int as if a pointer would fit into it" things
could be the reason why I get those crashes after having used
"odbc_exec" or other php_odbc functions - do you agree?
Greetings,
Tobias Barth
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/39756
--
Edit this bug report at http://bugs.php.net/?id=39756&edit=1