Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With Faster Exceptions, exceptions thrown in some out-of-process COM calls raise AppDomain.CurrentDomain.UnhandledException #113367

Open
Molinarius opened this issue Mar 11, 2025 · 0 comments
Labels
area-ExceptionHandling-coreclr untriaged New issue has not been triaged by the area owner

Comments

@Molinarius
Copy link

Description

Probably starting with the faster exceptions of .NET 9, in an application that provides an out-of-process COM server, when a method that has been called from the COM client throws an exception, the first of these exceptions raises the event AppDomain.CurrentDomain.UnhandledException.

However, this happens only in some type of clients, my guess is clients that use IDispatch.

Reproduction Steps

  1. Get the out-of-process COM example from https://github.com/dotnet/samples/tree/main/core/extensions/OutOfProcCOM.

  2. Change the ExeServer project to use .NET9.

  3. In Program.cs of the project ExeServer, in Main, add these lines after the call of Trace.Listeners.Add:

    AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
        Trace.WriteLine($"CurrentDomain_UnhandledException: IsTerminating={e.IsTerminating}, {e.ExceptionObject}");
    Trace.WriteLine($"Environment.Version is {Environment.Version}, Is64BitProcess is {Environment.Is64BitProcess}.");
    Trace.WriteLine($"DOTNET_LegacyExceptionHandling is '{Environment.GetEnvironmentVariable("DOTNET_LegacyExceptionHandling")}'.");
    
  4. In ExeServer.cs, in the method double IServer.ComputePi(), add this line as second line:

    throw new OverflowException("This is not an actual overflow.");

  5. In the project ManagedClient in the file Program.cs, make these changes:

    • Replace the line var server = (IServer)obj; with dynamic server = obj;

    • Replace these lines:

      double pi = server.ComputePi();
      Console.WriteLine($"\u03C0 = {pi}");
      

      with:

      for (int i = 0; i < 3; i++)
      {
          try
          {
              double pi = server.ComputePi();
              Console.WriteLine($"\u03C0 = {pi}");
          }
          catch (Exception e)
          {
              Console.WriteLine(e.GetType() + " " + e.Message);
          }
      }
      
  6. Compile, COM register, and run ManagedClient as described in README.md.

  7. (Unregister when done.)

Expected behavior

AppDomain.CurrentDomain.UnhandledException is not raised.

Actual behavior

AppDomain.CurrentDomain.UnhandledException is raised, but only on the first exception.

Regression?

Yes. Works as expected with .NET 8, and works when setting the environment variable DOTNET_LegacyExceptionHandling to 1.

Known Workarounds

It currently seems to me that the call to UnhandledException has no side effects.

Therefore, I'm not sure if it actually might be a workaround to ignore such exceptions in handlers of UnhandledException, e.g. by somehow marking them.

Configuration

Windows 10 22H2.

.NET SDKs:

  • 9.0.200
  • 10.0.100-preview.1.25120.13

Other information

  • Same behavior with .NET 9 and .NET 10 preview.

  • I see the same behavior when using VB script, e.g.:

    ' Run with cscript
    set server = GetObject("new:{AF080472-F173-4D9D-8BE7-435776617347}")
    on error resume next
    Dim i
    For i = 1 To 3
        Dim result
        result = server.ComputePi()
    
        If Err.Number <> 0 Then
            WScript.Echo "Error: " & Err.Description
            Err.Clear
        Else
            WScript.Echo "result: " & result
        End If
    Next
    
  • When using PowerShell, both the Windows PowerShell and pwsh, I see the same behavior with other projects, however, with this example project, creating a COM object gives me the error Type library is not registered. (0x80131165), but I think this is a different topic.

  • I do not see this behavior with the NativeClient of this example project, and not with native clients using #import, and not with the unmodified ManagedClient of this example project.

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Mar 11, 2025
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Mar 11, 2025
@huoyaoyuan huoyaoyuan added area-ExceptionHandling-coreclr and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-ExceptionHandling-coreclr untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

2 participants