Bug #5387 | Core dump on mysql_stmt_execute | ||
---|---|---|---|
Submitted: | 3 Sep 2004 11:42 | Modified: | 13 Sep 2004 21:10 |
Reporter: | Bill McCaffrey | Email Updates: | |
Status: | Duplicate | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 4.1.4 | OS: | Linux (Mandrake 9) |
Assigned to: | Assigned Account | CPU Architecture: | Any |
[3 Sep 2004 11:42]
Bill McCaffrey
[6 Sep 2004 9:24]
Konstantin Osipov
Stack trace clearly shows that stmt pointer given to update_stmt_fields is damaged. This is the same pointer as you give to mysql_stmt_execute. So we're most likely seeing a stack overrun, either inside libmysql, or inside your application. A repeatable test case is required to debug the problem. Could you provide us with one? Thank you.
[8 Sep 2004 5:56]
Bill McCaffrey
I have found an interesting things here. If I free all statements as soon as I get a 1210 error, then the segfault never happens. Here is a program to create the 1210 "Incorrect arguments to mysql_stmt_execute" error. I am still working on some sample code to get the segfault. Note that setting SIZE below 97 does not generate any errors. This was tested on server and client versions 4.1.3 and 4.1.4 witht he same results #include <string.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <mysql.h> // values above 96 generate 1210 errors #define SIZE 97 #define SERVER "" #define USERNAME "" #define PASSWORD "" #define DEFAULTDB "" ////////////////////////////////////////////////////////////////////// // statement cache entry typedef struct { long bindcount; MYSQL_STMT* stmt; MYSQL_BIND* bind; long length[SIZE]; my_bool isnull[SIZE]; char data[SIZE][21]; } mycacheitem; void populate_table(MYSQL* dbconn); mycacheitem* build_cache(MYSQL* dbconn,int items); void run_query(MYSQL* dbconn,mycacheitem* myitem,int start); ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { MYSQL* dbconn = 0; int cv,sv; int i,j; mycacheitem* cache[SIZE]; dbconn = mysql_init(0); if(dbconn == 0) { puts("init error"); exit(0); } if(mysql_real_connect(dbconn,SERVER,USERNAME,PASSWORD,DEFAULTDB,0,0,0) == 0) { puts("connect error"); exit(0); } cv = mysql_get_client_version(); sv = mysql_get_server_version(dbconn); printf("client version is %d\n",cv); printf("server version is %d\n",sv); if(cv < 40103) { puts("upgrade client libraries to at least 4.1.3"); exit(0); } if(sv < 40103) { puts("upgrade server to at least 4.1.3"); exit(0); } populate_table(dbconn); printf("building cache:\n"); for(i=0;i<SIZE;i++) { putchar('.'); cache[i] = build_cache(dbconn,i+1); } for(i=0;i<10;i++) { printf("\n%d:",i); for(j=0;j<SIZE;j++) { run_query(dbconn,cache[j],i); putchar('.'); } } mysql_close(dbconn); return 0; } ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// void populate_table(MYSQL* dbconn) { char query[500]; int i; if(mysql_query(dbconn,"drop table test") != 0) { printf("drop table: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); } if(mysql_query(dbconn,"create table test (f1 int primary key)") != 0) { printf("create table: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } puts("building table"); for(i=0;i<SIZE*3;i++) { sprintf(query,"insert into test values (%d)",i); putchar('.'); if(mysql_query(dbconn,query) != 0) { printf("insert: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } } puts("done"); } ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// mycacheitem* build_cache(MYSQL* dbconn,int items) { char query[SIZE*4+100]; int i; int bindcount = 0; unsigned long size; MYSQL_BIND* bind; mycacheitem* myitem; myitem = malloc(sizeof(mycacheitem)); memset(myitem,0,sizeof(mycacheitem)); strcpy(query,"select * from test where f1 in ( ?"); for(i=1;i<items;i++) strcat(query,", ?"); strcat(query,")"); myitem->stmt = mysql_stmt_init(dbconn); if (!myitem->stmt) { printf("stmt_init: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } if (mysql_stmt_prepare(myitem->stmt, query, strlen(query))) { printf("stmt_prepare: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } bindcount= mysql_stmt_param_count(myitem->stmt); if (bindcount <= 0) { printf("bindcount: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } size = bindcount*sizeof(MYSQL_BIND); bind = malloc(size); memset(bind,0,size); myitem->bind = bind; myitem->bindcount = bindcount; for(i=0;i<bindcount;i++) { bind->buffer_type = MYSQL_TYPE_VAR_STRING; bind->buffer_length = 20; bind->buffer = myitem->data[i]; bind->is_null = &(myitem->isnull[i]); bind->length = &(myitem->length[i]); bind++; } if (mysql_stmt_bind_param(myitem->stmt, myitem->bind)) { printf("bind param: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } return myitem; } ////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////// void run_query(MYSQL* dbconn,mycacheitem* myitem,int start) { int i; MYSQL_BIND* bind; int myerr; bind = myitem->bind; for(i = 0;i < myitem->bindcount;i++) { sprintf(bind->buffer,"%d",start+i*2); *(bind->length) = strlen(bind->buffer); bind++; } if(mysql_stmt_execute(myitem->stmt)) { myerr = mysql_errno(dbconn); printf("\nexecute: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); if(myerr == 1210) return; else exit(0); } if(mysql_stmt_store_result(myitem->stmt)) { printf("store result: %d %s\n",mysql_errno(dbconn),mysql_error(dbconn)); exit(0); } }
[8 Sep 2004 8:46]
Konstantin Osipov
97 is the number here. This is most likely the same bug as Bug#5399, which was closed just a few minutes ago. Could you check that the problem doesn't exist on the latest BK tree? Thank you.
[9 Sep 2004 4:41]
Bill McCaffrey
I needed to apply that change to sql/sql_class.cc as well and I am no longer seeing the 1210 errors. I will have to do some more testing to see if the segfault issue is gone.
[9 Sep 2004 5:21]
Bill McCaffrey
The program that I used to produce the segfault is now working fine with the updated server and client lib.
[13 Sep 2004 21:10]
Konstantin Osipov
Good, then I'm closing the bug report (duplicate of bug #5399).