I'm writing a .NET 4.5 console application that use external dynamic libraries and I don't have access to the sources of those libraries. The problem is that those DLLs may raise a segmentation fault signal and when this happens, the whole process is immediately terminated. My current solution is to run this dll-dependent code as a separate process, and then retrieve the result, but I've noticed that this solution is not very efficient.
To illustrate my issue, I've made a sample code:
#include <signal.h>
__declspec(dllexport) void err(void)
{
raise(SIGSEGV);
}
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp
{
class Program
{
[DllImport("segFault.dll")]
extern static void err();
static void Main(string[] args)
{
try
{
Console.Write("started");
err();
Console.WriteLine("running");
}
catch(Exception ex)
{
Console.WriteLine("Exception:" + ex.Message);
}
}
}
}
With such setup, I'll never reach the "running" nor the "Exception:" code, because the whole process will be terminated while reaching the segfault signal. I have tried to mess with Application Domains but also without any great success.
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApp
{
class Program
{
[DllImport("segFault.dll")]
extern static void err();
static void Main(string[] args)
{
if (!args.Any())
{
AppDomain.CreateDomain("testdomain")
.ExecuteAssemblyByName("ConsoleApp", "1");
Console.ReadKey();
}
try
{
Console.Write("started");
err();
Console.WriteLine("running");
}
catch (Exception ex)
{
Console.WriteLine("Exception:" + ex.Message);
}
}
}
}
I have also tried to bridge the P/Invoke execution using a simple wrapper and then dynamically load that wrapper to the main executable, and also, without any success.
// Bridge.dll
using System.Runtime.InteropServices;
namespace Bridge
{
public static class Bridge
{
[DllImport("segFault.dll")]
public static extern void err();
}
}
// Main Executable
using System;
using System.Reflection;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Assembly.Load("Bridge").GetType("Bridge.Bridge")
.GetMethod("err").Invoke(null, null);
Console.WriteLine("This code will not execute");
}
}
}