编译生成.NET Core Framework遇到的问题

前两天在Windows Server 2012上编译生成.NET Core Framework的代码库corefx,遭遇了几个问题,在这篇博文中记录一下。

编译生成操作方法是在命令行(Developer Command Prompt for VS2014)中运行corefx中的build.cmd命令。

(一)

遇到的第1个问题[#560]是:"Err445! Got unexpected exception: System.IO.IOException: There is not enough space on the disk."

问题发生在 System.IO.MemoryMappedFiles\tests\MemoryMappedFile\CreateViewAccessor.cs 的第378行:

using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(
s_fileNameForLargeCapacity,
FileMode.Open,
"CVA_RunTestLargeCapacity",
capacity))

问题引发点:

// 2^31-1, 2^31, 2^31+1, 2^32-1, 2^32, 2^32+1
Int64[] capacities = { 2147483647, 2147483648, 2147483649, 4294967295, 4294967296, 4294967297 };

foreach (Int64 capacity in capacities)
{
    RunTestLargeCapacity(capacity);
}

出问题时,capacity的值是4294967296(4G)。

当时corefx代码库所在的硬盘分区剩余空间只有4.81G,后来将剩余空间增加至9.21G,问题消失。

(二)

遇到的第2个问题[#564]是:有时运行build.cmd之后,硬盘分区的卷标被修改为BCLTest。

 经过分析源代码,发现问题的引发点在 System.IO.FileSystem.DriveInfo\tests\GetVolumeLabelTests.cs 的97行:

for (int i = 0; i < drives.Length; i++)
{
    if (originalVolumeInfo.ContainsKey(drives[i].Name))
    {
        try
        {
            drives[i].VolumeLabel = (String)originalVolumeInfo[drives[i].Name];
        }
        catch (UnauthorizedAccessException) { }
    }
    //...
}

GetVolumeLabelTests在测试过程中会修改硬盘分区的卷标,修改之后会恢复原来的卷标。但如果在恢复过程中出现UnauthorizeAccessException异常(比如当前硬盘分区正在某些文件操作不允许修改卷标),硬盘分区卷标就会变成BCLTest而回不去了。

该问题可以通过下面的代码进行重现:

//Scenario 3: We will revert to the original volume value and check
for (int i = 0; i < drives.Length; i++)
{
    if (originalVolumeInfo.ContainsKey(drives[i].Name))
    {
        try
        {
            drives[i].VolumeLabel = (String)originalVolumeInfo[drives[i].Name];
            throw new UnauthorizedAccessException();
        }
        catch (UnauthorizedAccessException) { }
    }
    //...
}

(三)

遇到的第3个问题[#566]是运行Microsoft.Win32.Registry.Tests单元测试时出现“Error Key value is incorrect...”异常。

问题的引发点在 Microsoft.Win32.Registry\tests\RegistryKey\RegistryKey_GetValue_str_obj_regvalopt.cs:line 43:

try
{
    Object obj = _rk1.GetValue(null, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
    if (obj != null)
    {
        Assert.False(true, "Error Key value is incorrect...");
    }
}

当时obj的值是0。

在gitbuh上提交issue之后,根据 @stephentoub 的回复,找到了问题的原因,原来是注册表HKEY_CURRENT_USER中"(Default)"的值为0引起的。

删除该注册表项之后,Windows会自动创建空的"(Default)"。

之后,问题解决。

但是,后来过一段时间再看,HKEY_CURRENT_USER中"(Default)"的值又变为0,问题没有根本解决。

posted @ 2015-02-02 12:57 dudu 阅读(...) 评论(...) 编辑 收藏