导致堆失败的原因 [英] propget cause heap failure

查看:272
本文介绍了导致堆失败的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在使用COM为MFC/控制台应用程序提供一些日期.但是遇到一些堆堆失败的情况.

以下是场景:

1.定义propget方法

Hi Guys,

I was using a COM to provide some date for MFC/Console app. But encounter some propget heap failure.

Following is the scenario:

1. Define the propget method

HRESULT m_ProcessName([out, string, retval] OLECHAR** pVal);


正文:


Body:

STDMETHODIMP CExProcessInfo::get_m_ProcessName(OLECHAR** pVal)
 {
  // TODO: Add your implementation code here
  if(m_pProcessName == NULL)
   *pVal = (OLECHAR*)::SysAllocString(L"");
  else
   *pVal = (OLECHAR*)::SysAllocString(m_pProcessName);
  return S_OK;
 }



2.在客户端上调用方法:



2. Call the method on client:

WCHAR* pProcName = new WCHAR[MAX_PATH];

  pep[i]->get_m_ProcessName(&pProcName);



在控制台应用程序中,此调用可以很好地执行并返回正确的值.但是,当我在MFC OnInitDialog()中调用此功能时,它将失败并提示一个断言.

当我调试代码时,我得到以下失败信息:



In console application, this call can be executed well and return the right value. But when i call this fucntion in MFC OnInitDialog(), it will fail and prompt a assert.

When i debug into the code, i''ve got the following failure info:

!heap -s -v

Details:==============================

Error address: 0041185c
 Heap handle: 003a0000
 Error type heap_failure_invalid_argument (9)
 Stack trace:
                 772cddff: ntdll!RtlFreeHeap+0x00000064
                 75ad6e6a: ole32!CRetailMalloc_Free+0x0000001c
                 75ad6f54: ole32!CoTaskMemFree+0x00000013
                 758e154c: RPCRT4!NdrFreeTypeMemory+0x00000046
                 758d24a9: RPCRT4!NdrPointerFree+0x000000a8
                 7594555e: RPCRT4!NdrpFreeParams+0x00000145
                 75945445: RPCRT4!NdrStubCall2+0x000004e0
                 75bbaec1: ole32!CStdStubBuffer_Invoke+0x0000003c
                 75bbd876: ole32!SyncStubInvoke+0x0000003c
                 75bbddd0: ole32!StubInvoke+0x000000b9
                 75ad8a43: ole32!CCtxComChnl::ContextInvoke+0x000000fa
                 75ad8938: ole32!MTAInvoke+0x0000001a
                 75bba44c: ole32!AppInvoke+0x000000ab
                 75bbdb41: ole32!ComInvokeWithLockAndIPID+0x00000372
                 75bbe1fd: ole32!ComInvoke+0x000000c5
                 75ad9367: ole32!ThreadDispatch+0x00000023
 NtGlobalFlag enables following debugging aids for new heaps:    tail checking
     free checking
     validate parameters
 Index   Address  Name      Debugging options enabled
   1:   003a0000                 tail checking free checking validate parameters
   2:   00010000                 tail checking free checking validate parameters
   3:   00670000                 tail checking free checking validate parameters
   4:   00650000                 tail checking free checking validate parameters
   5:   005f0000                 tail checking free checking validate parameters
   6:   02500000                 tail checking free checking validate parameters
   7:   024d0000                 tail checking free checking validate parameters
   8:   03e30000                 tail checking free checking validate parameters
   9:   03d60000                 tail checking free checking validate parameters
  10:   024f0000                 tail checking free checking validate parameters


And the !analyze -v ====================================

FAULTING_IP:
ntdll!RtlReportCriticalFailure+29
 773137dd cc              int     3

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
 ExceptionAddress: 773137dd (ntdll!RtlReportCriticalFailure+0x00000029)
    ExceptionCode: 80000003 (Break instruction exception)
   ExceptionFlags: 00000000
 NumberParameters: 3
    Parameter[0]: 00000000
    Parameter[1]: 84d79d48
    Parameter[2]: 056cee5d

FAULTING_THREAD:  00000be4

PROCESS_NAME:  TestCOMListView.exe

ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION}  Breakpoint  A breakpoint has been reached.

EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - One or more arguments are invalid

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  84d79d48

EXCEPTION_PARAMETER3:  056cee5d

MOD_LIST: <ANALYSIS/>

