Cpp2IL
Cpp2IL copied to clipboard
Exception handling
Not sure how much you've looked into this but I made a standalone prototype that attempts reconstructs exception handling semantics from x64 binaries compiled with vs2019. Seems to work pretty good except for some jank at the end where the compiler inserts the code for explicit null throwers and the like.
Code is here: https://github.com/ZingBallyhoo/Cpp2IL/blob/read-exception-info/ReadExceptionInfo/Program.cs
good resources: https://www.youtube.com/watch?v=COEv2kq_Ht8 https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/ ehdata4_export.h from MSVC includes https://reactos.org/wiki/Techwiki:SEH64 for vs2017 abi and earlier http://www.uninformed.org/?v=4&a=1&t=pdf https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-160
public int TryCatchTwo()
{
try
{
throw new Exception();
return 1;
} catch (ArgumentException)
{
return 100;
} catch (Exception)
{
return 0;
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchtwo-asm
public int TryCatchThree()
{
try
{
throw new Exception();
return 1;
} catch (ArgumentException)
{
return 100;
} catch (ObjectDisposedException)
{
return 101;
} catch (Exception)
{
return 0;
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchthree-asm
public int TryCatchFilter()
{
try
{
throw new Exception("msg");
} catch (Exception e) when (e.Message == "msg2")
{
return 100;
} catch (Exception)
{
return 101;
}
// should be unreachable
return 102;
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchfilter-asm the translator can't deal with mixing filtered and non-filtered handlers https://forum.unity.com/threads/catching-exception-with-when-clause-will-not-work-as-expected-when-using-il2cpp.989260/ https://www.jacksondunstan.com/articles/4702
public int TryCatchFinally()
{
int myLocal = 100;
try
{
throw new Exception("msg");
} catch (Exception e)
{
return myLocal;
} finally
{
myLocal = 5;
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchfinally-asm
public int TryCatchNested()
{
try
{
try
{
throw new Exception();
return 1;
} catch
{
throw new ArgumentException();
return 2;
}
} catch
{
return 3;
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchnested-asm
public void TryMultiple()
{
try
{
Console.Out.WriteLine("one");
} catch
{
}
Console.Out.WriteLine("inbetween");
try
{
Console.Out.WriteLine("two");
} catch
{
Console.Out.WriteLine("caught two");
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trymultiple-asm
public int TryCatchMultipleNested()
{
try
{
try
{
Console.Out.WriteLine("one");
} catch
{
}
Console.Out.WriteLine("inbetween");
try
{
Console.Out.WriteLine("two");
} catch
{
Console.Out.WriteLine("caught two");
}
return 59;
} catch
{
return 3;
}
}
https://gist.github.com/ZingBallyhoo/f1162fa0b14d5abb47c6eaba22807ae7#file-trycatchmultiplenested-asm
I had very briefly looked at it and then thrown my hands up and told myself I'd look at it later. It's currently 1:30am so I won't check your code now, but I will take a look when I wake up and see about implementing it. Thanks for all your contributions!