C# 优雅地捕获加载的动态库中发生的分段错误

C# 优雅地捕获加载的动态库中发生的分段错误,c#,segmentation-fault,C#,Segmentation Fault,我正在编写一个使用外部动态库的.NET4.5控制台应用程序,但我无法访问这些库的源代码。问题是,这些DLL可能会发出分段故障信号,当这种情况发生时,整个过程立即终止。我目前的解决方案是将这个依赖dll的代码作为一个单独的进程运行,然后检索结果,但我注意到这个解决方案不是很有效 为了说明我的问题,我制作了一个示例代码: #包括 __declspec(dllexport)无效错误(void) { 升起(SIGSEGV); } 使用系统; 使用System.Runtime.InteropServic

我正在编写一个使用外部动态库的.NET4.5控制台应用程序,但我无法访问这些库的源代码。问题是,这些DLL可能会发出分段故障信号,当这种情况发生时,整个过程立即终止。我目前的解决方案是将这个依赖dll的代码作为一个单独的进程运行,然后检索结果,但我注意到这个解决方案不是很有效

为了说明我的问题,我制作了一个示例代码:

#包括
__declspec(dllexport)无效错误(void)
{
升起(SIGSEGV);
}
使用系统;
使用System.Runtime.InteropServices;
名称空间控制台
{
班级计划
{
[DllImport(“segFault.dll”)]
外部静态无效错误();
静态void Main(字符串[]参数)
{
尝试
{
控制台。写入(“已启动”);
err();
控制台。写入线(“运行”);
}
捕获(例外情况除外)
{
Console.WriteLine(“异常:+ex.Message”);
}
}
}
}
有了这样的设置,我将永远不会到达“正在运行”或“异常:”代码,因为整个过程将在到达segfault信号时终止。 我曾试图搞乱应用程序域,但也没有取得任何成功

使用系统;
使用System.Linq;
使用System.Runtime.InteropServices;
名称空间控制台
{
班级计划
{
[DllImport(“segFault.dll”)]
外部静态无效错误();
静态void Main(字符串[]参数)
{
如果(!args.Any())
{
AppDomain.CreateDomain(“testdomain”)
.ExecuteAssemblyByName(“ConsoleApp”、“1”);
Console.ReadKey();
}
尝试
{
控制台。写入(“已启动”);
err();
控制台。写入线(“运行”);
}
捕获(例外情况除外)
{
Console.WriteLine(“异常:+ex.Message”);
}
}
}
}
我还尝试使用一个简单的包装器来桥接p/Invoke执行,然后动态地将该包装器加载到主可执行文件,但没有成功

//Bridge.dll
使用System.Runtime.InteropServices;
名称空间桥
{
公共静态类桥梁
{
[DllImport(“segFault.dll”)]
公共静态外部无效错误();
}
}
//主可执行文件
使用制度;
运用系统反思;
名称空间控制台
{
班级计划
{
静态void Main(字符串[]参数)
{
Assembly.Load(“Bridge”).GetType(“Bridge.Bridge”)
.GetMethod(“err”).Invoke(null,null);
Console.WriteLine(“此代码将不执行”);
}
}
}

您可以尝试为
SIGSEGV
安装自定义处理程序,例如所述,但您必须知道自己在做什么
SIGSEGV
意味着进程的未老化内存可能“损坏”,因此整个应用程序甚至运行时可能处于损坏/未定义状态。@dymanoid遗憾的是,这个答案都是关于使用C语言捕获segfault信号,我没有能力修改我的DLL,因此我需要在C语言中注意这一点。您仍然可以创建一个小型本机模块,并在不接触DLL的情况下加载到应用程序中。SIGSEGV的
SIGSEGV
是在流程级别处理的,而不是在模块级别处理的。能否请您进一步阐述该主题?如何将已编译的C++ DLL打包成模块,用C?汇编程序执行它?只需创建一个新的本机模块,使用我引用的答案中的代码(它为整个流程安装信号处理程序),然后在托管应用程序中使用P/Invoke调用该模块的“安装程序”函数。