Пример #1
0
 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;
                }
            }
        }
Пример #3
0
        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;
                    }
                }
            }
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        ///////////////////////////////////////////////////////////////////////

        public static bool HasFlags(
            ThreadFlags flags,
            ThreadFlags hasFlags,
            bool all
            )
        {
            if (all)
            {
                return((flags & hasFlags) == hasFlags);
            }
            else
            {
                return((flags & hasFlags) != ThreadFlags.None);
            }
        }
Пример #6
0
 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);
            }
        }
Пример #8
0
 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;
     }
 }
Пример #9
0
        /// <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);
        }
Пример #10
0
 /// <summary>
 /// Removes a flag from the thread
 /// </summary>
 /// <param name="flag">The flag</param>
 public void RemoveFlag(ThreadFlags flag)
 {
     m_flags &= ~flag;
 }
Пример #11
0
 /// <summary>
 /// Adds a flag to the thread
 /// </summary>
 /// <param name="flag">The flag</param>
 public void AddFlag(ThreadFlags flag)
 {
     m_flags |= flag;
 }
Пример #12
0
 /// <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);
 }
Пример #13
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);
        }
        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;
                    }
                }
            }
        }
        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;
                }
            }
        }