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

[mono] Generic Default Interface Method crash with Environment.StackTrace #60486

Closed
bholmes opened this issue Oct 15, 2021 · 4 comments · Fixed by #60770, mono/mono#21356 or Unity-Technologies/mono#1551
Assignees
Labels
area-VM-meta-mono untriaged New issue has not been triaged by the area owner

Comments

@bholmes
Copy link
Contributor

bholmes commented Oct 15, 2021

Description

Calling Environment.StackTrace from a default interface method of a generic interface causes a crash in the Mono runtime.

Reproduction Steps

Compile and run the following program with the Mono runtime...

using System;

namespace DefItf
{
    public interface IPublisher<out TData>
    {
        event Action<TData> OnPublish;
    }

    public interface ISubscriber<T>
    {
        void OnReceiveSubscription(T data);

        void Subscribe(IPublisher<T> publisher)
        {
            InternalSubscribe(this, publisher);
        }

        void Unsubscribe(IPublisher<T> publisher)
        {
            InternalUnsubscribe(this, publisher);
        }

        protected static void InternalSubscribe(ISubscriber<T> subscriber, IPublisher<T> publisher)
        {
            publisher.OnPublish += subscriber.OnReceiveSubscription;
            Console.WriteLine(Environment.StackTrace.ToString());
        }

        protected static void InternalUnsubscribe(ISubscriber<T> subscriber, IPublisher<T> publisher)
        {
            publisher.OnPublish -= subscriber.OnReceiveSubscription;
            Console.WriteLine(Environment.StackTrace.ToString());
        }
    }

    public class PubTest :IPublisher<InputData>
    {
        public event Action<InputData> OnPublish;

        public void Call() => OnPublish?.Invoke(new InputData());
    }

    public class InputData
    {
        public int i;
    }

    public class Program : ISubscriber<InputData>
    {
        static void Main(string[] args)
        {
            new Program().Start();
        }
        
        // Start is called before the first frame update
        public void Start()
        {
            var pub = new PubTest();
            var sub = (ISubscriber<InputData>)this;
            sub.Subscribe(pub);
            pub.Call();
            sub.Unsubscribe(pub);
        }

        public void Subscribe(IPublisher<InputData> publisher)
        {
            ISubscriber<InputData>.InternalSubscribe(this, publisher);
        }

        public void OnReceiveSubscription(InputData data)
        {
            Console.WriteLine($"do something");
        }
    }
}

Expected behavior

Program completes without crashing and the output is written to the screen.

Actual behavior

Program crashes.

Regression?

Not a regression

Known Workarounds

No known workarounds.

Configuration

  • Tested with Mono runtime build from code, main branch 56d807d.
  • Verified on Windows and Linux x64

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Oct 15, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@danmoseley
Copy link
Member

Is it possible to share a stack trace?

@ghost
Copy link

ghost commented Oct 17, 2021

Tagging subscribers to this area:
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Calling Environment.StackTrace from a default interface method of a generic interface causes a crash in the Mono runtime.

Reproduction Steps

Compile and run the following program with the Mono runtime...

using System;

namespace DefItf
{
    public interface IPublisher<out TData>
    {
        event Action<TData> OnPublish;
    }

    public interface ISubscriber<T>
    {
        void OnReceiveSubscription(T data);

        void Subscribe(IPublisher<T> publisher)
        {
            InternalSubscribe(this, publisher);
        }

        void Unsubscribe(IPublisher<T> publisher)
        {
            InternalUnsubscribe(this, publisher);
        }

        protected static void InternalSubscribe(ISubscriber<T> subscriber, IPublisher<T> publisher)
        {
            publisher.OnPublish += subscriber.OnReceiveSubscription;
            Console.WriteLine(Environment.StackTrace.ToString());
        }

        protected static void InternalUnsubscribe(ISubscriber<T> subscriber, IPublisher<T> publisher)
        {
            publisher.OnPublish -= subscriber.OnReceiveSubscription;
            Console.WriteLine(Environment.StackTrace.ToString());
        }
    }

    public class PubTest :IPublisher<InputData>
    {
        public event Action<InputData> OnPublish;

        public void Call() => OnPublish?.Invoke(new InputData());
    }

    public class InputData
    {
        public int i;
    }

    public class Program : ISubscriber<InputData>
    {
        static void Main(string[] args)
        {
            new Program().Start();
        }
        
        // Start is called before the first frame update
        public void Start()
        {
            var pub = new PubTest();
            var sub = (ISubscriber<InputData>)this;
            sub.Subscribe(pub);
            pub.Call();
            sub.Unsubscribe(pub);
        }

