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; }
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); }