NTGLOBALFLAG:  70

APPLICATION_VERIFIER_FLAGS:  0

LAST_CONTROL_TRANSFER:  from 7731473b to 773137dd

DEFAULT_BUCKET_ID:  ACTIONABLE_HEAP_CORRUPTION_heap_failure_invalid_argument

PRIMARY_PROBLEM_CLASS:  ACTIONABLE_HEAP_CORRUPTION_heap_failure_invalid_argument

BUGCHECK_STR:  APPLICATION_FAULT_ACTIONABLE_HEAP_CORRUPTION_heap_failure_invalid_argument

STACK_TEXT:
056cf128 7731473b c0000374 7732cdd8 056cf16c ntdll!RtlReportCriticalFailure+0x29
 056cf138 7731481b 00000002 723f5340 00000000 ntdll!RtlpReportHeapFailure+0x21
 056cf16c 772cddff 00000009 003a0000 0041185c ntdll!RtlpLogHeapFailure+0xa1
 056cf19c 75ad6e6a 003a0000 00000000 0041185c ntdll!RtlFreeHeap+0x64
 056cf1b0 75ad6f54 75bc66bc 0041185c 056cf1dc ole32!CRetailMalloc_Free+0x1c
 056cf1c0 758e154c 0041185c 758d24d3 637733e8 ole32!CoTaskMemFree+0x13
 056cf1c8 758d24d3 637733e8 637733ec 056cf24c RPCRT4!NdrFreeTypeMemory+0x46
 056cf1dc 758d24a9 0041185c 0041185c 637733ec RPCRT4!NdrPointerFree+0xf3
 056cf1fc 7594555e 0041185c 056cf428 007733e8 RPCRT4!NdrPointerFree+0xa8
 056cf220 75945445 056cf428 00000002 6377318a RPCRT4!NdrpFreeParams+0x145
 056cf234 759453ff e1818bfa 00412560 0040f100 RPCRT4!NdrStubCall2+0x4e0
 056cf630 75bbaec1 00412560 00402fa8 0040f100 RPCRT4!NdrStubCall2+0x415
 056cf678 75bbd876 00412560 0040f100 00402fa8 ole32!CStdStubBuffer_Invoke+0x3c
 056cf6c0 75bbddd0 0040f100 0041325c 00411a48 ole32!SyncStubInvoke+0x3c
 056cf70c 75ad8a43 0040f100 00412160 00412560 ole32!StubInvoke+0xb9
 056cf7e8 75ad8938 00402fa8 00000000 00412560 ole32!CCtxComChnl::ContextInvoke+0xfa
 056cf804 75bba44c 0040f100 00000001 00412560 ole32!MTAInvoke+0x1a
 056cf834 75bbdb41 d0908070 00402fa8 00412560 ole32!AppInvoke+0xab
 056cf914 75bbe1fd 0040f0a8 00403b78 00000000 ole32!ComInvokeWithLockAndIPID+0x372
 056cf93c 75ad9367 0040f0a8 76fdc2b0 0040f258 ole32!ComInvoke+0xc5
 056cf950 75aacd48 0040f0a8 00000000 0040f258 ole32!ThreadDispatch+0x23
 056cf96c 75aad87a 00000000 00000000 056cf988 ole32!CRpcThread::WorkerLoop+0x26
 056cf97c 76fded6c 0040f258 056cf9c8 772b377b ole32!CRpcThreadCache::RpcWorkerThreadEntry+0x16
 056cf988 772b377b 0040f258 723f5be4 00000000 kernel32!BaseThreadInitThunk+0xe
 056cf9c8 772b374e 75aad864 0040f258 00000000 ntdll!__RtlUserThreadStart+0x70
 056cf9e0 00000000 75aad864 0040f258 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  .cxr 00000000 ; kb ; !heap ; dt ntdll!LdrpLastDllInitializer BaseDllName ; dt ntdll!LdrpFailureData ; ~7s ; kb

FOLLOWUP_IP:
RPCRT4!NdrFreeTypeMemory+46
 758e154c c3              ret

SYMBOL_STACK_INDEX:  6

SYMBOL_NAME:  rpcrt4!NdrFreeTypeMemory+46

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: RPCRT4

IMAGE_NAME:  RPCRT4.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  4ce7b9a2

