阅读:1171回复:5
protocolreceive封装
我想在windows CE 4.2 的passthru的protocol.c文件,使用protocolReceive()中做IPIP封装,ping已经通了,但是一段时间后,会出现内存分配不足。也就是出现内存泄露。代码片断如下,那位大侠给指点一下吧,多谢了!
//把数据包内容拷贝到pData status = NdisAllocateMemory( (PVOID *)&pData, uiLookAheadBufferSize, 0, noMaxAddr); if(status != NDIS_STATUS_SUCCESS) return 1; status = NdisAllocateMemory( (PVOID *)&pHeader, uiHeaderBufferSize, 0, noMaxAddr); if(status != NDIS_STATUS_SUCCESS) return 1; NdisZeroMemory (pHeader, uiHeaderBufferSize); NdisZeroMemory (pData, uiLookAheadBufferSize); NdisMoveMemory(pHeader, pvHeaderBuffer, uiHeaderBufferSize); NdisMoveMemory(pData, pvLookAheadBuffer, uiLookAheadBufferSize); 。。。。。。 。。。。。。 //用pEncapData构造新的数据包 status = NdisAllocateMemory((PVOID *)&pEncapData, uiLookAheadBufferSize+sizeof(ip_header), 0, noMaxAddr); if (status!=NDIS_STATUS_SUCCESS ) return 1; NdisZeroMemory(pEncapData, uiLookAheadBufferSize+sizeof(ip_header)); //把封装好的IP头拷贝进数据包 NdisMoveMemory(pEncapData, pIpHeader, sizeof(ip_header)); NdisMoveMemory(pEncapData+sizeof(ip_header), pData, uiLookAheadBufferSize); 。。。。。。 。。。。。。 //指定包 NdisMEthIndicateReceive(pBinding->hMPBinding, hMacReceiveContext, HeaderBuffer, uiHeaderBufferSize, (PVOID)pEncapData, LookAheadBufferSize+20, uiPacketSize+20); //释放内存 NdisFreeMemory(pIpHeader, sizeof(ip_header), 0); NdisFreeMemory(pEncapData, uiLookAheadBufferSize+20, 0); 如果不封装,只是使用pData代替pLookAheadBuffer,即 NdisMEthIndicateReceive(pBinding->hMPBinding, hMacReceiveContext, pvHeaderBuffer, uiHeaderBufferSize, (PVOID)pData, uiLookAheadBufferSize,uiPacketSize); 就没有内存泄露问题!!! |
|
论坛版主
|
沙发#
发布于:2005-08-04 15:09
时间有点儿长,有点儿记不清了:)
你这儿写得不是很清楚,你是在帮下层释放资源吗?(pIpHeader等等) 如果是,我觉得这里释放资源好像不对,CE的NDIS和桌面系统提供的API和处理流程一样的话,我记得在向上INDICATE包的时候把下层传来的包包存在你自己分配的包的一个域的,而上层返回你会调用NdisReturnPackets,也就是执行ndis IMD的MPReturnPacket,这里你释放你刚才分配的东西,然后把下层传上来的缓冲区归还给miniport驱动,他自己释放。 |
|
板凳#
发布于:2005-08-04 15:47
我根据protocolreceive()传来的pvLookAheadBuffer指针,做简单的IPIP封装。pIpHeader也是我分配的,用NdisAllocateMemory()分配。我不太清楚为什么不做封装(但用自己的缓冲区替换了pvLookAheadBuffer),可以长时间ping;而一旦封装(解封装),就会发生内存泄露。PB提示的错误是
ERROR: d:\mckendric\private\winceos\coreos\nk\kernel\virtmem.c line 1217: 248308 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: Failed VirtualAlloc(00003000) of 00000014 bytes 248309 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: Data Abort: Thread=83c31a9c Proc=829793a8 'device.exe' 248310 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: AKY=00000009 PC=03fb730c RA=010ca8c0 BVA=08000000 FSR=00000007 248329 PID:83c85dd2 TID:e3c315d2 0x83c31a9c: NKDispatchException: returning failure. Flags=0 |
|
论坛版主
|
地板#
发布于:2005-08-04 16:32
你自己分配的缓冲区使用了virtualalloc?释放资源的时候有没有free呢?
|
|
地下室#
发布于:2005-08-07 15:14
我没有使用VirtualAlloc(),另外,保证NdisAllocateMemory()和NdisFreeMemory()成对使用了。
这可能是protocolreceive()函数执行时间过长的原因吗,或者说封装应该在protocolreceiveComplete()中执行。protocolreceive()和protocolreceiveComplete()有什么区别,前者分配的缓冲区如何在后者中释放呢? |
|
论坛版主
|
5楼#
发布于:2005-08-08 13:40
这个函数在2k/nt下面运行时会禁止调度,但在ce下怎么样我不清楚,不过你最好让这个函数尽快结束。
我记得protocolreceiveComplete()这个函数不需要动吧。 你再看看你的ptreceive是否包含了三种完整的情况?(有三条接受路径,具体什么状况你可以到ndis版询问,现成帖子也很多) |
|