|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2006-12-06 15:16 UTC] tobias dot barth at web-arts dot com
Description:
------------
I got SuSE 10.1, a self-compiled php 4.4.4 (also tried the php5-5.1.2-29.22 from SuSE and php 5.1.4 from the php website with the same result), unixODBC, apache 2.2 and MaxDB 7.6 on an AMD X2 x86_64 platform with the following table:
CREATE TABLE "PRESSESTIMMEN"
(
"ID" Fixed (18,0) NOT NULL,
"TITLE" Varchar (100) ASCII,
"HEADLINE" Varchar (250) ASCII,
"DATUM" Date,
"TEXT" Long ASCII,
"BILD_NAME" Varchar (100) ASCII,
"BILD_TYPE" Varchar (120) ASCII,
"BILD_SIZE" Fixed (18,0),
"BILD" Char (2) ASCII,
"ARCHIVDATUM" Date,
PRIMARY KEY ("ID")
)
doing a
$a = odbc_exec ($dbcon, select id,title,headline,datum from pressestimmen");
while (odbc_fetch_into ($a, $row)) {
...
}
works well. But if I modify the select statement:
$a = odbc_exec ($dbcon, select * from pressestimmen");
only reads out the first line. The second call to "odbc_fetch_into" crashes. in the error_log of apache, I see
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid pointer: 0x0000
555555c2df40 ***
If I modify the select statement to
$a = odbc_exec ($dbcon, "select id,title,headline,datum,text from pressestimmen");
I get the same problems. I think it is because of the data type "long ascii" of the "text" column. I had this software running on php3 and php4 since the days of SuSE 7.0 on 32 bit platforms until SuSE 10.0 and SuSE 10.1 on a dual XEON 32 bit platform without problems, but now on the 64 bit machine, it crashes. So I think, it is an 64 Bit problem with the Long Ascii data type.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
okay, I will create a test script. in the meantime - perhaps this trace could help? ---Type <return> to continue, or q <return> to quit--- Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 47707950089888 (LWP 29782)] _efree (ptr=0x640000003c) at /usr/src/php4-STABLE-200612061330/Zend/zend_alloc.c:256 256 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(p->size); (gdb) bt #0 _efree (ptr=0x640000003c) at /usr/src/php4-STABLE-200612061330/Zend/zend_alloc.c:256 #1 0x00002b63e17b0463 in _free_odbc_result (rsrc=<value optimized out>) at /usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:173 #2 0x00002b63e1869efe in list_entry_destructor (ptr=<value optimized out>) at /usr/src/php4-STABLE-200612061330/Zend/zend_list.c:177 #3 0x00002b63e186983a in zend_hash_del_key_or_index (ht=0x2b63e19faaa8, arKey=0x0, nKeyLength=0, h=12, flag=<value optimized out>) at /usr/src/php4-STABLE-200612061330/Zend/zend_hash.c:529 #4 0x00002b63e186a107 in _zend_list_delete (id=<value optimized out>) at /usr/src/php4-STABLE-200612061330/Zend/zend_list.c:56 #5 0x00002b63e1870c08 in zend_assign_to_variable (result=0x555555c63288, op1=<value optimized out>, op2=0x555555c632c8, value=0x555555bfea08, type=0, Ts=0x7fffccb7aa00) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:483 #6 0x00002b63e187677c in execute (op_array=0x555555c04f38) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:1393 #7 0x00002b63e18782a9 in execute (op_array=0x555555b651c0) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:2278 #8 0x00002b63e1876249 in execute (op_array=0x555555b256c8) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:1725 #9 0x00002b63e18782a9 in execute (op_array=0x555555b20ef8) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:2278 #10 0x00002b63e1862a9a in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/src/php4-STABLE-200612061330/Zend/zend.c:935 #11 0x00002b63e18344b7 in php_execute_script (primary_file=0x7fffccb995d0) at /usr/src/php4-STABLE-200612061330/main/main.c:1752 #12 0x00002b63e188083d in php_handler (r=0x555555b0d0a8) at /usr/src/php4-STABLE-200612061330/sapi/apache2handler/sapi_apache2.c:581 #13 0x000055555558c6ba in ap_run_handler () from /usr/sbin/httpd2-prefork #14 0x000055555558faa2 in ap_invoke_handler () from /usr/sbin/httpd2-prefork #15 0x000055555559a1c8 in ap_process_request () from /usr/sbin/httpd2-prefork #16 0x0000555555597409 in ap_register_input_filter () from /usr/sbin/httpd2-prefork #17 0x0000555555593772 in ap_run_process_connection () from /usr/sbin/httpd2-prefork #18 0x000055555559dc09 in ap_graceful_stop_signalled () from /usr/sbin/httpd2-prefork #19 0x000055555559de0e in ap_graceful_stop_signalled () from /usr/sbin/httpd2-prefork #20 0x000055555559e911 in ap_mpm_run () from /usr/sbin/httpd2-prefork #21 0x0000555555579cb8 in main () from /usr/sbin/httpd2-prefork (gdb) quitI have now created an example, which always crashes on my machine. 1) create the user "CRASHTEST" on a MaxDB 7.6 database (log in as DBA in the sqlstudio and type: create user CRASHTEST password CRASHTEST resource not exclusive) 2) login in as user "CRASHTEST" and run the following sql script: CREATE TABLE "PRESSESTIMMEN" ( "ID" Fixed (18,0) NOT NULL, "TITLE" Varchar (100) ASCII, "HEADLINE" Varchar (250) ASCII, "TEXT" Long ASCII, "BILD_NAME" Varchar (100) ASCII, "BILD_TYPE" Varchar (120) ASCII, "BILD_SIZE" Fixed (18,0), "BILD" Char (2) ASCII, PRIMARY KEY ("ID") ) // insert into pressestimmen(id,title,headline,text,bild_name,bild_type,bild_size,bild) values(1,'test','test','testtext','test','test/test',100000,'te') // insert into pressestimmen(id,title,headline,text,bild_name,bild_type,bild_size,bild) values(2,'test','test','testtext','test','test/test',100000,'te') // insert into pressestimmen(id,title,headline,text,bild_name,bild_type,bild_size,bild) values(2,'test','test','testtext','test','test/test',100000,'te') 3) run the following php script (my unixODBC instance is called "OLTP"): <? $dbcon = odbc_connect ("OLTP", "CRASHTEST", "CRASHTEST"); $z=odbc_exec("select * from pressestimmen where id=3"); $a = odbc_exec ($dbcon, "select id from pressestimmen"); echo "end of script";flush(); ?> this crashes, and the gdb backtrace is: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 47129735329440 (LWP 15483)] 0x00002add3ea84f01 in _int_malloc () from /lib64/libc.so.6 (gdb) bt #0 0x00002add3ea84f01 in _int_malloc () from /lib64/libc.so.6 #1 0x00002add3ea86d76 in malloc () from /lib64/libc.so.6 #2 0x00002add413c20cb in _emalloc (size=21) at /usr/src/php4-STABLE-200612061330/Zend/zend_alloc.c:177 #3 0x00002add4132277a in odbc_bindcols (result=0x555555b26668) at /usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:674 #4 0x00002add41325c0f in zif_odbc_exec (ht=<value optimized out>, return_value=0x555555b25188, this_ptr=<value optimized out>, return_value_used=<value optimized out>) at /usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:1323 #5 0x00002add413eb1ce in execute (op_array=0x555555b20478) at /usr/src/php4-STABLE-200612061330/Zend/zend_execute.c:1681 #6 0x00002add413d1a9a in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/src/php4-STABLE-200612061330/Zend/zend.c:935 #7 0x00002add413a34b7 in php_execute_script (primary_file=0x7fff6d02ba50) at /usr/src/php4-STABLE-200612061330/main/main.c:1752 #8 0x00002add413ef83d in php_handler (r=0x555555b0d0a8) at /usr/src/php4-STABLE-200612061330/sapi/apache2handler/sapi_apache2.c:581 #9 0x000055555558c6ba in ap_run_handler () from /usr/sbin/httpd2-prefork #10 0x000055555558faa2 in ap_invoke_handler () from /usr/sbin/httpd2-prefork #11 0x000055555559a1c8 in ap_process_request () from /usr/sbin/httpd2-prefork #12 0x0000555555597409 in ap_register_input_filter () from /usr/sbin/httpd2-prefork #13 0x0000555555593772 in ap_run_process_connection () from /usr/sbin/httpd2-prefork #14 0x000055555559dc09 in ap_graceful_stop_signalled () from /usr/sbin/httpd2-prefork #15 0x000055555559de0e in ap_graceful_stop_signalled () from /usr/sbin/httpd2-prefork #16 0x000055555559e911 in ap_mpm_run () from /usr/sbin/httpd2-prefork #17 0x0000555555579cb8 in main () from /usr/sbin/httpd2-prefork (gdb) it crashes in the second call to odbc_exec. when I place a echo "1";exit; between both calls to odbc_exec, the "1" is displayed and it does not crash.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 BarthI 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 #