[marshal] Rethrow in native-to-managed wrapper to keep exception stacktrace (#5384)
[mono.git] / mono / tests / bug-58782-capture-and-throw.cs
1 using System;
2 using System.Runtime.InteropServices;
3
4 class Driver
5 {
6         [DllImport ("libtest")]
7         static extern void mono_test_native_to_managed_exception_rethrow (Action action);
8
9         [DllImport ("libc")]
10         static extern void _exit (int exitCode);
11
12         static int Main (string[] args)
13         {
14                 AppDomain.CurrentDomain.UnhandledException += (sender, exception_args) =>
15                 {
16                         CustomException exc = exception_args.ExceptionObject as CustomException;
17                         if (exc == null) {
18                                 Console.WriteLine ($"FAILED - Unknown exception: {exception_args.ExceptionObject}");
19                                 _exit (1);
20                         }
21
22                         Console.WriteLine (exc.StackTrace);
23                         if (string.IsNullOrEmpty (exc.StackTrace)) {
24                                 Console.WriteLine ("FAILED - StackTrace is null for unhandled exception.");
25                                 _exit (2);
26                         } else {
27                                 Console.WriteLine ("SUCCESS - StackTrace is not null for unhandled exception.");
28                                 _exit (0);
29                         }
30                 };
31
32                 mono_test_native_to_managed_exception_rethrow (CaptureAndThrow);
33                 Console.WriteLine ("Should have exited in the UnhandledException event handler.");
34                 return 2;
35         }
36
37         static void CaptureAndThrow ()
38         {
39                 try {
40                         Throw ();
41                 } catch (Exception e) {
42                         System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture (e).Throw ();
43                 }
44         }
45
46         static void Throw ()
47         {
48                 throw new CustomException ("C");
49         }
50
51         class CustomException : Exception
52         {
53                 public CustomException(string s) : base(s) {}
54         }
55 }