Description:
My environment is Windows XP sp3 and Visual Studio 2005.
Bug is similar to: Bug#48866: http://bugs.mysql.com/bug.php?id=48866
The program getsym.exe, running under the debugger, crashes in a call to mysql_query for load data local:
while ( mysql_ok = mysql_query( pmysql, <--- CRASH HERE
"load data local infile 'local_co' "
"replace into table companies fields terminated by ',' "
"lines terminated by '\n';" )) {
char *errmsg = mysql_error( pmysql );
report( stderr, FILI,
"%5d: load data local infile fail %s", pid, errmsg );
printf( "%5d: load data local infile fail %s", pid, errmsg );
pmysql = realConnectDB ( &mysql, "calls_new" );
}
the program crashes in strmov().
Call stack after crash:
getsym.exe!_strmov() + 0x11 bytes
getsym.exe!_net_clear_error() + 0x29 bytes
getsym.exe!_cli_advanced_command() + 0x136 bytes
getsym.exe!_mysql_send_query@12() + 0x70 bytes
getsym.exe!_mysql_real_query@12() + 0x98 bytes
getsym.exe!_mysql_query@8() + 0x1d bytes
--> getsym.exe!main(int argc=1, char * * argv=0x003e3090) Line 502 + 0x11 bytes C
getsym.exe!__tmainCRTStartup() Line 597 + 0x19 bytes C
ASM code around crash location:
_strmov:
0049FD10 push ebp
0049FD11 mov ebp,esp
0049FD13 push ecx
0049FD14 mov dword ptr [ebp-4],0CCCCCCCCh
0049FD1B mov eax,dword ptr [ebp+8]
0049FD1E mov ecx,dword ptr [ebp+0Ch] <-- crash prelude
0049FD21 mov dl,byte ptr [ecx] <-- crash
Registers at the time of the crash:
DL 2C
ECX 4741432C <-- not good!
EBP 00125A58
EAX 0012FDAF
How to repeat:
Call load data local infile to a remote server with an infile that's perhaps 20kb to 30kb in size. Crash does not always happen on the first call: sometimes the crash occurs on any subsequent call up to about the 20th call, in my experience.
Suggested fix:
I understand, from reading the history of bug 48866, that the bug was found in Fedora 12. But of course I'm not running Fedora 12: I'm runnning WinXP sp3 and using mysqlclient.lib v6.0.2 from 7-august-2009.
The suggested fix is to just call memmove( ) instead of trying to move chars inside strmov( ):
_strmov:
0049FD10 push ebp
0049FD11 mov ebp,esp
0049FD13 push ecx
0049FD14 mov dword ptr [ebp-4],0CCCCCCCCh
0049FD1B mov eax,dword ptr [ebp+8] // why this loop?
0049FD1E mov ecx,dword ptr [ebp+0Ch]
0049FD21 mov dl,byte ptr [ecx]
0049FD23 mov byte ptr [eax],dl
0049FD25 mov eax,dword ptr [ebp+8]
0049FD28 mov cl,byte ptr [eax]
0049FD2A mov byte ptr [ebp-1],cl
0049FD2D mov edx,dword ptr [ebp+8]
0049FD30 add edx,1
0049FD33 mov dword ptr [ebp+8],edx
0049FD36 mov eax,dword ptr [ebp+0Ch]
0049FD39 add eax,1
0049FD3C mov dword ptr [ebp+0Ch],eax
0049FD3F movsx ecx,byte ptr [ebp-1]
0049FD43 test ecx,ecx
0049FD45 je _strmov+39h (49FD49h)
0049FD47 jmp _strmov+0Bh (49FD1Bh) // call memmove( ) instead, imo
0049FD49 mov eax,dword ptr [ebp+8]
0049FD4C sub eax,1
0049FD4F mov esp,ebp
0049FD51 pop ebp
0049FD52 ret