I think I found the source, but I still don't know the reason.
Looking through the Microsoft Shared Source , we can find the source for GetAssemblyRefHash()
:
HRESULT CAsmLink::GetAssemblyRefHash(mdToken FileToken, const void** ppvHash, DWORD* pcbHash) { if (TypeFromToken(FileToken) != mdtAssemblyRef) { VSFAIL( "You can only get AssemblyRef hashes for assemblies!"); return E_INVALIDARG; } HRESULT hr; CAssembly *file = NULL; if (FAILED(hr = m_pImports->GetFile( FileToken, (CFile**)&file))) return hr; return file->GetHash(ppvHash, pcbHash); }
Only two places to explore - call m_pImports->GetFile()
, where m_pImports
- CAssembly *m_pImports;
, the other is file->GetHash()
.
m_pImports->GetFile()
here, and this is a dead end:
HRESULT CAssembly::GetFile(DWORD index, CFile** file) { if (!file) return E_POINTER; if (RidFromToken(index) < m_Files.Count()) { if ((*file = m_Files.GetAt(RidFromToken(index)))) return S_OK; } return ReportError(E_INVALIDARG); }
file->GetHash()
, which is located here:
HRESULT CAssembly::GetHash(const void ** ppvHash, DWORD *pcbHash) { ASSERT( ppvHash && pcbHash); if (IsInMemory()) {
We see that about halfway there he is trying to allocate a place to store the result of byte [], and if it fails, returns E_OUTOFMEMORY, which is the error code that you see:
if ((m_pbHash = new BYTE[cchSize]) == NULL) return ReportError(E_OUTOFMEMORY); m_cbHash = cchSize;
There are other ways to consider, but this seems like the most obvious source. Thus, it seems that the problem is that simple memory allocation is not performed.
What could be the reason for this?
- Lack of free pages of physical memory / swap
- Fragmentation of memory in the process.
- Inability to reserve a commit location for this in the swap file
- Lack of address space
At this point, I think it will be a fragmentation of memory. Have you checked three times that the Microsoft CPP compiler works in 64-bit mode? Perhaps see if you can debug the compiler (Microsoft character servers can help you here) and set a breakpoint for this line and unload the heap when that happens.
Some features of heap fragmentation diagnostics - run sysinternal VMMap when the compiler breaks and see a free list - you need three pieces of at least 64 KB for free to perform the distribution ; less than 64 kbytes, and it will not be used, and two blocks of 64 KB are reserved.