S.l.e!ep.¢%

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

内存崩溃的BUG (3)

Posted on 2009-04-01 13:35 S.l.e!ep.¢% 阅读(1532) 评论(3)  编辑 收藏 引用 所属分类: WinDbg

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

在昨天的调试中,感谢JayZ
-----------------------------------------------------------------------------------------------------
地址段034bd000 - 00007000没法访问。

看调用栈0012e50c 0042ffc3 00000400 034c0fec 00000001 ws2_32!WSASend+0x61

WSASend的第二个参数为034c0fec很不幸的落在这个区间内。看WSASend的原型
int WSASend(
__in SOCKET s,
__in LPWSABUF lpBuffers,
__in DWORD dwBufferCount,
__out LPDWORD lpNumberOfBytesSent,
__in DWORD dwFlags,
__in LPWSAOVERLAPPED lpOverlapped,
__in LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
显然第二个参数lpBuffers的地址非法。

call stack frame往上就是你的代码了:
0012f580 0040e577 0012f5bc 00000014 0012f58c xxx.exe+xxx-function

你需要在这里确认一下为什么传出的lpBuffers指向一个错误的地址
-------------------------------------------------------------------------------------------------------

传入 WSASend 的第二个参数 lpBuffers 确实指向了一个错误的地址,
用 knL + .frame + x
查看了   xxx.exe+xxx-function     的局部变量,发现

-------------------------------------------------------------------------------------------------------
PER_IO_CONTEXT* overlappedEx=new PER_IO_CONTEXT;      发现  overlappedEx  这个指针已经指向的内存是不对的
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,
&(overlappedEx->dwBytes), overlappedEx->dwFlags,
&(overlappedEx->Overlapped), NULL ) == SOCKET_ERROR)
{

在IOCP通知后,会 delete overlappedEx
-------------------------------------------------------------------------------------------------------

怀疑是不是 overlappedEx 这个指针的值被其它地方修改了?
于是在局数变量中定义了多一个变量,在 WSASend 调用前,加多这个语句,

PER_IO_CONTEXT* p  = overlappedEx;

等了几个小时,再次重现问题,

用 knL + .frame + x
查看了   xxx.exe+xxx-function     的局部变量,发现

p 的值跟 overlappedEx 还是相等的, 但它们指向的内存却是

0366fe8c p = 0x03443fd8
0:010> !address 0x03443fd8
    03442000 : 03442000 - 00007000
                    Type     00000000
                    Protect  00000001 PAGE_NOACCESS
                    State    00010000 MEM_FREE                
                    Usage    RegionUsageFree
0:010> dd 0x03443fd8
03443fd8  ???????? ???????? ???????? ????????
03443fe8  ???????? ???????? ???????? ????????
03443ff8  ???????? ???????? ???????? ????????
03444008  ???????? ???????? ???????? ????????
03444018  ???????? ???????? ???????? ????????
03444028  ???????? ???????? ???????? ????????
03444038  ???????? ???????? ???????? ????????
03444048  ???????? ???????? ???????? ????????

0:010> KB
ChildEBP RetAddr  Args to Child             
0366edac 71a26294 00000668 03443fec 00000001 mswsock!WSPSend+0x243
0366ede8 00430027 00000668 03443fec 00000001 ws2_32!WSASend+0x77

初步结论是: 在执行到  mswsock!WSPSend+0x243 ,在 WSASend 上一层 new 出来的  PER_IO_CONTEXT 已经被 delete 了

Feedback

# re: 内存崩溃的BUG (3)   回复  更多评论   

2009-04-02 00:15 by JayZ
看如下输出:
03442000 : 03442000 - 00007000
Type 00000000
Protect 00000001 PAGE_NOACCESS
State 00010000 MEM_FREE
Usage RegionUsageFree
这个内存段甚至已经不属于Heap了(RegionUsageFree)。

建议放个条件断点在VirtualFree里面,来看一下这个内存段什么时候被free掉的。从call stack上面应该很容易就能发现问题。

# re: 内存崩溃的BUG (3)   回复  更多评论   

2009-04-02 08:36 by guest
下内存断点来监视,看看到底是被谁给改了。

# re: 内存崩溃的BUG (3)   回复  更多评论   

2009-04-02 12:17 by S.l.e!ep.¢%
-------------------------------------------------------------------------------------------------------
PER_IO_CONTEXT* overlappedEx=new PER_IO_CONTEXT; 发现 overlappedEx 这个指针已经指向的内存是不对的
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, 0,
&(overlappedEx->Overlapped), NULL ) == SOCKET_ERROR)
{

在IOCP通知后,会 delete overlappedEx
-------------------------------------------------------------------------------------------------------

今天直接用 Windbg 启动程序,在 在IOCP通知后,会 delete overlappedEx 用 OutPutDebugString 打日志,
发现 在 delete overlappedEx 后,
WSASend 还会访问到 overlappedEx

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