How can a simple string comparison cause an OleException?

点点圈 提交于 2019-12-11 18:46:47

问题


I have this piece of C++ code:

static CString timeout(_T("TIMEOUT"));
if(strError.Left(7).CompareNoCase(timeout) == 0) return TRUE;

In my immediate windows, I see following value for strError:

? strError
L""
ATL::CSimpleStringT<wchar_t,1>: L""

I'm getting following exception (I'm debugging a crash dump):

Unhandled exception at 0x74B4A9F2 in CRASH.DMP: Microsoft C++ exception: 
COleException at memory location 0x01BFFD14. occurred

My call stack is the following:

   KERNELBASE.dll!_RaiseException@16()  Unknown
   msvcr110.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 152  C++
   mfc110u.dll!AfxThrowOleException(long)   Unknown
   mfc110u.dll!ATL::AtlThrowImpl(long)  Unknown
   mfc110u.dll!ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >::CompareNoCase(wchar_t const *)  Unknown
>  <Application>.exe!<Own_Class>::<Own_Function>(const ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > & strError) Line 106 C++

As I was having a crash while checking .Left(7) of an empty string, I immediately assumed this was the course of the issue. However I've realised that this piece of code generally is working fine (I just double-checked this), and while having a second look, I see that the exception if not an access violation or a nullpointerexception, but an Ole related exception. In the meanwhile I've understood that the issue's not within the strError.Left(7) part: it seems to be the CompareNoCase() method, going wrong, but how?

Can anybody enlighten me what's doing wrong in my code?

As far as strError is concerned, it gets created as follows:

CString strError;
...
strError = <function>();

where <function>() is something like:

CString <function>(){
...
  return _T("fix string"); // or:
  return <Complicated_function_handling>();

In this particular case, I have no idea how strError has been created (I know it's empty, as clearly seen in the immediate window, but I only have the crash dump, so I can read current values, but I don't know their history).

One thing, which might be helpful: I've asked for the memory address of strError, and I've looked at the data within memory (using Visual Studio Memory debug window), and I get following data:

5c 18 9c 71 38 d9 ca 00 03 00 00 00 cc 3d c2 00 70 fe bf 01 94 13 b3 00 39 00 00 00 80 fe bf 01 be 58 aa 00 b0 3d c2 00 10 0c cd 00 44 03 00 00 01 00 00 00 d3 5f ac 00 8a 40 1d 72 8e f2 d6 73

Thanks in advance


回答1:


Working my thru the source for MFC, the exception is being thrown because timeOut is a NULL string. Common ways that this can happen are if it has not been constructed yet, or it has been destroyed. The error code stored within the COleException is E_FAIL.

The call sequence goes something like this:

  • CompareNoCase calls AtlIsValidString (which will return false in your case if timeOut, when converted to a const char *, is NULL).
  • Since AtlIsValidString returns false, the code associated with the ATLENSURE macro calls AtlThrow(E_FAIL) (AtlThrow is a macro that is defined as ATL::AtlThrowImpl.
  • AtlThrowImpl calls AfxThrowOleException since the error code is not E_OUTOFMEMORY.


来源:https://stackoverflow.com/questions/54666981/how-can-a-simple-string-comparison-cause-an-oleexception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!