Skip to content

AV in GetITypeInfoForMT #75035

Closed
Closed
@jkotas

Description

@jkotas

See #74977 (reply in thread) for context

[Inline Frame] coreclr.dll!InterlockedCompareExchangeT(ITypeInfo * volatile *) Line 4341
[Inline Frame] coreclr.dll!InterlockedCompareExchangeT(ITypeInfo * volatile *) Line 4375
[Inline Frame] coreclr.dll!InterlockedCompareExchangeT(ITypeInfo * volatile *) Line 4406
[Inline Frame] coreclr.dll!ComMethodTable::SetITypeInfo(ITypeInfo * pNew=0x000001efb0d30fe8) Line 3853
coreclr.dll!GetITypeInfoForMT(ComMethodTable * pMT=0x00007ffd575cf440, ITypeInfo * * ppTI=0x0000001d1d17c308) Line 805
coreclr.dll!DispatchEx_GetTypeInfo(IDispatch * pDisp=0x0000001d1d17c258, unsigned int pptinfo=0x0000001d1d17c308, unsigned long) Line 1547
coreclr.dll!DispatchEx_GetTypeInfo_CallBack(void * ptr=0x0000001d1d17c258) Line 1281
coreclr.dll!DispatchEx_GetTypeInfo_Wrapper(IDispatchEx * pDisp=0x00000230477a6740, unsigned int itinfo=0x00000000, unsigned long lcid=0x00000000, ITypeInfo * * pptinfo=0x0000001d1d17c308) Line 1306
jscript.dll!JAmsi::JAmsiProcessor()
jscript.dll!VAR::InvokeByDispID()
jscript.dll!NameTbl::InvokeInternal()
jscript.dll!VAR::InvokeByDispID()
jscript.dll!CScriptRuntime::Run(class VAR *)
jscript.dll!ScrFncObj::PerformCall(class CScriptRuntime *,class VAR *,int,class VAR *,class VAR *,unsigned long)
jscript.dll!ScrFncObj::CallWithFrameOnStack(class VAR *,int,class VAR *,class VAR *,unsigned long)
jscript.dll!ScrFncObj::Call()
jscript.dll!JsEval()
jscript.dll!NatFncObj::Call()
jscript.dll!NameTbl::InvokeInternal()
jscript.dll!VAR::InvokeByDispID()
jscript.dll!CScriptRuntime::Run(class VAR *)
jscript.dll!ScrFncObj::PerformCall(class CScriptRuntime *,class VAR *,int,class VAR *,class VAR *,unsigned long)
jscript.dll!ScrFncObj::CallWithFrameOnStack(class VAR *,int,class VAR *,class VAR *,unsigned long)
jscript.dll!ScrFncObj::Call()
jscript.dll!CSession::Execute(class NameTbl *,struct tagVARIANT *,int,struct tagVARIANT *,struct tagVARIANT *,unsigned long)
jscript.dll!COleScript::ExecutePendingScripts()
jscript.dll!COleScript::ParseScriptTextCore()
jscript.dll!COleScript::ParseScriptText(unsigned short const *,unsigned short const *,struct IUnknown *,unsigned short const *,unsigned __int64,unsigned long,unsigned long,struct tagVARIANT *,struct tagEXCEPINFO *)

The debugger is pointing at the following source line in ...\src\coreclr\inc\utilcode.h

    template <typename T>
    inline T* InterlockedCompareExchangeT(
        T* volatile * destination,
        T*            exchange,
        T*            comparand)
    {
        //STATIC_ASSERT(exchange == 0);
        typedef typename std::remove_const<T>::type * non_const_ptr_t;
-->     return reinterpret_cast<T*>(InterlockedCompareExchangePointer(
            reinterpret_cast<PVOID volatile *>(const_cast<non_const_ptr_t volatile *>(destination)),
            reinterpret_cast<PVOID>(const_cast<non_const_ptr_t>(exchange)),
            reinterpret_cast<PVOID>(const_cast<non_const_ptr_t>(comparand))));
    }

Here's what the disassembler has to say:

    // Returns a NON-ADDREF'd ITypeInfo.
    HRESULT GetITypeInfoForMT(ComMethodTable *pMT, ITypeInfo **ppTI)
    {
     mov         r11,rsp  
     mov         qword ptr [r11+10h],rbx  
     mov         qword ptr [r11+18h],rsi  
     push        rdi  
     sub         rsp,20h  
        CONTRACTL
        {
            NOTHROW;
            GC_TRIGGERS;
            MODE_PREEMPTIVE;
            PRECONDITION(CheckPointer(pMT));
            PRECONDITION(CheckPointer(ppTI));
        }
        CONTRACTL_END;

        HRESULT     hr = S_OK;              // A result.
        ITypeInfo   *pTI;                   // The ITypeInfo.

        pTI = pMT->GetITypeInfo();
     mov         rax,qword ptr [rcx+28h]  
     xor         edi,edi  
     mov         qword ptr [r11+8],rax  
     mov         rsi,rdx  
     mov         rbx,rcx  
     test        rax,rax  

        if (pTI == NULL)
     jne         GetITypeInfoForMT+64h (07FFDB740A954h)  
        {
            MethodTable *pClass = pMT->GetMethodTable();

            hr = GetITypeInfoForEEClass(pClass, &pTI);
     mov         rcx,qword ptr [rcx+8]  
     lea         rdx,[r11+8]  
     xor         r8d,r8d  
     call        GetITypeInfoForEEClass (07FFDB7409A70h)  
     mov         edi,eax  

            if (SUCCEEDED(hr))
     test        eax,eax  
     js          GetITypeInfoForMT+5Fh (07FFDB740A94Fh)  
            {
                pMT->SetITypeInfo(pTI);
     mov         rcx,qword ptr [pTI]  
     xor         eax,eax  
-->  lock cmpxchg qword ptr [rbx+28h],rcx  
     jne         GetITypeInfoForMT+4Fh (07FFDB740A93Fh)  
     call        SafeAddRef (07FFDB711731Ch)  
                SafeReleasePreemp(pTI);
     mov         rcx,qword ptr [pTI]  
     call        SafeReleasePreemp (07FFDB7119290h)  
                pTI = pMT->GetITypeInfo();
     mov         rax,qword ptr [rbx+28h]  
     jmp         GetITypeInfoForMT+64h (07FFDB740A954h)  

            if (SUCCEEDED(hr))
     mov         rax,qword ptr [pTI]  
            }
        }

        *ppTI = pTI;
        return hr;
    }
     mov         rbx,qword ptr [rsp+38h]  
     mov         qword ptr [rsi],rax  
     mov         eax,edi  
     mov         rsi,qword ptr [rsp+40h]  
     add         rsp,20h  
     pop         rdi  
     ret  

Just for completeness, [rbx+28h] is pointing at two consecutive 64-bit nulls followed by other data.

One other bit: The debugger indicates that the access violation is due to an invalid write.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions