S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

内存崩溃的BUG
内存崩溃的BUG (2)
内存崩溃的BUG (3)

连续三天在跟踪同个问题!!!!!!!!

今天重现了几次问题,都是下面的原因导致的。

首先要说下IOCP的实现

下面的发送包时的代码
-------------------------------------------------------------------------
PER_IO_CONTEXT* overlappedEx=new PER_IO_CONTEXT
overlappedEx->IOOperation= WRITE;
overlappedEx->wsabuf.buf= (char *)malloc( nLen );
if( NULL == overlappedEx->wsabuf.buf )
{
delete overlappedEx;
return -1;
}

if(WSASend(m_socket,&(overlappedEx->wsabuf), 0x01, &dwBytes, 0x00, &(overlappedEx->Overlapped), NULL ) == SOCKET_ERROR)
-------------------------------------------------------------------------


下面是完成端口通知时的处理代码
-------------------------------------------------------------------------
 while (m_bIsRun)
 {
  result = GetQueuedCompletionStatus(m_hCompletionPort,&iosize,&key,&overlapped,INFINITE);
  if ( 0 == key ) 
  {
   break;
  }
  if( NULL != overlappedEx )
  {
   if ( WRITE == overlappedEx->IOOperation )
   {   
    delete overlappedEx;
    continue;
   }
}

……
}
-------------------------------------------------------------------------

之后在     delete overlappedEx; 前面用 OutPutDebugString 打印了调试信息, 发现在 
 delete overlappedEx; 执行后

WSASend 里面还会访问到  overlappedEx 下面的  Overlapped,结果就在 WSASend 出错了

overlappedEx 的结构体定义如下:

struct PER_IO_CONTEXT
{
 WSAOVERLAPPED    Overlapped;
 WSABUF                      wsabuf;
 IO_OPERATION         IOOperation;
};


查了下 MSDN  WSASend 函数的说明,无头绪,明天继续

Feedback

# re: 内存崩溃的BUG (4) 完成端口的问题? 程序的BUG?[未登录]  回复  更多评论   

2009-04-02 19:48 by cppexplore
.............................
内存检测工具跑一遍就能发现的问题,你还真执着啊。

# re: 内存崩溃的BUG (4) 完成端口的问题? 程序的BUG?  回复  更多评论   

2009-04-07 13:14 by freeeyes
推荐你使用完全端口的时候,一定要注意判空操作。
如果我是你的话,就这么写。
while (m_bIsRun)
{
result = GetQueuedCompletionStatus(m_hCompletionPort,&iosize,&key,&overlapped,INFINITE);
if ( 0 == key )
{
break;
}
if( NULL != overlappedEx )
{
if ( WRITE == overlappedEx->IOOperation )
{
delete overlappedEx;
overlappedEx = NULL;
continue;
}
}

而且在使用Send的同时,可能会出现这样的情况。就是你发送的Send数据还在缓冲区的时候,你的overlappedEx对象被释放,造成的内存崩溃的现象。我的做法是增加一些数据锁。同时,在要删除overlappedEx的时候,先判定写标志是否在进行。如果有做一个定时器,延时几秒删除对象(将对象放入删除队列),这样似乎比较好。ACE下的思想也是这样的。
另外,我不太明白你为什么要在WRITE == overlappedEx->IOOperation 的时候进行删除对象操作?

# re: 内存崩溃的BUG (4) 完成端口的问题? 程序的BUG?  回复  更多评论   

2009-04-20 23:07 by hearts
我也遇到了这个问题。楼主发现的是对的。也是不知道为什么。只好对overlapped进行引用计数。问题倒是解决了,不过觉得做法很丑陋。不知道有没有好的解决办法。可能HasOverlappedCompleted有些帮助

# re: 内存崩溃的BUG (4) 完成端口的问题? 程序的BUG?  回复  更多评论   

2009-10-17 13:47 by FreeChord
delete overlappedEx;

这块内存(buf)没free啊!
overlappedEx->wsabuf.buf= (char *)malloc( nLen );

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理