You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

coverlet无法检测模块(ArgumentException):部分项目覆盖率为0求助

Coverlet 3.2.0无法检测部分.NET Core 3.1项目,覆盖率为0(GuidHeap数组越界错误)

问题概述

解决方案中部分项目的单元测试可正常执行,但覆盖率始终为0;其余项目配置一致却能正常生成覆盖率数据。

环境配置

  • coverlet: 3.2.0
  • xUnit: 2.4.2
  • MSFT.Net.Test.SDK: 16.6.1
  • .NET Core 3.1

测试执行命令

dotnet.exe test c:\TestProject.csproj --collect "XPlat Code Coverage" --results-directory C:\CodeCoverage --configuration Release

诊断日志中的错误信息

启用--diag后,日志输出以下关键错误:

[coverlet]Unable to instrument module: C:\Development\EBH\RefreshAPI\src\EBillingHub.InvoiceExtraction.Business.Logic.Tests.Unit\bin\Release\netcoreapp3.1\EBillingHub.InvoiceExtraction.Business.Logic.dll 
System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. 
at System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count) 
at Mono.Cecil.Metadata.GuidHeap.Read(UInt32 index) 
at Mono.Cecil.MetadataReader.InitializeCustomDebugInformations() 
at Mono.Cecil.MetadataReader.GetCustomDebugInformation(ICustomDebugInformationProvider provider) 
at Mono.Cecil.Cil.PortablePdbReader.ReadModule() 
at Mono.Cecil.Cil.PortablePdbReader.ProcessDebugHeader(ImageDebugHeader header) 
at Mono.Cecil.ModuleDefinition.ReadSymbols(ISymbolReader reader, Boolean throwIfSymbolsAreNotMaching) 
at Mono.Cecil.ModuleReader.ReadSymbols(ModuleDefinition module, ReaderParameters parameters) 
at Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters) 
at Mono.Cecil.ModuleDefinition.ReadModule(Disposable1 stream, String fileName, ReaderParameters parameters) 
at Mono.Cecil.ModuleDefinition.ReadModule(Stream stream, ReaderParameters parameters) 
at Coverlet.Core.Instrumentation.Instrumenter.CreateReachabilityHelper() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 203 
at Coverlet.Core.Instrumentation.Instrumenter.InstrumentModule() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 209 
at Coverlet.Core.Instrumentation.Instrumenter.Instrument() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 153 
at Coverlet.Core.Coverage.PrepareModules() in //src/coverlet.core/Coverage.cs:line 135 

TpTrace Warning: 0 : 22036, 1, 2023/03/16, 17:52:05.273, 364420612049, datacollector.dll, 
[coverlet]Unable to instrument module: C:\Development\EBH\RefreshAPI\src\EBillingHub.InvoiceExtraction.Business.Logic.Tests.Unit\bin\Release\netcoreapp3.1\EBillingHub.InvoiceExtraction.BusinessLogic.dll 
System.ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. 
at System.Buffer.BlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count) 
at Mono.Cecil.Metadata.GuidHeap.Read(UInt32 index) 
at Mono.Cecil.MetadataReader.InitializeCustomDebugInformations() 
at Mono.Cecil.MetadataReader.GetCustomDebugInformation(ICustomDebugInformationProvider provider) 
at Mono.Cecil.Cil.PortablePdbReader.ReadModule() 
at Mono.Cecil.Cil.PortablePdbReader.ProcessDebugHeader(ImageDebugHeader header) 
at Mono.Cecil.ModuleDefinition.ReadSymbols(ISymbolReader reader, Boolean throwIfSymbolsAreNotMaching) 
at Mono.Cecil.ModuleReader.ReadSymbols(ModuleDefinition module, ReaderParameters parameters) 
at Mono.Cecil.ModuleReader.CreateModule(Image image, ReaderParameters parameters) 
at Mono.Cecil.ModuleDefinition.ReadModule(Disposable1 stream, String fileName, ReaderParameters parameters) 
at Mono.Cecil.ModuleDefinition.ReadModule(Stream stream, ReaderParameters parameters) 
at Coverlet.Core.Instrumentation.Instrumenter.CreateReachabilityHelper() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 203 
at Coverlet.Core.Instrumentation.Instrumenter.InstrumentModule() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 209 
at Coverlet.Core.Instrumentation.Instrumenter.Instrument() in //src/coverlet.core/Instrumentation/Instrumenter.cs:line 153 
at Coverlet.Core.Coverage.PrepareModules() in //src/coverlet.core/Coverage.cs:line 135

关联Cecil代码分析

查看Mono.Cecil的GuidHeap实现,错误触发于Read方法的数组拷贝逻辑:

sealed class GuidHeap : Heap {
    public GuidHeap (byte [] data)
        : base (data)
    {
    }

    public Guid Read (uint index)
    {
        const int guid_size = 16;

        if (index == 0 || ((index - 1) + guid_size) > data.Length)
            return new Guid ();

        var buffer = new byte [guid_size];

        Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size);

        return new Guid (buffer);
    } 
}

判断逻辑虽做了边界检查,但实际执行时仍出现数组越界,推测是调试符号文件(pdb)中的GUID堆数据损坏或索引异常。

临时现象

修改项目名称并构建,再改回原名(不清理输出目录,保留两个不同名称的DLL),此时被重命名过的DLL可被正常检测并生成覆盖率数据。

可行解决办法

  1. 清理缓存后重新构建
    完全删除项目的bin和obj目录,重新执行构建和测试命令,解决旧缓存导致的pdb/DLL损坏问题。

  2. 升级coverlet版本
    coverlet 3.2.0存在与Mono.Cecil的兼容性问题,升级至3.2.x补丁版或更高稳定版本可修复该数组越界错误。

  3. 禁用Reachability分析
    创建coverlet.runsettings配置文件,禁用触发错误的Reachability分析功能:

    <RunSettings>
      <DataCollectionRunSettings>
        <DataCollectors>
          <DataCollector friendlyName="XPlat Code Coverage">
            <Configuration>
              <EnableReachabilityAnalysis>false</EnableReachabilityAnalysis>
            </Configuration>
          </DataCollector>
        </DataCollectors>
      </DataCollectionRunSettings>
    </RunSettings>
    

    执行测试时添加--settings coverlet.runsettings参数。

  4. 检查调试符号配置
    确保Release模式下项目生成完整的可移植调试符号,在项目文件中显式配置:

    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
      <DebugType>portable</DebugType>
      <DebugSymbols>true</DebugSymbols>
    </PropertyGroup>
    

内容的提问来源于stack exchange,提问作者Siarhei Machel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:38:02