private static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, ThreadFlags dwCreationFlags, out IntPtr lpThreadId);
public void Stop() { // All public API methods are wrapped in a single thread lock. // This frees users to invoke the public API from multiple threads, but provides us a bit of sanity. lock (singleThreadLock) { if (updateTimer != null) { updateTimer.Dispose(); updateTimer = null; } if (Monitor.TryEnter(multiThreadLock)) { Monitor.Exit(multiThreadLock); // Restart update to remove mappings before stopping UpdatePortMappings(); } else if (threadID == ThreadID.RefreshExternalIP) { // Stop the RefreshExternalIPThread refreshExternalIPThreadFlags = ThreadFlags.ShouldQuit; } } }
public void UpdatePortMappings() { // All public API methods are wrapped in a single thread lock. // This frees users to invoke the public API from multiple threads, but provides us a bit of sanity. lock (singleThreadLock) { if (Monitor.TryEnter(multiThreadLock)) { updatePortMappingsThreadFlags = ThreadFlags.None; threadID = ThreadID.UpdatePortMappings; Thread bgThread = new Thread(new ThreadStart(UpdatePortMappingsThread)); bgThread.Start(); Monitor.Exit(multiThreadLock); } else { if (threadID == ThreadID.UpdatePortMappings) { updatePortMappingsThreadFlags = ThreadFlags.ShouldQuit | ThreadFlags.ShouldRestart; } } } }
internal void InitializeThreads(Inferior inferior) { TargetAddress ptr = inferior.ReadAddress(MonoDebuggerInfo.ThreadTable); while (!ptr.IsNull) { int size; if (MonoDebuggerInfo.CheckRuntimeVersion(81, 3)) { size = 60 + inferior.TargetMemoryInfo.TargetAddressSize; } else { size = 32 + inferior.TargetMemoryInfo.TargetAddressSize; } TargetReader reader = new TargetReader(inferior.ReadMemory(ptr, size)); long tid = reader.ReadLongInteger(); TargetAddress lmf_addr = reader.ReadAddress(); TargetAddress end_stack = reader.ReadAddress(); TargetAddress extended_notifications_addr = ptr + 24; if (inferior.TargetMemoryInfo.TargetAddressSize == 4) { tid &= 0x00000000ffffffffL; } reader.Offset += 8; ptr = reader.ReadAddress(); ThreadFlags flags = ThreadFlags.None; if (MonoDebuggerInfo.CheckRuntimeVersion(81, 3)) { reader.Offset = 56 + inferior.TargetAddressSize; flags = (ThreadFlags)reader.ReadInteger(); } bool found = false; foreach (SingleSteppingEngine engine in process.Engines) { if (engine.TID != tid) { continue; } engine.SetManagedThreadData(lmf_addr, extended_notifications_addr); engine.OnManagedThreadCreated(end_stack); check_thread_flags(engine, flags); found = true; break; } if (!found) { Report.Error("Cannot find thread {0:x} in {1}", tid, process.ProcessStart.CommandLine); } } }
/////////////////////////////////////////////////////////////////////// public static bool HasFlags( ThreadFlags flags, ThreadFlags hasFlags, bool all ) { if (all) { return((flags & hasFlags) == hasFlags); } else { return((flags & hasFlags) != ThreadFlags.None); } }
void check_thread_flags(SingleSteppingEngine engine, ThreadFlags flags) { if ((flags & (ThreadFlags.Internal | ThreadFlags.ThreadPool)) != ThreadFlags.Internal) { engine.Thread.ThreadFlags &= ~(Thread.Flags.Daemon | Thread.Flags.Immutable); if (engine != process.MainThreadServant) { process.Debugger.OnManagedThreadCreatedEvent(engine.Thread); } } else if ((flags & ThreadFlags.ThreadPool) != 0) { engine.Thread.ThreadFlags &= ~Thread.Flags.Immutable; } }
public void StopBlocking() { // All public API methods are wrapped in a single thread lock. // This frees users to invoke the public API from multiple threads, but provides us a bit of sanity. lock (singleThreadLock) { refreshExternalIPThreadFlags = ThreadFlags.ShouldQuit; updatePortMappingsThreadFlags = ThreadFlags.ShouldQuit; Monitor.Enter(multiThreadLock); NATPMP.natpmp_t natpmp = new NATPMP.natpmp_t(); NATPMP.initnatpmp(ref natpmp); List <PortMapping> mappingsToRemove = PortMapper.SharedInstance.PortMappingsToRemove; lock (mappingsToRemove) { while (mappingsToRemove.Count > 0) { PortMapping pm = mappingsToRemove[0]; if (pm.MappingStatus == PortMappingStatus.Mapped) { RemovePortMapping(pm, ref natpmp); } mappingsToRemove.RemoveAt(0); } } List <PortMapping> mappingsToStop = PortMapper.SharedInstance.PortMappings; lock (mappingsToStop) { for (int i = 0; i < mappingsToStop.Count; i++) { PortMapping pm = mappingsToStop[i]; if (pm.MappingStatus == PortMappingStatus.Mapped) { RemovePortMapping(pm, ref natpmp); } } } Monitor.Exit(multiThreadLock); } }
void check_thread_flags(SingleSteppingEngine engine, ThreadFlags flags) { if ((flags & (ThreadFlags.Internal | ThreadFlags.ThreadPool)) != ThreadFlags.Internal) { engine.Thread.ThreadFlags &= ~(Thread.Flags.Daemon | Thread.Flags.Immutable); if (engine != process.MainThreadServant) process.Debugger.OnManagedThreadCreatedEvent (engine.Thread); } else if ((flags & ThreadFlags.ThreadPool) != 0) { engine.Thread.ThreadFlags &= ~Thread.Flags.Immutable; } }
/// <summary> /// Creates a thread inside another process' context. /// </summary> /// <param name="hProcess">Handle to the process inside which thread will be created.</param> /// <param name="dwStartAddress">Address at which thread will start.</param> /// <param name="dwParameter">Parameter that will be passed to the thread.</param> /// <param name="dwCreationFlags">Flags that control creation of the thread.</param> /// <param name="dwThreadId">[Out] The id of the created thread.</param> /// <returns>Returns the handle of the created thread.</returns> public static IntPtr CreateRemoteThread(IntPtr hProcess, uint dwStartAddress, uint dwParameter, ThreadFlags dwCreationFlags, out uint dwThreadId) { IntPtr hThread, lpThreadId; hThread = Imports.CreateRemoteThread(hProcess, IntPtr.Zero, 0, (IntPtr)dwStartAddress, (IntPtr)dwParameter, dwCreationFlags, out lpThreadId); dwThreadId = (uint)lpThreadId; return(hThread); }
/// <summary> /// Removes a flag from the thread /// </summary> /// <param name="flag">The flag</param> public void RemoveFlag(ThreadFlags flag) { m_flags &= ~flag; }
/// <summary> /// Adds a flag to the thread /// </summary> /// <param name="flag">The flag</param> public void AddFlag(ThreadFlags flag) { m_flags |= flag; }
/// <summary> /// Checks if the thread has a flag /// </summary> /// <param name="flag">The flag</param> /// <returns>If it has the flag</returns> public bool HasFlag(ThreadFlags flag) { return((m_flags & flag) == flag); }
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); }
public void StopBlocking() { // All public API methods are wrapped in a single thread lock. // This frees users to invoke the public API from multiple threads, but provides us a bit of sanity. lock (singleThreadLock) { refreshExternalIPThreadFlags = ThreadFlags.ShouldQuit; updatePortMappingsThreadFlags = ThreadFlags.ShouldQuit; Monitor.Enter(multiThreadLock); DoUpdateExistingUPnPPortMappings(); List<PortMapping> mappingsToRemove = PortMapper.SharedInstance.PortMappingsToRemove; lock (mappingsToRemove) { while (mappingsToRemove.Count > 0) { PortMapping pm = mappingsToRemove[0]; if (pm.MappingStatus == PortMappingStatus.Mapped) { RemovePortMapping(pm); } mappingsToRemove.RemoveAt(0); } } List<PortMapping> mappingsToStop = PortMapper.SharedInstance.PortMappings; lock (mappingsToStop) { for (int i = 0; i < mappingsToStop.Count; i++) { PortMapping pm = mappingsToStop[i]; if (pm.MappingStatus == PortMappingStatus.Mapped) { RemovePortMapping(pm); } } } Monitor.Exit(multiThreadLock); } }
public void Stop() { // All public API methods are wrapped in a single thread lock. // This frees users to invoke the public API from multiple threads, but provides us a bit of sanity. lock (singleThreadLock) { if (Monitor.TryEnter(multiThreadLock)) { Monitor.Exit(multiThreadLock); // Restart update to remove mappings before stopping UpdatePortMappings(); } else if (threadID == ThreadID.RefreshExternalIP) { // Stop the RefreshExternalIPThread refreshExternalIPThreadFlags = ThreadFlags.ShouldQuit; } } }