        public void Subscribe(IPublisher<InputData> publisher)
        {
            ISubscriber<InputData>.InternalSubscribe(this, publisher);
        }

        public void OnReceiveSubscription(InputData data)
        {
            Console.WriteLine($"do something");
        }
    }
}

Expected behavior

Program completes without crashing and the output is written to the screen.

Actual behavior

Program crashes.

Regression?

Not a regression

Known Workarounds

No known workarounds.

Configuration

  • Tested with Mono runtime build from code, main branch 56d807d.
  • Verified on Windows and Linux x64

Other information

No response

Author: bholmes
Assignees: -
Labels:

untriaged, area-VM-meta-mono

Milestone: -

@bholmes
Copy link
Contributor Author

bholmes commented Oct 21, 2021

Thread 1 "HelloWorld" received signal SIGSEGV, Segmentation fault.
0x00007ffff739912c in m_class_get_class_kind (klass=0x100000002c8) at /home/bill/dev/runtime/src/mono/mono/metadata/class-getters.h:43
43      MONO_CLASS_GETTER(m_class_get_class_kind, guint8, , MonoClass, class_kind)
(gdb) bt
#0  0x00007ffff739912c in m_class_get_class_kind (klass=0x100000002c8) at /home/bill/dev/runtime/src/mono/mono/metadata/class-getters.h:43
#1  0x00007ffff769fda5 in mono_class_is_ginst (klass=0x100000002c8) at /home/bill/dev/runtime/src/mono/mono/mini/../../mono/metadata/class-inlines.h:57
#2  0x00007ffff769fc16 in mono_get_generic_context_from_stack_frame (ji=0x5555557eaaf0, generic_info=0x5555557cc170) at /home/bill/dev/runtime/src/mono/mono/mini/mini-exceptions.c:862
#3  0x00007ffff76a0ac5 in get_method_from_stack_frame (ji=0x5555557eaaf0, generic_info=0x5555557cc170) at /home/bill/dev/runtime/src/mono/mono/mini/mini-exceptions.c:888
#4  0x00007ffff76a19c4 in ves_icall_get_frame_info (skip=-1, need_file_info=1 '\001', method=0x7fffffffd030, iloffset=0x7fffffffd028, native_offset=0x7fffffffd020, file=0x7fffffffd018, line=0x7fffffffd010,
    column=0x7fffffffd008) at /home/bill/dev/runtime/src/mono/mono/mini/mini-exceptions.c:1458

@thaystg thaystg self-assigned this Oct 21, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Oct 22, 2021
monojenkins pushed a commit to monojenkins/mono that referenced this issue Dec 1, 2021
…ace method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Dec 2, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Jan 1, 2022
bholmes added a commit to Unity-Technologies/mono that referenced this issue Feb 3, 2022
…ace method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486
lambdageek pushed a commit to mono/mono that referenced this issue Feb 8, 2022
…ace method (#21356)

* [mono] Fix StackTrace from a dim and Vtable offsets for static interface method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486

* mono_get_generic_info_from_stack_frame fix for default interface methods

The context is a MonoMethodRuntimeGenericContext when the method is a
default interface method.

Related to dotnet/runtime#62334

Co-authored-by: thaystg <thaystg@users.noreply.github.com>
Co-authored-by: Bill Holmes <bill.holmes@unity3d.com>
schoudhary-rythmos pushed a commit to Unity-Technologies/mono that referenced this issue Mar 4, 2022
…ace method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486
schoudhary-rythmos pushed a commit to Unity-Technologies/mono that referenced this issue Mar 4, 2022
…ace method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486
ThomasKuehne pushed a commit to ThomasKuehne/mono that referenced this issue Mar 23, 2024
…ace method (mono#21356)

* [mono] Fix StackTrace from a dim and Vtable offsets for static interface method

- Fix StackTrace when called from a DIM.
- Fix the other test case that was added for @bholmes, and this case when the method `TestMethod5` was being called it was executing `TestMethod10`, and this was fixed skipping static interface methods when was calculating vtable offsets.

The fix was completely done by @vargaz, I just opened the PR.
Thanks @vargaz .

Fix dotnet/runtime#60486

* mono_get_generic_info_from_stack_frame fix for default interface methods

The context is a MonoMethodRuntimeGenericContext when the method is a
default interface method.

Related to dotnet/runtime#62334

Co-authored-by: thaystg <thaystg@users.noreply.github.com>
Co-authored-by: Bill Holmes <bill.holmes@unity3d.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.