关于TCP套接字关闭时出现memory fault(core dumped)的问题。

我在Qnx620下负责一个仿真系统网络程序的调试工作。我设计了一个这样的工作方式:当接到仿真中止命令后关闭程序中所用的两个TCP套接字,但每次调用ReleaseSocket(mysock)都出现memory fault(core dumped),程序直接崩溃。我觉得我的编程思路没什么问题:接到关闭消息-->shutdown(tcp_sock, 2)-->close(tcp_sock)。是不是这样有点不graceful呀?有那位朋友有这种遭遇吗?如果您能给我一些指点,一些帮助,我会非常感激!
附:(在程序中还用了select(…)。有两个TCP套接字,一个负责接数据,一个负责发数据,感觉是关闭接数据的那个套接字出问题。但我不确定)

源代码:
int ReleaseSocket(int* sock_fd){
if(*sock_fd<0) return -1;
if(0!=shutdown((*sock_fd),2)){
xErrorMsg(“In ReleaseSocket: shutdown() sock=%d…”,*sock_fd);
return -1;
}
if(0!=close((*sock_fd))){
xErrorMsg(“In ReleaseSocket: close() sock=%d…”,*sock_fd);
return -1;
}
*sock_fd=-1;
return EOK;
}

程序本身看上去没有什么问题,用Debug看一下具体是那一行导致了core dump。会不会应该传指针进来的,却传了fd进来?

传递参数肯定没问题。
我觉得好像是关闭正在传输数据的socket时候,造成的core dumped。
我那程序有4个线程,对Qnx下的debug又不熟悉。
还有,我觉得我的编程习惯还是不错的。
在每个调用出错时都会输出错误原因(就是我的xErrorMsg),但对于memory fault(core dumped)就无能为力了,根本就没给机会输出就直接崩溃。

  1. 在编译、链接时用-g 参数。
  2. 运行你的程序,等core dump后,在root 用户下,试试:

gdb /var/dump/.core

应该可以看到在那一行上出错。

xtang,首先对您表示衷心的感谢!
根据您上面的指导,我基本上大概找到了原因。
gdb显示的出错代码:
106(行号) if(FD_ISSET(gTCPRecvSock,&gFdSet.fs)){
其中gTCPRecvSock就是那个接收数据用的socket,gFdSet.fs是文件描述符集合。根据这一信息,基本确定了问题源。不过现在还没想出隔离该问题的好办法,我认为只要知道错误所在,下面问题就好办多了。

可能fd太大了吧。标准的FD_SETSIZE只有32,也就是说 fd 只能在 32 之下。
解决方法是在编译行里加 -DFD_SETSIZE=256,重新编译你的程序。

凭我的判断,不是这个原因,因为程序可以正常联调,只要不调用ReleaseSocket(&gTCPRecvSock),程序就能够很好的工作。一旦调用,就出现所描述的问题。在我的程序中,fd的个数总共没超过6个,fd最大的值也没超过10。
我会按照你的指导再调试,毕竟存在希望。
谢谢xtang热心的帮助!

再猜一次 :smiley:

ReleaseSocket(&gTCPRecvSock)后,gTCPRecvSock被设成了-1,然后程序又去FD_ISSET()测度,等于去测一个很大的fd,因为超过了fdset的大小,引起内存参照错。

试试
if(gTCPRecvSock != -1 && FD_ISSET(gTCPRecvSock,&gFdSet.fs)){

xtang,您的猜测完全正确,经过修改,程序运行非常好!
您的帮助使我摆脱了一段阴霾已久的不快,现在感觉好舒服啊。
再次谢谢您热心、耐心的帮助。今后我一定向您学习。