FAILURE_BUCKET_ID:  ACTIONABLE_HEAP_CORRUPTION_heap_failure_invalid_argument_80000003_RPCRT4.dll!NdrFreeTypeMemory

BUCKET_ID:  APPLICATION_FAULT_ACTIONABLE_HEAP_CORRUPTION_heap_failure_invalid_argument_rpcrt4!NdrFreeTypeMemory+46

WATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/TestCOMListView_exe/1_0_0_1/4f56cbbc/ntdll_dll/6_1_7601_17725/4ec49b60/80000003/000c37dd.htm?Retriage=1

Followup: MachineOwner
 ---------


Call stack=================================

0:007> k
 ChildEBP RetAddr
056cf128 7731473b ntdll!RtlReportCriticalFailure+0x29
 056cf138 7731481b ntdll!RtlpReportHeapFailure+0x21
 056cf16c 772cddff ntdll!RtlpLogHeapFailure+0xa1
 056cf19c 75ad6e6a ntdll!RtlFreeHeap+0x64
 056cf1b0 75ad6f54 ole32!CRetailMalloc_Free+0x1c
 056cf1c0 758e154c ole32!CoTaskMemFree+0x13
 056cf1c8 758d24d3 RPCRT4!NdrFreeTypeMemory+0x46
 056cf1dc 758d24a9 RPCRT4!NdrPointerFree+0xf3
 056cf1fc 7594555e RPCRT4!NdrPointerFree+0xa8
 056cf220 75945445 RPCRT4!NdrpFreeParams+0x145
 056cf234 759453ff RPCRT4!NdrStubCall2+0x4e0
 056cf630 75bbaec1 RPCRT4!NdrStubCall2+0x415
 056cf678 75bbd876 ole32!CStdStubBuffer_Invoke+0x3c
 056cf6c0 75bbddd0 ole32!SyncStubInvoke+0x3c
 056cf70c 75ad8a43 ole32!StubInvoke+0xb9
 056cf7e8 75ad8938 ole32!CCtxComChnl::ContextInvoke+0xfa
 056cf804 75bba44c ole32!MTAInvoke+0x1a
 056cf834 75bbdb41 ole32!AppInvoke+0xab
 056cf914 75bbe1fd ole32!ComInvokeWithLockAndIPID+0x372
 056cf93c 75ad9367 ole32!ComInvoke+0xc5
 056cf950 75aacd48 ole32!ThreadDispatch+0x23
 056cf96c 75aad87a ole32!CRpcThread::WorkerLoop+0x26
 056cf97c 76fded6c ole32!CRpcThreadCache::RpcWorkerThreadEntry+0x16
 056cf988 772b377b kernel32!BaseThreadInitThunk+0xe
 056cf9c8 772b374e ntdll!__RtlUserThreadStart+0x70
 056cf9e0 00000000 ntdll!_RtlUserThreadStart+0x1b

推荐答案

不要在客户端中分配pProcName

您正在该指针之上执行SysAlloc
don''t allocate pProcName in the client

You''re doing a SysAlloc on top of that pointer


将此参数更改为该propget函数的BSTR *即可解决此问题.但不清楚为什么会这样.....

COM做任何发布工作都不同吗?
Change the parameter to BSTR* of this propget function can resolvs the issue. but not clear why this happens.....

Is COM doing anything release works differently?
STDMETHODIMP CExProcessInfo::get_m_ProcessName(BSTR* pVal)
{
	// TODO: Add your implementation code here
	if(m_pProcessName == NULL)
          *pVal = ::SysAllocString(L"");
	else
	{
	  *pVal = ::SysAllocString(m_pProcessName);
	}
	return S_OK;
}



当我搜索MSDN时,发现BSTR的评论是:

如果将简单的Unicode字符串作为期望BSTR的COM函数的参数传递,则COM函数将失败.

因此,在使用SysAllocString时,应将pVal作为带有长度前缀的BSTR返回.否则,内存将无法正确回收并导致堆崩溃.

参考链接: http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms221069(v = vs.85).aspx [



As i searched MSDN, found that BSTR''s remark:

If you pass a simple Unicode string as an argument to a COM function that is expecting a BSTR, the COM function will fail.

So when using SysAllocString, the pVal should be returned as a BSTR which with length prefix. If not, the memory will not be recycled properly and cause the heap crash.

Reference Link: http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx[^]


这篇关于导致堆失败的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