Skip to content

[Profiler] duplicated ExceptionUnwindFunctionEnter/ExceptionUnwindFunctionLeave callbacks when exception is thrown from try-finally block. #123351

@alexanderqqq

Description

@alexanderqqq

Hi there,

Starting from .NET 9.0 profiler receives duplicated ExceptionUnwindFunctionEnter/ExceptionUnwindFunctionLeave callbacks for the same FunctionID when an exception is thrown from finally in try-finally block. This does not happen on .NET 8, where a single unwind enter/leave pair is reported for the function.

This behavior appears to contradict the current documentation for ExceptionUnwindFunctionLeave, which states that:

the function instance and its stack data are removed from the stack

(Documentation link is for .NET Framework, but it is the only official public reference we can find for these callbacks today.)

I suspect this is related to the new exception handling implementation, where finally is compiled as a separate funclet, but it is unclear whether this behavior is expected and should be observed by profilers, or whether unwind notifications for funclet-related transitions should be hidden. Also, profiler does not receive corresponding Enter/Leave callbacks for such funclets, and funclet frames are hidden from the runtime stackwalker, which makes the duplicated unwind notifications difficult to interpret.


Here is a simple example:

public static class Program
{
    public static void Main()
    {
        var demo = new Demo();

        try
        {
            demo.Foo();
        }
        catch (Exception ex)
        {
            Console.WriteLine("Caught in Main: " + ex.GetType().Name + " - " + ex.Message);
        }

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

public sealed class Demo
{
    public void Foo()
    {
        try
        {
            Console.WriteLine("Try");
        }
        finally
        {
            throw new OperationCanceledException("Thrown from finally");
        }
    }
}

.NET 10.0.100/9.0.9 x64, Windows 25H2 x64 26200.7623:

0000881C 1 00000255EF84E6F0 PTProf::ExceptionThrown oid=00000255F409EF78 cid=00007FF84D7418B8 cname='System.OperationCanceledException'
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionEnter fid=00007FF84D69F7E8 //Foo
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionLeave
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionEnter fid=00007FF84D69F7E8 //Foo
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionLeave
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionEnter fid=00007FF84D69E8F0 //Main
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchCatcherFound fid=00007FF84D69E8F0 //Main
0000881C 1 00000255EF84E6F0 PTProf::ExceptionSearchFunctionLeave
0000881C 1 00000255EF84E6F0 PTProf::ExceptionUnwindFunctionEnter fid=00007FF84D69F7E8 //Foo
0000881C 1 00000255EF84E6F0 PTProf::ExceptionUnwindFunctionLeave
0000881C 1 00000255EF84E6F0 PTProf::ExceptionUnwindFunctionEnter fid=00007FF84D69F7E8 //Foo 
0000881C 1 00000255EF84E6F0 PTProf::ExceptionUnwindFunctionLeave
0000881C 1 00000255EF84E6F0 PTProf::ExceptionUnwindFunctionEnter fid=00007FF84D69E8F0 //Main
0000881C 1 00000255EF84E6F0 PTProf::ExceptionCatcherEnter fid=00007FF84D69E8F0 //Main
0000881C 1 00000255EF84E6F0 PTProf::ExceptionCatcherLeave

.NET 8.0.20 x64, Windows 25H2 x64 26200.7623:

0000AD1C 1 000002045EF64980 PTProf::ExceptionThrown oid=00000204638BA868 cid=00007FF839F15B30 cname='System.OperationCanceledException'
0000AD1C 1 000002045EF64980 PTProf::ExceptionSearchFunctionEnter fid=00007FF839F14158 //Foo
0000AD1C 1 000002045EF64980 PTProf::ExceptionSearchFunctionLeave
0000AD1C 1 000002045EF64980 PTProf::ExceptionSearchFunctionEnter fid=00007FF839C97FA8//Main
0000AD1C 1 000002045EF64980 PTProf::ExceptionSearchCatcherFound fid=00007FF839C97FA8 //Main
0000AD1C 1 000002045EF64980 PTProf::ExceptionSearchFunctionLeave
0000AD1C 1 000002045EF64980 PTProf::ExceptionUnwindFunctionEnter fid=00007FF839F14158 //Foo
0000AD1C 1 000002045EF64980 PTProf::ExceptionUnwindFunctionLeave
0000AD1C 1 000002045EF64980 PTProf::ExceptionUnwindFunctionEnter fid=00007FF839C97FA8 //Main
0000AD1C 1 000002045EF64980 PTProf::ExceptionCatcherEnter fid=00007FF839C97FA8  //Main
0000AD1C 1 000002045EF64980 PTProf::ExceptionCatcherLeave

Metadata

Metadata

Assignees

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions