“检测到 FatalExecutionEngineError”重新定义 String.Empty 后使用 Console.Writeline 时
我正在尝试(为了好玩)将 String.Empty
重新定义为单个空格“”。为什么这会破坏 CLR 框架?
信息:
运行时遇到了 致命错误。错误的地址 位于 0x5814b976,线程 0xf40 上。 错误代码为0x80131623。这 错误可能是 CLR 中的错误或 不安全或不可验证的部分 用户代码。此的常见来源 bug 包括用户编组错误 COM 互操作或 PInvoke,这可能 损坏堆栈。
如何重现:
class Program
{
static void Main()
{
typeof(string).GetField("Empty").SetValue(null, " ");
Console.WriteLine("{}", "");
}
}
I'm trying (for fun) to redefine String.Empty
to be a single space "". Why does this break the CLR framework?
Message:
The runtime has encountered a
fatal error. The address of the error
was at 0x5814b976, on thread 0xf40.
The error code is 0x80131623. This
error may be a bug in the CLR or in
the unsafe or non-verifiable portions
of user code. Common sources of this
bug include user marshaling errors for
COM-interop or PInvoke, which may
corrupt the stack.
How to reproduce:
class Program
{
static void Main()
{
typeof(string).GetField("Empty").SetValue(null, " ");
Console.WriteLine("{}", "");
}
}
如果我们查看该程序
,它将失败,并出现
FormatException
并显示错误消息输入字符串格式不正确
。但是,当我们在
Console.WriteLine
行之前插入typeof(string).GetField("Empty").SetValue(null, " ");
时,代码会失败它尝试查找该错误消息。如果我们查看完整的堆栈跟踪(包括“显示外部代码”),那么我们会看到代码在System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(string fileName = " mscorlib.resources")
处失败(注意mscorlib.resources 前面有空格)。原因是
ManifestBasedResourceGroveler
使用ResourceManager
的方法GetResourceFileName
来查找资源文件。在GetResourceFileName
中,我们使用StringBuilder
来构造文件名,StringBuilder
的构造函数以String.Empty
开头。If we look at the program
then it will fail with an
FormatException
with the error messageInput string was not in a correct format
.However when we insert
typeof(string).GetField("Empty").SetValue(null, " ");
before the line withConsole.WriteLine
then the code fails when it tries to look up that error message. If we look at the full stacktrace (including "Show external code") then we see that the code fails atSystem.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing(string fileName = " mscorlib.resources")
(notice the space in front of mscorlib.resources).The reason for this is that
ManifestBasedResourceGroveler
uses the metodeGetResourceFileName
ofResourceManager
to find the resource file. And inGetResourceFileName
we use aStringBuilder
to construct the filename and the constructor ofStringBuilder
starts withString.Empty
.