示例#1
0
        public void GetThreadTebTest()
        {
            using DataTarget dt = TestTargets.AppDomains.LoadFullDumpWithDbgEng();
            IThreadReader threadReader = (IThreadReader)dt.DataReader;

            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
            using SOSDac dac         = runtime.DacLibrary.SOSDacInterface;


            foreach (ClrThread thread in runtime.Threads)
            {
                if (!thread.IsAlive)
                {
                    continue;
                }

                Assert.NotEqual(0u, thread.OSThreadId);

                ulong teb = threadReader.GetThreadTeb(thread.OSThreadId);
                Assert.NotEqual(0ul, teb);

                if (dac.GetThreadData(thread.Address, out ThreadData threadData))
                {
                    Assert.Equal((ulong)threadData.Teb, teb);
                }
            }
        }
示例#2
0
        public void EnsureOSThreadOrdering()
        {
            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

            IThreadReader threadReader = (IThreadReader)dt.DataReader;

            var items = threadReader.EnumerateOSThreadIds().ToArray();

            uint mainThreadId = runtime.GetMainThread().OSThreadId;

            Assert.Equal(mainThreadId, threadReader.EnumerateOSThreadIds().First());
        }
示例#3
0
        public void EnumerateOSThreadIdsTest()
        {
            using DataTarget dt      = TestTargets.Types.LoadFullDump();
            using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();

            IThreadReader threadReader = (IThreadReader)dt.DataReader;

            uint[] threads = threadReader.EnumerateOSThreadIds().ToArray();

            Assert.NotEmpty(threads);
            Assert.DoesNotContain(0u, threads);

            // no duplicates
            Assert.Equal(threads.Length, new HashSet <uint>(threads).Count);

            foreach (uint threadId in runtime.Threads.Select(f => f.OSThreadId).Where(id => id != 0))
            {
                Assert.Contains(threadId, threads);
            }
        }
示例#4
0
        public ThreadServiceFromDataReader(ITarget target, IDataReader dataReader)
            : base(target)
        {
            _dataReader   = dataReader;
            _threadReader = (IThreadReader)dataReader;

            if (dataReader is IThreadReader threadReader)
            {
                // Initialize the current thread
                IEnumerable <uint> threads = threadReader.EnumerateOSThreadIds();
                if (threads.Any())
                {
                    CurrentThreadId = threads.First();
                }
            }
            else
            {
                throw new InvalidOperationException("IThreadReader not implemented");
            }
        }
示例#5
0
        public ThreadService(IDataReader dataReader)
        {
            _dataReader   = dataReader;
            _threadReader = (IThreadReader)dataReader;

            Type contextType;

            switch (dataReader.Architecture)
            {
            case Architecture.Amd64:
                // Dumps generated with newer dbgeng have bigger context buffers and clrmd requires the context size to at least be that size.
                _contextSize  = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 0x700 : AMD64Context.Size;
                _contextFlags = AMD64Context.ContextControl | AMD64Context.ContextInteger | AMD64Context.ContextSegments;
                contextType   = typeof(AMD64Context);
                break;

            case Architecture.X86:
                _contextSize  = X86Context.Size;
                _contextFlags = X86Context.ContextControl | X86Context.ContextInteger | X86Context.ContextSegments;
                contextType   = typeof(X86Context);
                break;

            case Architecture.Arm64:
                _contextSize  = Arm64Context.Size;
                _contextFlags = Arm64Context.ContextControl | Arm64Context.ContextInteger;
                contextType   = typeof(Arm64Context);
                break;

            case Architecture.Arm:
                _contextSize  = ArmContext.Size;
                _contextFlags = ArmContext.ContextControl | ArmContext.ContextInteger;
                contextType   = typeof(ArmContext);
                break;

            default:
                throw new PlatformNotSupportedException($"Unsupported architecture: {dataReader.Architecture}");
            }

            var registers = new List <RegisterInfo>();
            int index     = 0;

            FieldInfo[] fields = contextType.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (FieldInfo field in fields)
            {
                RegisterAttribute registerAttribute = field.GetCustomAttributes <RegisterAttribute>(inherit: false).SingleOrDefault();
                if (registerAttribute == null)
                {
                    continue;
                }
                RegisterType registerType = registerAttribute.RegisterType & RegisterType.TypeMask;
                switch (registerType)
                {
                case RegisterType.Control:
                case RegisterType.General:
                case RegisterType.Segments:
                    break;

                default:
                    continue;
                }
                if ((registerAttribute.RegisterType & RegisterType.ProgramCounter) != 0)
                {
                    _instructionPointerIndex = index;
                }
                if ((registerAttribute.RegisterType & RegisterType.StackPointer) != 0)
                {
                    _stackPointerIndex = index;
                }
                if ((registerAttribute.RegisterType & RegisterType.FramePointer) != 0)
                {
                    _framePointerIndex = index;
                }
                FieldOffsetAttribute offsetAttribute = field.GetCustomAttributes <FieldOffsetAttribute>(inherit: false).Single();
                var registerInfo = new RegisterInfo(index, offsetAttribute.Value, Marshal.SizeOf(field.FieldType), registerAttribute.Name ?? field.Name.ToLower());
                registers.Add(registerInfo);
                index++;
            }

            _lookupByName  = registers.ToDictionary((info) => info.RegisterName);
            _lookupByIndex = registers.ToDictionary((info) => info.RegisterIndex);
            _registers     = registers;
        }
 public ThreadServiceFromDataReader(ITarget target, IDataReader dataReader)
     : base(target)
 {
     _dataReader   = dataReader;
     _threadReader = (IThreadReader)dataReader;
 }