예제 #1
0
        internal bool HandleChildEvent(SingleSteppingEngine engine, Inferior inferior,
						ref Inferior.ChildEvent cevent, out bool resume_target)
        {
            if (cevent.Type == Inferior.ChildEventType.CHILD_NOTIFICATION) {
                NotificationType type = (NotificationType) cevent.Argument;

                Report.Debug (DebugFlags.EventLoop,
                          "{0} received notification {1}: {2}",
                          engine, type, cevent);

                switch (type) {
                case NotificationType.AcquireGlobalThreadLock:
                    Report.Debug (DebugFlags.Threads,
                              "{0} received notification {1}", engine, type);
                    engine.Process.AcquireGlobalThreadLock (engine);
                    break;

                case NotificationType.ReleaseGlobalThreadLock:
                    Report.Debug (DebugFlags.Threads,
                              "{0} received notification {1}", engine, type);
                    engine.Process.ReleaseGlobalThreadLock (engine);
                    break;

                case NotificationType.ThreadCreated: {
                    TargetAddress data = new TargetAddress (
                        inferior.AddressDomain, cevent.Data2);

                    TargetAddress lmf = inferior.ReadAddress (data + 8);
                    engine.SetManagedThreadData (lmf, data + 24);

                    if (MonoDebuggerInfo.CheckRuntimeVersion (81, 3)) {
                        int flags_offset = 56 + inferior.TargetAddressSize;
                        ThreadFlags flags = (ThreadFlags) inferior.ReadInteger (data + flags_offset);
                        check_thread_flags (engine, flags);
                    }

                    Report.Debug (DebugFlags.Threads,
                              "{0} managed thread created: {1:x} {2} {3} - {4}",
                              engine, cevent.Data1, data, lmf, engine.LMFAddress);
                    break;
                }

                case NotificationType.ThreadCleanup: {
                    TargetAddress data = new TargetAddress (
                        inferior.AddressDomain, cevent.Data1);

                    Report.Debug (DebugFlags.Threads,
                              "{0} managed thread cleanup: {1:x} {2}",
                              engine, cevent.Data2, data);
                    break;
                }

                case NotificationType.GcThreadCreated: {
                    TargetAddress data = new TargetAddress (
                        inferior.AddressDomain, cevent.Data1);
                    long tid = cevent.Data2;

                    Report.Debug (DebugFlags.Threads,
                              "{0} created gc thread: {1:x} {2}",
                              engine, tid, data);

                    engine = engine.Process.GetEngineByTID (inferior, tid);
                    if (engine == null)
                        throw new InternalError ();

                    engine.OnManagedThreadCreated (data);
                    break;
                }

                case NotificationType.GcThreadExited:
                    Report.Debug (DebugFlags.Threads, "{0} gc thread exited", engine);
                    engine.OnManagedThreadExited ();
                    try {
                        inferior.Continue ();
                    } catch {
                        // Ignore errors; for some reason, the thread may have died
                        // already by the time get this notification.
                    }
                    resume_target = false;
                    return true;

                case NotificationType.InitializeThreadManager:
                    csharp_language = inferior.Process.CreateMonoLanguage (
                        debugger_info);
                    if (engine.Process.IsAttached)
                        csharp_language.InitializeAttach (inferior);
                    else
                        csharp_language.Initialize (inferior);

                    break;

                case NotificationType.ReachedMain: {
                    Inferior.StackFrame iframe = inferior.GetCurrentFrame (false);
                    engine.SetMainReturnAddress (iframe.StackPointer);
                    engine.Process.OnProcessReachedMainEvent ();
                    resume_target = !engine.InitializeBreakpoints ();
                    return true;
                }

                case NotificationType.WrapperMain:
                    break;
                case NotificationType.MainExited:
                    engine.SetMainReturnAddress (TargetAddress.Null);
                    break;

                case NotificationType.UnhandledException:
                    cevent = new Inferior.ChildEvent (
                        Inferior.ChildEventType.UNHANDLED_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return false;

                case NotificationType.HandleException:
                    cevent = new Inferior.ChildEvent (
                        Inferior.ChildEventType.HANDLE_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return false;

                case NotificationType.ThrowException:
                    cevent = new Inferior.ChildEvent (
                        Inferior.ChildEventType.THROW_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return false;

                case NotificationType.FinalizeManagedCode:
                    mono_debugger_server_finalize_mono_runtime (mono_runtime_info);
                    mono_runtime_info = IntPtr.Zero;
                    csharp_language = null;
                    break;

                case NotificationType.OldTrampoline:
                case NotificationType.Trampoline:
                    resume_target = false;
                    return false;

                case NotificationType.ClassInitialized:
                    break;

                case NotificationType.InterruptionRequest:
                    inferior.WriteInteger (MonoDebuggerInfo.InterruptionRequest, 0);
                    var callbacks = managed_callbacks;
                    managed_callbacks = new Queue<ManagedCallbackData> ();
                    resume_target = !engine.OnManagedCallback (callbacks);
                    return true;

                default: {
                    TargetAddress data = new TargetAddress (
                        inferior.AddressDomain, cevent.Data1);

                    resume_target = csharp_language.Notification (
                        engine, inferior, type, data, cevent.Data2);
                    return true;
                }
                }

                resume_target = true;
                return true;
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_STOPPED) &&
                (cevent.Argument == thread_abort_signal)) {
                resume_target = true;
                return true;
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_STOPPED) && (cevent.Argument != 0) && !
                engine.Process.Session.Config.StopOnManagedSignals) {
                if (inferior.IsManagedSignal ((int) cevent.Argument)) {
                    resume_target = true;
                    return true;
                }
            }

            resume_target = false;
            return false;
        }
예제 #2
0
        internal bool HandleChildEvent(SingleSteppingEngine engine, Inferior inferior,
                                       ref Inferior.ChildEvent cevent, out bool resume_target)
        {
            if (cevent.Type == Inferior.ChildEventType.CHILD_NOTIFICATION)
            {
                NotificationType type = (NotificationType)cevent.Argument;

                Report.Debug(DebugFlags.EventLoop,
                             "{0} received notification {1}: {2}",
                             engine, type, cevent);

                switch (type)
                {
                case NotificationType.AcquireGlobalThreadLock:
                    Report.Debug(DebugFlags.Threads,
                                 "{0} received notification {1}", engine, type);
                    engine.Process.AcquireGlobalThreadLock(engine);
                    break;

                case NotificationType.ReleaseGlobalThreadLock:
                    Report.Debug(DebugFlags.Threads,
                                 "{0} received notification {1}", engine, type);
                    engine.Process.ReleaseGlobalThreadLock(engine);
                    break;

                case NotificationType.ThreadCreated: {
                    TargetAddress data = new TargetAddress(
                        inferior.AddressDomain, cevent.Data2);

                    TargetAddress lmf = inferior.ReadAddress(data + 8);
                    engine.SetManagedThreadData(lmf, data + 24);

                    if (MonoDebuggerInfo.CheckRuntimeVersion(81, 3))
                    {
                        int         flags_offset = 56 + inferior.TargetAddressSize;
                        ThreadFlags flags        = (ThreadFlags)inferior.ReadInteger(data + flags_offset);
                        check_thread_flags(engine, flags);
                    }

                    Report.Debug(DebugFlags.Threads,
                                 "{0} managed thread created: {1:x} {2} {3} - {4}",
                                 engine, cevent.Data1, data, lmf, engine.LMFAddress);
                    break;
                }

                case NotificationType.ThreadCleanup: {
                    TargetAddress data = new TargetAddress(
                        inferior.AddressDomain, cevent.Data1);

                    Report.Debug(DebugFlags.Threads,
                                 "{0} managed thread cleanup: {1:x} {2}",
                                 engine, cevent.Data2, data);
                    break;
                }

                case NotificationType.GcThreadCreated: {
                    TargetAddress data = new TargetAddress(
                        inferior.AddressDomain, cevent.Data1);
                    long tid = cevent.Data2;

                    Report.Debug(DebugFlags.Threads,
                                 "{0} created gc thread: {1:x} {2}",
                                 engine, tid, data);

                    engine = engine.Process.GetEngineByTID(inferior, tid);
                    if (engine == null)
                    {
                        throw new InternalError();
                    }

                    engine.OnManagedThreadCreated(data);
                    break;
                }

                case NotificationType.GcThreadExited:
                    Report.Debug(DebugFlags.Threads, "{0} gc thread exited", engine);
                    engine.OnManagedThreadExited();
                    try {
                        inferior.Continue();
                    } catch {
                        // Ignore errors; for some reason, the thread may have died
                        // already by the time get this notification.
                    }
                    resume_target = false;
                    return(true);

                case NotificationType.InitializeThreadManager:
                    csharp_language = inferior.Process.CreateMonoLanguage(
                        debugger_info);
                    if (engine.Process.IsAttached)
                    {
                        csharp_language.InitializeAttach(inferior);
                    }
                    else
                    {
                        csharp_language.Initialize(inferior);
                    }

                    break;

                case NotificationType.ReachedMain: {
                    Inferior.StackFrame iframe = inferior.GetCurrentFrame(false);
                    engine.SetMainReturnAddress(iframe.StackPointer);
                    engine.Process.OnProcessReachedMainEvent();
                    resume_target = !engine.InitializeBreakpoints();
                    return(true);
                }

                case NotificationType.WrapperMain:
                    break;

                case NotificationType.MainExited:
                    engine.SetMainReturnAddress(TargetAddress.Null);
                    break;

                case NotificationType.UnhandledException:
                    cevent = new Inferior.ChildEvent(
                        Inferior.ChildEventType.UNHANDLED_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return(false);

                case NotificationType.HandleException:
                    cevent = new Inferior.ChildEvent(
                        Inferior.ChildEventType.HANDLE_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return(false);

                case NotificationType.ThrowException:
                    cevent = new Inferior.ChildEvent(
                        Inferior.ChildEventType.THROW_EXCEPTION,
                        0, cevent.Data1, cevent.Data2);
                    resume_target = false;
                    return(false);

                case NotificationType.FinalizeManagedCode:
                    mono_debugger_server_finalize_mono_runtime(mono_runtime_info);
                    mono_runtime_info = IntPtr.Zero;
                    csharp_language   = null;
                    break;

                case NotificationType.OldTrampoline:
                case NotificationType.Trampoline:
                    resume_target = false;
                    return(false);

                case NotificationType.ClassInitialized:
                    break;

                case NotificationType.InterruptionRequest:
                    inferior.WriteInteger(MonoDebuggerInfo.InterruptionRequest, 0);
                    var callbacks = managed_callbacks;
                    managed_callbacks = new Queue <ManagedCallbackData> ();
                    resume_target     = !engine.OnManagedCallback(callbacks);
                    return(true);

                default: {
                    TargetAddress data = new TargetAddress(
                        inferior.AddressDomain, cevent.Data1);

                    resume_target = csharp_language.Notification(
                        engine, inferior, type, data, cevent.Data2);
                    return(true);
                }
                }

                resume_target = true;
                return(true);
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_STOPPED) &&
                (cevent.Argument == thread_abort_signal))
            {
                resume_target = true;
                return(true);
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_STOPPED) && (cevent.Argument != 0) && !
                engine.Process.Session.Config.StopOnManagedSignals)
            {
                if (inferior.IsManagedSignal((int)cevent.Argument))
                {
                    resume_target = true;
                    return(true);
                }
            }

            resume_target = false;
            return(false);
        }