Example #1
0
        void check_pending_events()
        {
            SingleSteppingEngine[] list = new SingleSteppingEngine [pending_events.Count];
            pending_events.Keys.CopyTo(list, 0);

            for (int i = 0; i < list.Length; i++)
            {
                SingleSteppingEngine engine = list [i];
                if (engine.Process.HasThreadLock)
                {
                    continue;
                }

                Inferior.ChildEvent cevent = (Inferior.ChildEvent)pending_events [engine];
                pending_events.Remove(engine);

                try {
                    Report.Debug(DebugFlags.Wait,
                                 "ThreadManager {0} process pending event: {1} {2}",
                                 DebuggerWaitHandle.CurrentThread, engine, cevent);
                    engine.ReleaseThreadLock(cevent);
                    Report.Debug(DebugFlags.Wait,
                                 "ThreadManager {0} process pending event done: {1}",
                                 DebuggerWaitHandle.CurrentThread, engine);
                } catch (ST.ThreadAbortException) {
                    ;
                } catch (Exception e) {
                    Report.Debug(DebugFlags.Wait,
                                 "ThreadManager caught exception: {0}", e);
                }
            }
        }
Example #2
0
 internal void AddPendingEvent(SingleSteppingEngine engine, Inferior.ChildEvent cevent)
 {
     Report.Debug(DebugFlags.Wait, "Add pending event: {0} {1}", engine, cevent);
     pending_events.Add(engine, cevent);
 }
Example #3
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;
        }
Example #4
0
        internal bool HandleChildEvent(SingleSteppingEngine engine, Inferior inferior,
                                       ref Inferior.ChildEvent cevent, out bool resume_target)
        {
            if (cevent.Type == Inferior.ChildEventType.NONE)
            {
                resume_target = true;
                return(true);
            }

            if (cevent.Type == Inferior.ChildEventType.CHILD_CREATED_THREAD)
            {
                int pid = (int)cevent.Argument;
                inferior.Process.ThreadCreated(inferior, pid, false, true);
                if (pending_sigstops.ContainsKey(pid))
                {
                    pending_sigstops.Remove(pid);
                }
                resume_target = true;
                return(true);
            }

            if (cevent.Type == Inferior.ChildEventType.CHILD_FORKED)
            {
                inferior.Process.ChildForked(inferior, (int)cevent.Argument);
                resume_target = true;
                return(true);
            }

            if (cevent.Type == Inferior.ChildEventType.CHILD_EXECD)
            {
                thread_hash.Remove(engine.PID);
                engine_hash.Remove(engine.ID);
                inferior.Process.ChildExecd(engine, inferior);
                resume_target = false;
                return(true);
            }

            if (cevent.Type == Inferior.ChildEventType.CHILD_STOPPED)
            {
                if (cevent.Argument == inferior.SIGCHLD)
                {
                    cevent = new Inferior.ChildEvent(
                        Inferior.ChildEventType.CHILD_STOPPED, 0, 0, 0);
                    resume_target = true;
                    return(true);
                }
                else if (inferior.Has_SIGWINCH && (cevent.Argument == inferior.SIGWINCH))
                {
                    resume_target = true;
                    return(true);
                }
                else if (inferior.HasSignals && (cevent.Argument == inferior.Kernel_SIGRTMIN + 1))
                {
                    // __SIGRTMIN and __SIGRTMIN+1 are used internally by the threading library
                    resume_target = true;
                    return(true);
                }
            }

            if (inferior.Process.OperatingSystem.CheckForPendingMonoInit(inferior))
            {
                resume_target = true;
                return(true);
            }

            bool retval = false;

            resume_target = false;
            if (inferior.Process.MonoManager != null)
            {
                retval = inferior.Process.MonoManager.HandleChildEvent(
                    engine, inferior, ref cevent, out resume_target);
            }

            if ((cevent.Type == Inferior.ChildEventType.CHILD_EXITED) ||
                (cevent.Type == Inferior.ChildEventType.CHILD_SIGNALED))
            {
                thread_hash.Remove(engine.PID);
                engine_hash.Remove(engine.ID);
                engine.OnThreadExited(cevent);
                resume_target = false;
                return(true);
            }

            return(retval);
        }
Example #5
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);
        }