gpt4 book ai didi

c# - 使用 Reflection.Emit 创建的动态程序集崩溃,退出代码为 -532462766

转载 作者:行者123 更新时间:2023-11-30 16:11:00 25 4
gpt4 key购买 nike

我一直在关注this article生成动态程序集如下:

var directory = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
var file = new FileInfo(Path.Combine(directory.FullName, @"MyDynamicAssembly.exe"));

var domain = AppDomain.CurrentDomain;
var name = new AssemblyName("Namespace.With.Dots");
var builderAssembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, directory.FullName);
var builderModule = builderAssembly.DefineDynamicModule("Namespace.With.Dots.Temp.exe");
var builderType = builderModule.DefineType("Program", TypeAttributes.Class | TypeAttributes.Public, typeof(object));
var builderMethod = builderType.DefineMethod("Main", MethodAttributes.Private | MethodAttributes.Static, typeof(int), new Type [] { typeof(string []) });

var generator = builderMethod.GetILGenerator();
generator.Emit(OpCodes.Ldstr, "Hello, World!");
generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type [] { typeof(string) }));
generator.EmitWriteLine("Hello again.");
generator.Emit(OpCodes.Ldc_I4, 0);
generator.Emit(OpCodes.Ret);

builderAssembly.SetEntryPoint(builderMethod, PEFileKinds.ConsoleApplication);
builderAssembly.Save(file.Name, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);

var process = Process.Start(file.FullName); // Crashes with image below.
var result = process.WaitForExit();
var exitCode = process.ExitCode; // -532462766.

以下是我对上述代码的了解:

  • 它正在创建一个动态程序集作为仅保存。
  • 程序集名称、模块名称和输出 PE 名称都不同(我假设这不是问题)。
  • 它创建一个名为 Program 的公共(public)静态类。
  • 它在此类中创建一个带有签名 private static int Main (string []) 的方法。
  • 它将此方法设置为入口点并将程序集配置为控制台应用程序。
  • 它将程序集编写为与处理器架构无关的 ILOnly。
  • 它将程序集镜像配置为我正在运行的 i386(带有 Intel 处理器的 Win7 32 位)。

方法:

  • 将字符串文字引用压入堆栈。
  • 使用从堆栈中获取的参数调用 Console.WriteLine
  • 使用 EmitWriteLine 再次调用 Console.WriteLine
  • 将 0 作为 Int32 插入堆栈作为返回值。
  • 返回。

崩溃:

忽略图像上的文件名。根据上面的代码,它将是 MyDynamicAssembly.exeApp crash info

任何关于这里出了什么问题的指示都将不胜感激。

最佳答案

除此之外,您还有更多艰巨的调试工作要做。您基本上只会得到两个退出代码。 -532462766 或 0xe0434352 是臭名昭著的“CCR”异常。 CLR 在尝试加载程序集时死机,无法执行正常的异常处理逻辑。在尝试在单独的进程中独立运行它之前,您当然希望通过在进程中对其进行测试来确保生成的 IL 是正确的。这样您至少可以使用调试器。

另一个是-532459699或0xe0434f4d,正常的“COM”异常。当代码抛出普通 .NET 异常并且由于缺少 try/catch 且没有 AppDomain.UnhandledException 事件处理程序而未处理时生成。您将不得不在没有堆栈跟踪的情况下凑合,并且只能使用 this answer 中的提示对抛出异常的位置进行反向工程。 .

当然,这是非常惩罚性的故障排除,您基本上不会想要这样做。至少考虑将代码加载到另一个 AppDomain 中,以便您有机会生成诊断并恢复。它仍然可以在另一个进程中通过编写一个小的“主机”程序来创建应用程序域并加载程序集并生成诊断。还为您提供了一种使用调试器的方法。

关于c# - 使用 Reflection.Emit 创建的动态程序集崩溃,退出代码为 -532462766,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24923914/

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