winsock 选择函数处的堆栈溢出异常 (0xC00000FD)
我有一个使用winsock 的应用程序。 I/O 部分在另一个线程上处理。 我正在对套接字使用阻塞选择方法。 但重点是,5-6 小时后,我的应用程序在 select 函数行给出了 0xC00000FD 异常。
据我所知,当存在递归或者非常大的局部变量时,就会出现这种异常。但对我来说,这两种情况都不是。
那么你知道我为什么会遇到这个异常吗? 或者有什么想法可以发现实际导致异常的原因?
非常感谢
编辑2:
亲爱的大家,我很抱歉,但由于重现案例需要很长时间,我才意识到这并没有解决问题。 当 select 函数行发生堆栈溢出异常时,一切似乎都正常。
我的意思是它是一个连接了一个客户端的服务器套接字。所以rset中有2个socket,wset中有1个。选择后,我正在检查所有准备好的套接字并进行必需的读取、写入、接受。超时为 250 毫秒。你认为这可能是问题所在吗?我不希望这个函数被阻塞,所以它不为空。但如果我使用 {0,0} ,确切的区别是什么?
一个重要的提示是:
当客户端套接字未发送任何数据时,相同的代码可以正常工作,没有任何问题。 但是当我开始从客户端向服务器发送一些数据时,出现了这个问题。 我确信 FD_SET 和 FD_CLR 没有问题,我的意思是当客户端不发送时,只有 1 个(服务器)套接字在 rset 中,1 个(客户端)在 wset 中。
反正我看了很多样品,但似乎没有什么区别。
请参阅下面的局部变量屏幕截图(我删除了可执行文件的名称,因为它是商业产品) http://img192.imageshack.us/img192/1948/stackoverflow.jpg
这是调用堆栈: ntdll.dll!7c90df3a()
[下面的框架可能不正确和/或丢失,没有为 ntdll.dll 加载符号] mswsock.dll!71a53c9c()
ntdll.dll!7c90d26c()
mswsock.dll!71a55f9f()
mswsock.dll!71a55974()
ws2_32.dll!71ab314f()
xyz.exe!vm_socket_select(vm_socket * hds=0x04c1fb84, int nhd=1, int mask=7) 第 230 行 + 0x1b 字节 C
xyz.exe!ND::nd_socket::SocketThreadProc() 第 173 行 + 0x12 字节 C++
xyz.exe!ND::nd_socket::ThreadRoutineStarter(void * u=0x07d63f90) 第 332 行 C++
xyz.exe!_callthreadstartex() 第 348 行 + 0x6 字节 C
xyz.exe!_threadstartex(void * ptd=0x011a3ce8) 第 326 行 + 0x5 字节 C
kernel32.dll!7c80b713()
我正在等待任何建议。 非常感谢
I have an application which makes use of winsock.
I/O part is handled on an other thread.
And I am using blocking select method for sockets.
But the point is that after 5-6 hours,my application gives 0xC00000FD exception, at the line of select function.
As far as I know, this exception occurs when there is recursion, or very large local variables. But neither of them is the case for me.
So do you have any idea why am I getting this exception?
Or any ideas to discover what actually causes exception?
many thanks
EDIT 2:
Dear All, I am very sorry but since reproducing the case takes long time, I just realized that this has not solved the problem.
Everything seems ok when stack overflow exception occurs at the line of select function.
I mean it is a server socket with a one client connected. So there is 2 socket in rset and 1 in wset. After selecting, I am checking all ready sockets and making required, read,write,accept. Timeout is 250 ms. Do you think can this be the problem? I don't want this function to be blocking so it is not null. But what will be the exact difference if I use {0,0}
An important hint is:
Same code was working without any problem, when client socket wasn't sending any data.
But when I started sending some data from client to server this problem occured.
I am sure that there is no problem with FD_SETs and FD_CLRs, I mean when client was not sending only 1(server) socket was in rset and 1(client) was in wset.
Anyway I had a look a lot of samples, but it seems that there is not a difference.
Please see local variables screenshot below(I have deleted name of executable, since it is a commercial product)
http://img192.imageshack.us/img192/1948/stackoverflow.jpg
And here is the call stack:
ntdll.dll!7c90df3a()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
mswsock.dll!71a53c9c()
ntdll.dll!7c90d26c()
mswsock.dll!71a55f9f()
mswsock.dll!71a55974()
ws2_32.dll!71ab314f()
xyz.exe!vm_socket_select(vm_socket * hds=0x04c1fb84, int nhd=1, int masks=7) Line 230 + 0x1b bytes C
xyz.exe!ND::nd_socket::SocketThreadProc() Line 173 + 0x12 bytes C++
xyz.exe!ND::nd_socket::ThreadRoutineStarter(void * u=0x07d63f90) Line 332 C++
xyz.exe!_callthreadstartex() Line 348 + 0x6 bytes C
xyz.exe!_threadstartex(void * ptd=0x011a3ce8) Line 326 + 0x5 bytes C
kernel32.dll!7c80b713()
I am waiting for any advice.
Many thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否尝试过在运行一段时间后在调试器中停止程序?然后看一下堆栈,它可能会给您提示。
递归并不意味着您的函数之一会无休止地调用自身,它再复杂不过了,并且在返回到起始位置之前涉及多个层。
Have you tried stopping your program in a debugger after some time running? Then take a look at the stack it might give you a hint.
Recursion doesn't mean one of your functions call itself endlessly, it can't be more tricky and involve several layers before it comes back where it started.