S.l.e!ep.¢%

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

内存崩溃的BUG (2)

Posted on 2009-03-31 23:00 S.l.e!ep.¢% 阅读(1652) 评论(5)  编辑 收藏 引用 所属分类: WinDbg

内存崩溃的BUG

上次没查出是什么原因,这次继续

0:000> u eip
mswsock!WSPSend+0x243:
719c594a 8b4004          mov     eax,dword ptr [eax+4]
719c594d 8b4d14          mov     ecx,dword ptr [ebp+14h]
719c5950 8901            mov     dword ptr [ecx],eax
719c5952 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
719c5956 803dd8729f7100  cmp     byte ptr [mswsock!SockAsyncSelectCalled (719f72d8)],0
719c595d 0f8591ae0000    jne     mswsock!WSPSend+0x27f (719d07f4)
719c5963 837de400        cmp     dword ptr [ebp-1Ch],0
719c5967 0f85dfae0000    jne     mswsock!WSPSend+0x2d1 (719d084c)

0:000> r
eax=034c0fd8 ebx=00000000 ecx=0012e444 edx=7c92eb94 esi=00000000 edi=00000000
eip=719c594a esp=0012e474 ebp=0012e4d0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
mswsock!WSPSend+0x243:
719c594a 8b4004          mov     eax,dword ptr [eax+4] ds:0023:034c0fdc=????????
0:000> !address [eax+4]
    034bd000 : 034bd000 - 00007000
                    Type     00000000
                    Protect  00000001 PAGE_NOACCESS
                    State    00010000 MEM_FREE
                    Usage    RegionUsageFree

从上面的粗体看,应该是在调用 WSPSend  前就出错了,
难道是传参数是出的错? 有谁能解释下原因?

Feedback

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

2009-03-31 23:22 by 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指向一个错误的地址。

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

2009-04-01 08:47 by S.l.e!ep.¢%
感谢楼上,
在 xxx.exe+xxx-function 是这样调用 WSASend 的

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,
&(overlappedEx->dwBytes), overlappedEx->dwFlags,
&(overlappedEx->Overlapped), NULL ) == SOCKET_ERROR)
{

在IOCP通知后,会 delete overlappedEx

这里应该是 overlappedEx 被破坏了,在堆分配的东西被破坏要从何查起好?

另外 00000400 034c0fec 00000001

00000400 表示第一个参数?
034c0fec 表示第二个参数?
00000001 表示第三个参数?

# re: 内存崩溃的BUG (2) [未登录]  回复  更多评论   

2009-04-01 10:10 by cppexplore
写完代码,需要用内存测试工具跑反复的跑,压力下跑,一遍没跑期望没有任何的内存问题 基本是不可能的。至少至今我开发的服务器,没有一个是写完编译过,就没有任何内存问题的。

# re: 内存崩溃的BUG (2) [未登录]  回复  更多评论   

2009-04-01 10:12 by cppexplore
由于内存问题宕掉,堆栈什么的都是不可信的,一定要在初次出现问题的地方找(第一次写内存错误),都到后面了,什么意义都没了。

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

2009-04-01 11:15 by JayZ
@S.l.e!ep.¢%

你试试看在overlappedEx地址处放个ba ,看看啥时候这个地址的内容被人改掉了。

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