gpt4 book ai didi

tfs - 执行 TFS 构建时,MSBuild 不一致地失败(通常是错误 C1093/存储空间不足)

转载 作者:行者123 更新时间:2023-12-04 12:47:26 25 4
gpt4 key购买 nike

我有一个非常奇怪且难以诊断的 MSBuild/TFS 问题。我有一个包含大约 12 种不同构建配置的解决方案。在构建服务器上运行时,构建该批次可能需要 30 分钟,并且已经运行了数周,但现在偶尔会失败。

大多数时候,当它失败时,它会是这样的错误:

19:25:45.037 2>TestPlanDocument.cpp(1): fatal error C1093: API call 'GetAssemblyRefHash' failed '0x8007000e' : ErrorMessage: Not enough storage is available to complete this operation. [C:\Builds\1\ICCSim Card Test Controller\ICCSimCTC Release\src\CardTestController\CardTestController.vcxproj]



该错误有时会发生在不同的文件上。也不会对每个构建配置都发生这种情况,它非常不一致,有时甚至会成功构建所有配置。构建配置之间也没有太大区别,主要只是一些字符串更改,当然它们都可以在本地构建就好了。

有问题的 API 调用通常是 GetAssemblyRefHash但不总是。我不认为这是问题所在,因为谷歌搜索 GetAssemblyRefHash 几乎什么也没有。我怀疑这里存在某种资源问题,但我不知道是什么:有足够的 HDD 空间(数百 GB),足够的 RAM(机器最初分配的最小空间为 4GB,但由于它是 Hyper -v - 它从未超过 2.5GB。为了以防万一,我将其提高到最低 8GB,并且没有任何变化)。

我已将构建详细程度设置为诊断,但它并没有真正显示任何其他有用的内容,只是出现了相同的错误。

作为引用,构建服务器在所有补丁上都是最新的。它运行 Windows Server 2012 R2,安装了 TFS 2013 和 VS 2013,两者都在更新 4 上。

在这一点上我真的很茫然,希望得到任何帮助或指点。

编辑:只是为了让人们了解最新情况,编译工具链处于 32 位模式,但是即使切换到 64 位,问题仍然存在。

最佳答案

我想我找到了来源,但我仍然不知道原因。

浏览Microsoft Shared Source ,我们可以找到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);
}

这里只有两个地方需要调查 - 调用 m_pImports->GetFile() ,其中 m_pImportsCAssembly *m_pImports; ,另一个是 file->GetHash() .
m_pImports->GetFile()在这里,并且是一个死胡同:

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() ,这里是:

HRESULT CAssembly::GetHash(const void ** ppvHash, DWORD *pcbHash)
{
ASSERT( ppvHash && pcbHash);
if (IsInMemory()) {
// We can't hash an InMemory file
*ppvHash = NULL;
*pcbHash = 0;
return S_FALSE;
}

if (!m_bDoHash || (m_cbHash && m_pbHash != NULL)) {
*ppvHash = m_pbHash;
*pcbHash = m_cbHash;
return S_OK;
}

DWORD cchSize = 0, result;

// AssemblyRefs ALWAYS use CALG_SHA1
ALG_ID alg = CALG_SHA1;
if (StrongNameHashSize( alg, &cchSize) == FALSE)
return ReportError(StrongNameErrorInfo());

if ((m_pbHash = new BYTE[cchSize]) == NULL)
return ReportError(E_OUTOFMEMORY);
m_cbHash = cchSize;

if ((result = GetHashFromAssemblyFileW(m_Path, &alg, (BYTE*)m_pbHash, cchSize, &m_cbHash)) != 0) {
delete [] m_pbHash;
m_pbHash = 0;
m_cbHash = 0;
}
*ppvHash = m_pbHash;
*pcbHash = m_cbHash;

return result == 0 ? S_OK : ReportError(HRESULT_FROM_WIN32(result));
}

我们可以看到,大约进行到一半时,它尝试分配空间来存储 byte[] 结果,当失败时,返回 E_OUTOFMEMORY,这是您看到的错误代码:

if ((m_pbHash = new BYTE[cchSize]) == NULL)
return ReportError(E_OUTOFMEMORY);
m_cbHash = cchSize;

还有其他途径需要考虑,但这似乎是最明显的来源。所以看起来问题是普通的内存分配失败了。

什么可能导致这种情况?
  • 缺少可用的物理内存页/交换
  • 过程中出现内存碎片。
  • 无法在交换文件中为此保留提交空间
  • 地址空间不足

  • 在这一点上,我最好的猜测是内存碎片。您是否三重检查了 Microsoft CPP 编译器是否在 64 位模式下运行?也许看看您是否可以调试编译器(Microsoft 符号服务器可能会在这里帮助您),并为该行设置断点并在发生时转储堆。

    关于诊断堆碎片的一些细节 - 当编译器中断时启动 sysinternal 的 VMMap,并查看空闲列表 - 你需要 three chunks at least 64 kB free to perform an allocation ;小于 64 kB 并且不会被使用,并且保留两个 64 kB 块。

    关于tfs - 执行 TFS 构建时,MSBuild 不一致地失败(通常是错误 C1093/存储空间不足),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27533717/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com