Exemple #1
0
        private void OnBreakpointHit(DkmThread thread)
        {
            CurrentSourceLocation cbp = _currentSourceLocation.Read();

            DebuggerString fileNameDS;

            _process.ReadMemory(cbp.fileName, DkmReadMemoryFlags.None, &fileNameDS, sizeof(DebuggerString));

            char *fileNameBuf = stackalloc char[fileNameDS.length];
            ulong dataOffset  = (ulong)((byte *)fileNameDS.data - (byte *)&fileNameDS);

            _process.ReadMemory(cbp.fileName + dataOffset, DkmReadMemoryFlags.None, fileNameBuf, fileNameDS.length * 2);
            string fileName = new string(fileNameBuf, 0, fileNameDS.length);

            SourceLocation loc = new SourceLocation(fileName, cbp.lineNumber);

            if (!_breakpoints.TryGetValue(loc, out List <DkmRuntimeBreakpoint> bps))
            {
                Debug.Fail("TraceFunc signalled a breakpoint at a location that BreakpointManager does not know about.");
                return;
            }

            foreach (var bp in bps)
            {
                bp.OnHit(thread, false);
            }
        }
Exemple #2
0
        private void WriteBreakpoints()
        {
            int maxLineNumber     = _breakpoints.Keys.Select(loc => loc.LineNumber).DefaultIfEmpty().Max();
            var lineNumbersStream = new MemoryStream((maxLineNumber + 1) * sizeof(int));
            var lineNumbersWriter = new BinaryWriter(lineNumbersStream);

            var stringsStream = new MemoryStream();
            var stringsWriter = new BinaryWriter(stringsStream);
            var stringOffsets = new Dictionary <string, int>();

            stringsWriter.Write((int)0);
            foreach (var s in _breakpoints.Keys.Select(loc => loc.FileName).Distinct())
            {
                stringOffsets[s] = (int)stringsStream.Position;
                stringsWriter.Write((int)s.Length);
                foreach (char c in s)
                {
                    stringsWriter.Write((ushort)c);
                }
                stringsWriter.Write((ushort)0);
            }

            var fileNamesOffsetsStream  = new MemoryStream();
            var fileNamesOffsetsWriter  = new BinaryWriter(fileNamesOffsetsStream);
            var fileNamesOffsetsIndices = new Dictionary <int[], int>(new StructuralArrayEqualityComparer <int>());

            fileNamesOffsetsWriter.Write((int)0);
            foreach (var g in _breakpoints.Keys.GroupBy(loc => loc.LineNumber))
            {
                var lineNumber = g.Key;

                var fileNamesOffsets = g.Select(loc => stringOffsets[loc.FileName]).ToArray();
                Array.Sort(fileNamesOffsets);

                if (!fileNamesOffsetsIndices.TryGetValue(fileNamesOffsets, out global::System.Int32 fileNamesOffsetsIndex))
                {
                    fileNamesOffsetsIndex = (int)fileNamesOffsetsStream.Position / sizeof(int);
                    foreach (int offset in fileNamesOffsets)
                    {
                        fileNamesOffsetsWriter.Write(offset);
                    }
                    fileNamesOffsetsWriter.Write((int)0);
                    fileNamesOffsetsIndices.Add(fileNamesOffsets, fileNamesOffsetsIndex);
                }

                lineNumbersStream.Position = lineNumber * sizeof(int);
                lineNumbersWriter.Write(fileNamesOffsetsIndex);
            }

            byte breakpointDataInUseByTraceFunc = _breakpointDataInUseByTraceFunc.Read();
            byte currentBreakpointData          = (breakpointDataInUseByTraceFunc == 0) ? (byte)1 : (byte)0;

            _currentBreakpointData.Write(currentBreakpointData);

            CliStructProxy <BreakpointData> bpDataProxy = _breakpointData[currentBreakpointData];
            BreakpointData bpData = bpDataProxy.Read();

            if (bpData.lineNumbers != 0)
            {
                _process.FreeVirtualMemory(bpData.lineNumbers, 0, NativeMethods.MEM_RELEASE);
            }
            if (bpData.fileNamesOffsets != 0)
            {
                _process.FreeVirtualMemory(bpData.fileNamesOffsets, 0, NativeMethods.MEM_RELEASE);
            }
            if (bpData.strings != 0)
            {
                _process.FreeVirtualMemory(bpData.strings, 0, NativeMethods.MEM_RELEASE);
            }

            bpData.maxLineNumber = maxLineNumber;
            if (lineNumbersStream.Length > 0)
            {
                bpData.lineNumbers = _process.AllocateVirtualMemory(0, (int)lineNumbersStream.Length, NativeMethods.MEM_COMMIT | NativeMethods.MEM_RESERVE, NativeMethods.PAGE_READWRITE);
                _process.WriteMemory(bpData.lineNumbers, lineNumbersStream.ToArray());
            }
            else
            {
                bpData.lineNumbers = 0;
            }

            bpData.fileNamesOffsets = _process.AllocateVirtualMemory(0, (int)fileNamesOffsetsStream.Length, NativeMethods.MEM_COMMIT | NativeMethods.MEM_RESERVE, NativeMethods.PAGE_READWRITE);
            _process.WriteMemory(bpData.fileNamesOffsets, fileNamesOffsetsStream.ToArray());

            bpData.strings = _process.AllocateVirtualMemory(0, (int)stringsStream.Length, NativeMethods.MEM_COMMIT | NativeMethods.MEM_RESERVE, NativeMethods.PAGE_READWRITE);
            _process.WriteMemory(bpData.strings, stringsStream.ToArray());

            bpDataProxy.Write(bpData);
        }