[Mono-bugs] [Bug 325900] New: GC.Collect crashes when invoked from a native callback

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Tue Sep 18 03:19:30 EDT 2007


https://bugzilla.novell.com/show_bug.cgi?id=325900

           Summary: GC.Collect crashes when invoked from a native callback
           Product: Mono: Runtime
           Version: 1.2
          Platform: Macintosh
        OS/Version: Mac OS X 10.4
            Status: NEW
          Severity: Critical
          Priority: P5 - None
         Component: GC
        AssignedTo: lupus at novell.com
        ReportedBy: jesjones at mindspring.com
         QAContact: mono-bugs at ximian.com
          Found By: ---


I'm working on a Mac Carbon framework which means that when I enter the main
event loop all the managed code is invoked as the result of delegates passed
into the unmanaged code. However if the garbage collection kicks in my app
crashes.

To see this compile and run the code below. You should see two windows. Select
one window and then the other. Each time a window is activated a call to
GC.Collect() is made. On my PowerPC mac with mono 1.2.5 the app crashes very
quickly with "System.ExecutionEngineException: SIGILL". 

---- snip ------
// gmcs -out:app.exe GC.cs && 
// rm -rf gc.app && 
// macpack -m:2 -n:gc -a:app.exe && 
// open gc.app
using System;
using System.Runtime.InteropServices;

namespace Test
{
using EventHandlerCallRef = IntPtr;        
using EventHandlerRef = IntPtr;
using EventHandlerUPP = IntPtr;        
using EventRef = IntPtr;    
using EventTargetRef = IntPtr;
using OSStatus = Int32;
using WindowRef = IntPtr;

internal enum WindowClass : uint
{
    kDocumentWindowClass          = 6,
}

[Flags]
internal enum WindowAttributes : uint
{
    None = 0,
    kWindowCloseBoxAttribute      = (1 << 0),
    kWindowCollapseBoxAttribute   = (1 << 3),
    kWindowResizableAttribute     = (1 << 4),
    kWindowStandardHandlerAttribute = (1 << 25),
    Default = kWindowCloseBoxAttribute  | 
         kWindowCollapseBoxAttribute | kWindowResizableAttribute |
kWindowStandardHandlerAttribute,
}

[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct Rect    
{
    public short top;
    public short left;
    public short bottom;
    public short right;

    public Rect(short top, short left, short bottom, short right)
    {
        this.top = top;
        this.left = left;
        this.bottom = bottom;
        this.right = right;
    }
}

internal enum EventClass : uint
{
    kEventClassWindow             = 0x77696e64 /* 'wind' */,
}

internal enum EventKind : uint
{
    kEventWindowActivated         = 5,
}

[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal struct EventTypeSpec
{
    public EventClass eventClass;
    public EventKind  eventKind;

    public EventTypeSpec(EventClass eventClass, EventKind eventKind)
    {
        this.eventClass = eventClass;
        this.eventKind = eventKind;
    }
}

internal class Application
{
    public void Run()
    {
        RunApplicationEventLoop();
    }

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern void RunApplicationEventLoop();
}

internal class Window
{
    public Window(Rect bounds)
    {        
        OSStatus err = CreateNewWindow(
            WindowClass.kDocumentWindowClass,
            WindowAttributes.Default,
            ref bounds, 
            out m_window);
        if (err != 0)
            throw new Exception("CreateNewWindow error: " + err);

        InstallActivateHandler();

        ShowHide(m_window, true);
    }

    private delegate OSStatus StdEventHandler(EventHandlerCallRef callRef,
EventRef evt, IntPtr userData);
    private const OSStatus eventNotHandledErr = -9874;

    private void InstallActivateHandler()
    {
        EventTypeSpec[] types = new EventTypeSpec[]{new EventTypeSpec(
            EventClass.kEventClassWindow, EventKind.kEventWindowActivated)};

        StdEventHandler handler = this.OnActivated;

        IntPtr fp = Marshal.GetFunctionPointerForDelegate(handler);
        m_upp = NewEventHandlerUPP(fp);        

        EventTargetRef target = GetWindowEventTarget(m_window);
        OSStatus err = InstallEventHandler(target, m_upp, (uint) types.Length,
types, IntPtr.Zero, IntPtr.Zero);
        if (err != 0)
            throw new Exception("InstallEventHandler error: " + err);
    }    

    private OSStatus OnActivated(EventHandlerCallRef callRef, EventRef evt,
IntPtr userData)
    {
        Console.WriteLine("activated window");

        GC.Collect();        // Unhandled Exception:
System.ExecutionEngineException: SIGILL
        Console.WriteLine("   collected");

        return eventNotHandledErr;
    }

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern OSStatus CreateNewWindow(
        WindowClass        windowClass,
        WindowAttributes   attributes,
        ref Rect           contentBounds,
        out WindowRef      outWindow);

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern EventTargetRef GetWindowEventTarget(
        WindowRef window);

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern OSStatus InstallEventHandler(
        EventTargetRef         inTarget,
        EventHandlerUPP        inHandler,
        uint                   inNumTypes,
        EventTypeSpec[]        inList,
        IntPtr                 inUserData,
        EventHandlerRef        outRef);

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern EventHandlerUPP NewEventHandlerUPP(
        IntPtr userRoutine);

   
[DllImport("/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon")]
    private static extern void ShowHide(
        WindowRef window, 
        [MarshalAs(UnmanagedType.U1)] bool show);

    private WindowRef m_window;
    private EventHandlerUPP m_upp;
}

internal class Program
{
    public static void Main(string[] args)
    { 
        Application app = new Application();
                Window window1 = new Window(new Rect(100, 100, 400, 400));
        Window window2 = new Window(new Rect(300, 100, 700, 400));
        app.Run();
    }
} 
}


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list