socket---select 模型
C/C++本地代码调试
socket---select 模型
uglyangel
2011-05-20, 20:23 下午
问题背景:
为了检测网络的通常,采用异步socket的方式连接目标主机
问题描述:
1、::select在不同的机器上返回的结果不同
2、如果该函数在普通的exe中则没有问题,但是写在ocx中由iexplorer.exe加载则有该问题(IE 6,7,8均存在)
版本信息:
1>os:win xp sp3
2>ws2_32.dll:5.1.2600.5512
3>mswsock.dll:5.1.2600.5625
函数代码:
bool TestOnLine()
{
WSADATA wsaData;
::WSAStartup(MAKEWORD(2, 0), &wsaData);
SOCKET sSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (sSocket == SOCKET_ERROR)
{
return false;
}
u_long ulArg = 1;
if (::ioctlsocket(sSocket, FIONBIO, &ulArg) == SOCKET_ERROR)
{
::closesocket(sSocket);
return false;
}
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(3000 + 1);
addr.sin_addr.s_addr = ::inet_addr("192.168.0.110");
memset(addr.sin_zero, 0, 8);
if (::connect(sSocket, (sockaddr*)(&addr), sizeof(sockaddr_in)) == SOCKET_ERROR)
{
timeval tm;
tm.tv_sec = 3000 / 1000;
tm.tv_usec = 3000 % 1000;
fd_set set;
FD_ZERO(&set);
FD_SET(sSocket, &set);
if (::select(0, NULL, &set, NULL, &tm) > 0)
{
//目标主机不在线是理论上不应该走这里,但是有的PC机上跑这个函数确实会走到这里
int error = -1;
int len = sizeof(int);
::getsockopt(sSocket, SOL_SOCKET, SO_ERROR, (char*)(&error), &len);
if (error != 0)
{
::closesocket(sSocket);
return false;
}
}
else
{
::closesocket(sSocket);
return false;
}
}
::closesocket(sSocket);
return true;
}
windbg调试结果:
1>正常情况:
Tracing WS2_32!select to return address 03828f6a
3 0 [ 0] WS2_32!select
19 0 [ 1] WS2_32!_SEH_prolog
38 19 [ 0] WS2_32!select
6 0 [ 1] WS2_32!DSOCKET::GetCountedDSocketFromSocket
18 0 [ 2] WS2HELP!WahReferenceContextByHandle
4 0 [ 3] kernel32!InterlockedExchangeAdd
35 4 [ 2] WS2HELP!WahReferenceContextByHandle
5 0 [ 3] kernel32!InterlockedIncrement
39 9 [ 2] WS2HELP!WahReferenceContextByHandle
4 0 [ 3] kernel32!InterlockedExchangeAdd
47 13 [ 2] WS2HELP!WahReferenceContextByHandle
10 60 [ 1] WS2_32!DSOCKET::GetCountedDSocketFromSocket
50 89 [ 0] WS2_32!select
3 0 [ 1] MSWSOCK!WSPSelect
19 0 [ 2] MSWSOCK!_SEH_prolog
96 19 [ 1] MSWSOCK!WSPSelect
16 0 [ 2] MSWSOCK!_allmul
109 35 [ 1] MSWSOCK!WSPSelect
16 0 [ 2] MSWSOCK!_allmul
134 51 [ 1] MSWSOCK!WSPSelect
1 0 [ 2] ntdll!NtDeviceIoControlFile
2 0 [ 2] ntdll!ZwDeviceIoControlFile
2 0 [ 3] ntdll!KiFastSystemCall
1 0 [ 2] ntdll!ZwDeviceIoControlFile
147 57 [ 1] MSWSOCK!WSPSelect
21 0 [ 2] MSWSOCK!SockWaitForSingleObject
1 0 [ 3] ntdll!ZwWaitForSingleObject
2 0 [ 3] ntdll!NtWaitForSingleObject
2 0 [ 4] ntdll!KiFastSystemCall
1 0 [ 3] ntdll!NtWaitForSingleObject
30 6 [ 2] MSWSOCK!SockWaitForSingleObject
6 0 [ 3] MSWSOCK!SockFindAndReferenceSocket
18 0 [ 4] WS2HELP!WahReferenceContextByHandle
4 0 [ 5] kernel32!InterlockedExchangeAdd
35 4 [ 4] WS2HELP!WahReferenceContextByHandle
5 0 [ 5] kernel32!InterlockedIncrement
39 9 [ 4] WS2HELP!WahReferenceContextByHandle
4 0 [ 5] kernel32!InterlockedExchangeAdd
47 13 [ 4] WS2HELP!WahReferenceContextByHandle
10 60 [ 3] MSWSOCK!SockFindAndReferenceSocket
50 76 [ 2] MSWSOCK!SockWaitForSingleObject
13 0 [ 3] WS2_32!WPUQueryBlockingCallback
11 0 [ 4] WS2_32!Prolog_v2
11 0 [ 5] kernel32!TlsGetValue
19 11 [ 4] WS2_32!Prolog_v2
32 30 [ 3] WS2_32!WPUQueryBlockingCallback
60 138 [ 2] MSWSOCK!SockWaitForSingleObject
5 0 [ 3] kernel32!InterlockedDecrement
81 143 [ 2] MSWSOCK!SockWaitForSingleObject
1 0 [ 3] ntdll!NtQuerySystemTime
2 0 [ 3] ntdll!ZwQuerySystemTime
2 0 [ 4] ntdll!KiFastSystemCall
1 0 [ 3] ntdll!ZwQuerySystemTime
90 149 [ 2] MSWSOCK!SockWaitForSingleObject
1 0 [ 3] ntdll!ZwWaitForSingleObject
2 0 [ 3] ntdll!NtWaitForSingleObject
2 0 [ 4] ntdll!KiFastSystemCall
1 0 [ 3] ntdll!NtWaitForSingleObject
107 155 [ 2] MSWSOCK!SockWaitForSingleObject
182 319 [ 1] MSWSOCK!WSPSelect
5 0 [ 2] MSWSOCK!__security_check_cookie
183 324 [ 1] MSWSOCK!WSPSelect
9 0 [ 2] MSWSOCK!_SEH_epilog
184 333 [ 1] MSWSOCK!WSPSelect
53 606 [ 0] WS2_32!select
5 0 [ 1] WS2_32!DSOCKET::DropDSocketReference
5 0 [ 2] kernel32!InterlockedDecrement
9 5 [ 1] WS2_32!DSOCKET::DropDSocketReference
57 620 [ 0] WS2_32!select
9 0 [ 1] WS2_32!_SEH_epilog
58 629 [ 0] WS2_32!select
687 instructions were executed in 686 events (0 from other threads)
Function Name Invocations MinInst MaxInst AvgInst
MSWSOCK!SockFindAndReferenceSocket 1 10 10 10
MSWSOCK!SockWaitForSingleObject 1 107 107 107
MSWSOCK!WSPSelect 1 184 184 184
MSWSOCK!_SEH_epilog 1 9 9 9
MSWSOCK!_SEH_prolog 1 19 19 19
MSWSOCK!__security_check_cookie 1 5 5 5
MSWSOCK!_allmul 2 16 16 16
WS2HELP!WahReferenceContextByHandle 2 47 47 47
WS2_32!DSOCKET::DropDSocketReference 1 9 9 9
WS2_32!DSOCKET::GetCountedDSocketFromSocket 1 10 10 10
WS2_32!Prolog_v2 1 19 19 19
WS2_32!WPUQueryBlockingCallback 1 32 32 32
WS2_32!_SEH_epilog 1 9 9 9
WS2_32!_SEH_prolog 1 19 19 19
WS2_32!select 1 58 58 58
kernel32!InterlockedDecrement 2 5 5 5
kernel32!InterlockedExchangeAdd 4 4 4 4
kernel32!InterlockedIncrement 2 5 5 5
kernel32!TlsGetValue 1 11 11 11
ntdll!KiFastSystemCall 4 2 2 2
ntdll!NtDeviceIoControlFile 1 1 1 1
ntdll!NtQuerySystemTime 1 1 1 1
ntdll!NtWaitForSingleObject 4 1 2 1
ntdll!ZwDeviceIoControlFile 2 1 2 1
ntdll!ZwQuerySystemTime 2 1 2 1
ntdll!ZwWaitForSingleObject 2 1 1 1
4 system calls were executed
Calls System Call
4 ntdll!KiFastSystemCall
eax=00000000 ebx=038d3a44 ecx=71a23168 edx=ffffffff esi=03856f1c edi=0012e360
eip=03828f6a esp=0012dee8 ebp=0012e1a8 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000213
ACTIVE_1!Activeformproj1_atlFinalize+0x240a:
03828f6a 85c0 test eax,eax
2>非正常情况
Tracing WS2_32!select to return address 02668f6a
3 0 [ 0] WS2_32!select
19 0 [ 1] WS2_32!_SEH_prolog
8 19 [ 0] WS2_32!select
10 0 [ 1] WS2_32!SlowProlog
12 0 [ 2] WS2_32!Prolog_v1
11 0 [ 3] kernel32!TlsGetValue
24 11 [ 2] WS2_32!Prolog_v1
12 35 [ 1] WS2_32!SlowProlog
38 66 [ 0] WS2_32!select
6 0 [ 1] WS2_32!DSOCKET::GetCountedDSocketFromSocket
18 0 [ 2] WS2HELP!WahReferenceContextByHandle
4 0 [ 3] kernel32!InterlockedExchangeAdd
35 4 [ 2] WS2HELP!WahReferenceContextByHandle
5 0 [ 3] kernel32!InterlockedIncrement
39 9 [ 2] WS2HELP!WahReferenceContextByHandle
4 0 [ 3] kernel32!InterlockedExchangeAdd
47 13 [ 2] WS2HELP!WahReferenceContextByHandle
10 60 [ 1] WS2_32!DSOCKET::GetCountedDSocketFromSocket
50 136 [ 0] WS2_32!select
3 0 [ 1] mswsock!WSPSelect
19 0 [ 2] mswsock!_SEH_prolog
96 19 [ 1] mswsock!WSPSelect
16 0 [ 2] mswsock!_allmul
109 35 [ 1] mswsock!WSPSelect
16 0 [ 2] mswsock!_allmul
134 51 [ 1] mswsock!WSPSelect
1 0 [ 2] ntdll!NtDeviceIoControlFile
2 0 [ 2] ntdll!ZwDeviceIoControlFile
2 0 [ 3] ntdll!KiFastSystemCall
1 0 [ 2] ntdll!ZwDeviceIoControlFile
165 57 [ 1] mswsock!WSPSelect
10 0 [ 2] mswsock!__WSAFDIsSet
214 67 [ 1] mswsock!WSPSelect
5 0 [ 2] mswsock!__security_check_cookie
215 72 [ 1] mswsock!WSPSelect
9 0 [ 2] mswsock!_SEH_epilog
216 81 [ 1] mswsock!WSPSelect
53 433 [ 0] WS2_32!select
5 0 [ 1] WS2_32!DSOCKET::DropDSocketReference
5 0 [ 2] kernel32!InterlockedDecrement
9 5 [ 1] WS2_32!DSOCKET::DropDSocketReference
57 447 [ 0] WS2_32!select
9 0 [ 1] WS2_32!_SEH_epilog
58 456 [ 0] WS2_32!select
514 instructions were executed in 513 events (0 from other threads)
Function Name Invocations MinInst MaxInst AvgInst
WS2HELP!WahReferenceContextByHandle 1 47 47 47
WS2_32!DSOCKET::DropDSocketReference 1 9 9 9
WS2_32!DSOCKET::GetCountedDSocketFromSocket 1 10 10 10
WS2_32!Prolog_v1 1 24 24 24
WS2_32!SlowProlog 1 12 12 12
WS2_32!_SEH_epilog 1 9 9 9
WS2_32!_SEH_prolog 1 19 19 19
WS2_32!select 1 58 58 58
kernel32!InterlockedDecrement 1 5 5 5
kernel32!InterlockedExchangeAdd 2 4 4 4
kernel32!InterlockedIncrement 1 5 5 5
kernel32!TlsGetValue 1 11 11 11
mswsock!WSPSelect 1 216 216 216
mswsock!_SEH_epilog 1 9 9 9
mswsock!_SEH_prolog 1 19 19 19
mswsock!__WSAFDIsSet 1 10 10 10
mswsock!__security_check_cookie 1 5 5 5
mswsock!_allmul 2 16 16 16
ntdll!KiFastSystemCall 1 2 2 2
ntdll!NtDeviceIoControlFile 1 1 1 1
ntdll!ZwDeviceIoControlFile 2 1 2 1
1 system call was executed
Calls System Call
1 ntdll!KiFastSystemCall
eax=00000001 ebx=027139b0 ecx=71a23168 edx=0013dee8 esi=02696f1c edi=0013e360
eip=02668f6a esp=0013dee8 ebp=0013e1a8 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000213
ACTIVE_1!Activeformproj1_atlFinalize+0x240a:
02668f6a 85c0 test eax,eax
IDA显示结果:
int __stdcall WSPSelect(int a1, fd_set *a2, fd_set *a3, int a4, unsigned int a5, int a6)
{
fd_set *v6; // edx@13
int v7; // edx@15
unsigned int v8; // eax@17
unsigned __int64 *v9; // ebx@17
int v10; // edi@17
signed __int64 v11; // qax@17
int v12; // ebx@17
signed __int64 v13; // qax@17
signed __int64 v14; // qax@17
int v15; // ecx@17
int v16; // ebx@22
int v18; // ST28_4@26
int v19; // ST2C_4@26
int v20; // ST30_4@26
int v21; // ST50_4@26
int v22; // eax@28
SOCKET v23; // edi@28
unsigned int v24; // eax@4
unsigned int v25; // ecx@5
unsigned int v26; // edx@6
int v27; // eax@8
int v28; // eax@9
int v29; // eax@44
SOCKET v30; // edi@44
fd_set *v31; // edx@45
signed __int64 v32; // [sp+Ch] [bp-D0h]@17
signed __int64 v33; // [sp+14h] [bp-C8h]@17
int v34; // [sp+1Ch] [bp-C0h]@9
unsigned __int64 v35; // [sp+20h] [bp-BCh]@17
unsigned int v36; // [sp+2Ch] [bp-B0h]@17
int v37; // [sp+30h] [bp-ACh]@26
int v38; // [sp+34h] [bp-A8h]@26
int v39; // [sp+38h] [bp-A4h]@26
int v40; // [sp+3Ch] [bp-A0h]@26
int v41; // [sp+40h] [bp-9Ch]@26
int v42; // [sp+44h] [bp-98h]@26
int v43; // [sp+48h] [bp-94h]@26
int v44; // [sp+4Ch] [bp-90h]@1
int v45; // [sp+50h] [bp-8Ch]@26
int v46; // [sp+54h] [bp-88h]@26
unsigned int v47; // [sp+58h] [bp-84h]@9
int v48; // [sp+5Ch] [bp-80h]@3
int v49; // [sp+60h] [bp-7Ch]@9
fd_set *v50; // [sp+64h] [bp-78h]@1
int v51; // [sp+68h] [bp-74h]@1
unsigned int v52; // [sp+6Ch] [bp-70h]@5
unsigned int v53; // [sp+70h] [bp-6Ch]@5
unsigned int i; // [sp+74h] [bp-68h]@9
int v55; // [sp+78h] [bp-64h]@5
char v56; // [sp+7Ch] [bp-60h]@9
int v57; // [sp+80h] [bp-5Ch]@26
int v58; // [sp+84h] [bp-58h]@9
char v59; // [sp+88h] [bp-54h]@9
char v60; // [sp+8Ch] [bp-50h]@9
int v61; // [sp+90h] [bp-4Ch]@26
int v62; // [sp+94h] [bp-48h]@26
int v63; // [sp+98h] [bp-44h]@26
int v64; // [sp+9Ch] [bp-40h]@26
int v65; // [sp+A0h] [bp-3Ch]@26
int v66; // [sp+A4h] [bp-38h]@26
int v67; // [sp+A8h] [bp-34h]@26
int v68; // [sp+ACh] [bp-30h]@26
int v69; // [sp+B0h] [bp-2Ch]@26
int v70; // [sp+B4h] [bp-28h]@26
int v71; // [sp+B8h] [bp-24h]@26
int v72; // [sp+BCh] [bp-20h]@26
unsigned int v73; // [sp+C0h] [bp-1Ch]@26
CPPEH_RECORD ms_exc; // [sp+C4h] [bp-18h]@5
int v75; // [sp+DCh] [bp+0h]@26
v50 = a3;
v51 = a4;
v44 = a6;
if ( !SockProcessTerminating && SockWspStartupCount && (v48 = *(_DWORD *)(*MK_FP(__FS__, 24) + 3948)) != 0 )
v24 = 0;
else
v24 = SockEnterApiSlow(&v48);
v52 = v24;
v25 = 0;
JUMPOUT(v24, 0, *(unsigned int *)loc_719CDD50);
v53 = 0;
v55 = 0;
ms_exc.disabled = 0;
if ( a2 )
v26 = a2->fd_count & 0xFFFF;
else
v26 = 0;
if ( a3 )
v25 = a3->fd_count & 0xFFFF;
v27 = v51;
if ( v51 )
v27 = *(_DWORD *)v51 & 0xFFFF;
v34 = v26 + v27 + v25;
JUMPOUT(v26 + v27 + v25, 0, *(unsigned int *)loc_719CDD57);
v47 = 12 * (v26 + v27 + v25) + 16;
JUMPOUT(v47, 0x44u, *(unsigned int *)loc_719CDD62);
v53 = (unsigned int)&v56;
v58 = v26 + v27 + v25;
v59 = 0;
v28 = (int)&v60;
v49 = (int)&v60;
for ( i = 0; a2 && i fd_count & 0xFFFF); ++i )
{
*(_DWORD *)v28 = a2->fd_array<img src="/emoticons/emotion-55.gif" alt="Idea [I]" />;
*(_DWORD *)(v28 + 4) = 25;
v28 += 12;
v49 = v28;
}
i = 0;
v6 = v50;
while ( v6 && i fd_count & 0xFFFF) )
{
*(_DWORD *)v28 = v6->fd_array<img src="/emoticons/emotion-55.gif" alt="Idea [I]" />;
*(_DWORD *)(v28 + 4) = 4;
v28 += 12;
v49 = v28;
++i;
}
i = 0;
v7 = v51;
while ( v7 && i fd_count = 0;
if ( v50 )
v50->fd_count = 0;
if ( v51 )
*(_DWORD *)v51 = 0;
v16 = v10;
v49 = v10;
for ( i = 0; i fd_count, *(unsigned int *)loc_719CDDB6);
if ( 0 == a2->fd_count )
{
if ( a2->fd_count fd_array[v22] = v23;
++a2->fd_count;
}
}
++v55;
}
}
if ( *(_BYTE *)(v16 + 4) & 4 )
{
v30 = *(_DWORD *)v16;
v29 = __WSAFDIsSet(*(_DWORD *)v16, v50);
if ( !v29 )
{
v31 = v50;
v38 = 0;
JUMPOUT(0, v50->fd_count, *(unsigned int *)loc_719CDDC6);
if ( 0 == v50->fd_count )
{
if ( v50->fd_count fd_array[v29] = v30;
++v31->fd_count;
}
}
++v55;
}
}
JUMPOUT(*(_BYTE *)(v16 + 4) & 2, 0, *(unsigned int *)loc_719CDDD6);
JUMPOUT(*(_BYTE *)(v16 + 4) & 0x80, 0, *(unsigned int *)loc_719CDE1B);
JUMPOUT(*(_BYTE *)(v16 + 4) & 0x40, 0, *(unsigned int *)loc_719CDE5B);
JUMPOUT(*(_BYTE *)(v16 + 5) & 1, 0, *(unsigned int *)loc_719CDEA0);
JUMPOUT(*(_BYTE *)(v16 + 4) & 8, 0, *(unsigned int *)loc_719CDEE5);
JUMPOUT(*(_BYTE *)(v16 + 4) & 0x10, 0, *(unsigned int *)loc_719CDF25);
JUMPOUT(*(_BYTE *)(v16 + 4) & 0x20, 0, *(unsigned int *)loc_719CDF65);
v16 += 12;
v49 = v16;
}
ms_exc.disabled = -1;
if ( v53 )
JUMPOUT(v53, (unsigned int)&v56, *(unsigned int *)loc_719CDFE5);
JUMPOUT(v52, 0, *(unsigned int *)loc_719CDFFB);
__security_check_cookie(v73);
return _SEH_epilog(
v18,
v19,
v20,
v32,
HIDWORD(v32),
v33,
HIDWORD(v33),
v34,
v35,
HIDWORD(v35),
v21,
v36,
v37,
v38,
v39,
v40,
v41,
v42,
v43,
v44,
v45,
v46,
v47,
v48,
v49,
v50,
v51,
v52,
v53,
i,
v55,
*(_DWORD *)&v56,
v57,
v58,
*(_DWORD *)&v59,
*(_DWORD *)&v60,
v61,
v62,
v63,
v64,
v65,
v66,
v67,
v68,
v69,
v70,
v71,
v72,
v73,
ms_exc.old_esp,
ms_exc.exc_ptr,
ms_exc.prev_er,
ms_exc.handler,
ms_exc.msEH_ptr,
ms_exc.disabled,
v75);
}
期待各位高人指点一下,先谢谢了!