public SourceLocation(string fileName, int lineNumber, string functionName = null, DkmNativeInstructionAddress nativeAddress = null) { FileName = fileName; LineNumber = lineNumber; FunctionName = functionName; NativeAddress = nativeAddress; }
public static DkmNativeInstructionAddress GetFunctionAddress(this IDiaSymbol moduleSym, string name, DkmNativeModuleInstance moduleInstance) { using (ComPtr <IDiaSymbol> funSym = moduleSym.GetSymbol(SymTagEnum.SymTagFunction, name)) { return(DkmNativeInstructionAddress.Create(moduleInstance.Process.GetNativeRuntimeInstance(), moduleInstance, funSym.Object.relativeVirtualAddress, null)); } }
public SourceLocation(ReadOnlyCollection <byte> encodedLocation, DkmProcess process = null) { var buffer = encodedLocation.ToArray(); using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) { FileName = reader.ReadString(); bool hasFunctionName = reader.ReadBoolean(); if (hasFunctionName) { FunctionName = reader.ReadString(); } LineNumber = reader.ReadInt32(); bool hasNativeAddress = reader.ReadBoolean(); if (hasNativeAddress && process != null) { var ip = reader.ReadUInt64(); var rva = reader.ReadUInt32(); NativeAddress = DkmNativeInstructionAddress.Create( process.GetNativeRuntimeInstance(), process.GetPythonRuntimeInfo().DLLs.Python, rva, new DkmNativeInstructionAddress.CPUInstruction(ip)); } else { NativeAddress = null; } } }
public FunctionTracer(DkmNativeInstructionAddress address, StackFrameAnalyzer analyzer) { this.frameAnalyzer = analyzer; DkmProcess process = address.ModuleInstance.Process; entryAddress = address; }
public unsafe TraceManagerLocalHelper(DkmProcess process, Kind kind) { _process = process; _pyrtInfo = process.GetPythonRuntimeInfo(); _traceFunc = _pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("TraceFunc"); _isTracing = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <ByteProxy>("isTracing"); _pyTracingPossible = _pyrtInfo.DLLs.Python.GetStaticVariable <UInt32Proxy>("_Py_TracingPossible"); if (kind == Kind.StepIn) { var fieldOffsets = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <CliStructProxy <FieldOffsets> >("fieldOffsets"); fieldOffsets.Write(new FieldOffsets(process, _pyrtInfo)); var types = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <CliStructProxy <Types> >("types"); types.Write(new Types(process, _pyrtInfo)); var functionPointers = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <CliStructProxy <FunctionPointers> >("functionPointers"); functionPointers.Write(new FunctionPointers(process, _pyrtInfo)); var stringEquals = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable <PointerProxy>("stringEquals"); if (_pyrtInfo.LanguageVersion <= PythonLanguageVersion.V27) { stringEquals.Write(_pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("StringEquals27").GetPointer()); } else { stringEquals.Write(_pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("StringEquals33").GetPointer()); } foreach (var interp in PyInterpreterState.GetInterpreterStates(process)) { foreach (var tstate in interp.GetThreadStates()) { RegisterTracing(tstate); } } _handlers = new PythonDllBreakpointHandlers(this); LocalComponent.CreateRuntimeDllFunctionExitBreakpoints(_pyrtInfo.DLLs.Python, "new_threadstate", _handlers.new_threadstate, enable: true); foreach (var methodInfo in _handlers.GetType().GetMethods()) { var stepInAttr = (StepInGateAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(StepInGateAttribute)); if (stepInAttr != null && (stepInAttr.MinVersion == PythonLanguageVersion.None || _pyrtInfo.LanguageVersion >= stepInAttr.MinVersion) && (stepInAttr.MaxVersion == PythonLanguageVersion.None || _pyrtInfo.LanguageVersion <= stepInAttr.MaxVersion)) { var handler = (StepInGateHandler)Delegate.CreateDelegate(typeof(StepInGateHandler), _handlers, methodInfo); AddStepInGate(handler, _pyrtInfo.DLLs.Python, methodInfo.Name, stepInAttr.HasMultipleExitPoints); } } if (_pyrtInfo.DLLs.CTypes != null) { OnCTypesLoaded(_pyrtInfo.DLLs.CTypes); } } }
public FunctionTracer(DkmNativeInstructionAddress address, StackFrameAnalyzer analyzer) { this.frameAnalyzer = analyzer; DkmProcess process = address.ModuleInstance.Process; entryAddress = address; }
DkmRuntimeInstructionBreakpoint PlaceBreakpointAtAddress(NullcRemoteProcessDataItem processData, DkmThread thread, ulong instructionAddress) { var dkmInstruction = DkmNativeInstructionAddress.Create(processData.nativeRuntimeInstance, processData.nativeModuleInstance, (uint)(instructionAddress - processData.nativeModuleInstance.BaseAddress), new DkmInstructionAddress.CPUInstruction(instructionAddress)); var stepBreakpoint = DkmRuntimeInstructionBreakpoint.Create(DebugHelpers.NullcStepperBreakpointSourceId, thread, dkmInstruction, false, null); stepBreakpoint.Enable(); return(stepBreakpoint); }
public SourceLocation(ReadOnlyCollection <byte> encodedLocation, DkmProcess process = null) { var buffer = encodedLocation.ToArray(); using (var stream = new MemoryStream(buffer)) using (var reader = new BinaryReader(stream)) { FileName = reader.ReadString(); bool hasFunctionName = reader.ReadBoolean(); if (hasFunctionName) { FunctionName = reader.ReadString(); } LineNumber = reader.ReadInt32(); bool hasNativeAddress = reader.ReadBoolean(); if (hasNativeAddress && process != null) { var ip = reader.ReadUInt64(); var rva = reader.ReadUInt32(); PythonDLLs dlls = process.GetPythonRuntimeInfo().DLLs; DkmNativeModuleInstance dll = null; switch (reader.ReadInt32()) { case 0: dll = dlls.Python; break; case 1: dll = dlls.DebuggerHelper; break; } if (dll != null) { NativeAddress = DkmNativeInstructionAddress.Create( process.GetNativeRuntimeInstance(), dll, rva, new DkmNativeInstructionAddress.CPUInstruction(ip)); } } else { NativeAddress = null; } } }
void IDkmInstructionAddressProvider.GetInstructionAddress(DkmProcess process, DkmWorkList workList, ulong instructionPointer, DkmCompletionRoutine <DkmGetInstructionAddressAsyncResult> completionRoutine) { var processData = DebugHelpers.GetOrCreateDataItem <NullcModuleDataItem>(process); if (!processData.nullcIsMissing && processData.moduleBase == 0) { processData.moduleBase = DebugHelpers.ReadPointerVariable(process, "nullcModuleStartAddress").GetValueOrDefault(0); processData.moduleSize = (uint)(DebugHelpers.ReadPointerVariable(process, "nullcModuleEndAddress").GetValueOrDefault(0) - processData.moduleBase); processData.nullcIsMissing = processData.moduleBase == 0; } if (processData.moduleBase != 0) { if (instructionPointer >= processData.moduleBase && instructionPointer < processData.moduleBase + processData.moduleSize) { DkmInstructionAddress address; if (DebugHelpers.useNativeInterfaces) { var nullcNativeRuntime = DebugHelpers.useDefaultRuntimeInstance ? process.GetNativeRuntimeInstance() : process.GetRuntimeInstances().OfType <DkmNativeRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid); var nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmNativeModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid); address = DkmNativeInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance, (uint)(instructionPointer - processData.moduleBase), new DkmInstructionAddress.CPUInstruction(instructionPointer)); } else { var nullcNativeRuntime = process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid); var nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid); address = DkmCustomInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance, null, instructionPointer, null, new DkmInstructionAddress.CPUInstruction(instructionPointer)); } completionRoutine(new DkmGetInstructionAddressAsyncResult(address, true)); return; } } process.GetInstructionAddress(workList, instructionPointer, completionRoutine); }
public unsafe TraceManagerLocalHelper(DkmProcess process, Kind kind) { _process = process; _pyrtInfo = process.GetPythonRuntimeInfo(); _traceFunc = _pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("TraceFunc"); _isTracing = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable<ByteProxy>("isTracing"); _pyTracingPossible = _pyrtInfo.DLLs.Python.GetStaticVariable<UInt32Proxy>("_Py_TracingPossible"); if (kind == Kind.StepIn) { var fieldOffsets = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable<CliStructProxy<FieldOffsets>>("fieldOffsets"); fieldOffsets.Write(new FieldOffsets(process, _pyrtInfo)); var types = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable<CliStructProxy<Types>>("types"); types.Write(new Types(process, _pyrtInfo)); var functionPointers = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable<CliStructProxy<FunctionPointers>>("functionPointers"); functionPointers.Write(new FunctionPointers(process, _pyrtInfo)); var stringEquals = _pyrtInfo.DLLs.DebuggerHelper.GetExportedStaticVariable<PointerProxy>("stringEquals"); if (_pyrtInfo.LanguageVersion <= PythonLanguageVersion.V27) { stringEquals.Write(_pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("StringEquals27").GetPointer()); } else { stringEquals.Write(_pyrtInfo.DLLs.DebuggerHelper.GetExportedFunctionAddress("StringEquals33").GetPointer()); } foreach (var interp in PyInterpreterState.GetInterpreterStates(process)) { foreach (var tstate in interp.GetThreadStates()) { RegisterTracing(tstate); } } _handlers = new PythonDllBreakpointHandlers(this); LocalComponent.CreateRuntimeDllFunctionExitBreakpoints(_pyrtInfo.DLLs.Python, "new_threadstate", _handlers.new_threadstate, enable: true); foreach (var methodInfo in _handlers.GetType().GetMethods()) { var stepInAttr = (StepInGateAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(StepInGateAttribute)); if (stepInAttr != null && (stepInAttr.MinVersion == PythonLanguageVersion.None || _pyrtInfo.LanguageVersion >= stepInAttr.MinVersion) && (stepInAttr.MaxVersion == PythonLanguageVersion.None || _pyrtInfo.LanguageVersion <= stepInAttr.MaxVersion)) { var handler = (StepInGateHandler)Delegate.CreateDelegate(typeof(StepInGateHandler), _handlers, methodInfo); AddStepInGate(handler, _pyrtInfo.DLLs.Python, methodInfo.Name, stepInAttr.HasMultipleExitPoints); } } if (_pyrtInfo.DLLs.CTypes != null) { OnCTypesLoaded(_pyrtInfo.DLLs.CTypes); } } }
public static ulong GetPointer(this DkmNativeInstructionAddress addr) { return(addr.RVA + addr.ModuleInstance.BaseAddress); }
DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input) { if (input == null) // null input frame indicates the end of the call stack. This sample does nothing on end-of-stack. { var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(stackContext.InspectionSession.Process); processData.nullcFramePosition = 1; return(null); } if (input.InstructionAddress == null) { return(new DkmStackWalkFrame[1] { input }); } if (input.InstructionAddress.ModuleInstance != null) { if (input.BasicSymbolInfo != null && input.BasicSymbolInfo.MethodName == "ExecutorRegVm::RunCode") { var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(input.Thread.Process); InitNullcDebugFunctions(processData, input.RuntimeInstance); if (processData.nullcIsMissing) { return(new DkmStackWalkFrame[1] { input }); } string vmInstructionStr = ExecuteExpression("instruction - codeBase", stackContext, input, true); string ptrValue = DebugHelpers.Is64Bit(input.Thread.Process) ? "longValue" : "intValue"; string vmDataOffsetStr = ExecuteExpression($"(unsigned long long)regFilePtr[1].{ptrValue} - (unsigned long long)rvm->dataStack.data", stackContext, input, true); if (vmInstructionStr != null && vmDataOffsetStr != null) { ulong vmInstruction = ulong.Parse(vmInstructionStr); string stackFrameDesc = ExecuteExpression($"((char*(*)(unsigned, unsigned)){processData.nullcDebugGetVmAddressLocation})({vmInstruction}, 0),sb", stackContext, input, false); var nullcCustomRuntime = input.Thread.Process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcVmRuntimeGuid); if (stackFrameDesc != null && nullcCustomRuntime != null) { var flags = input.Flags; flags = flags & ~(DkmStackWalkFrameFlags.NonuserCode | DkmStackWalkFrameFlags.UserStatusNotDetermined); flags = flags | DkmStackWalkFrameFlags.InlineOptimized; DkmCustomModuleInstance nullcModuleInstance = nullcCustomRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid); if (nullcModuleInstance != null) { DkmInstructionAddress instructionAddress = DkmCustomInstructionAddress.Create(nullcCustomRuntime, nullcModuleInstance, null, vmInstruction, null, null); var rawAnnotations = new List <DkmStackWalkFrameAnnotation>(); // Additional unique request id rawAnnotations.Add(DkmStackWalkFrameAnnotation.Create(DebugHelpers.NullcCallStackDataBaseGuid, ulong.Parse(vmDataOffsetStr))); var annotations = new ReadOnlyCollection <DkmStackWalkFrameAnnotation>(rawAnnotations); DkmStackWalkFrame frame = DkmStackWalkFrame.Create(stackContext.Thread, instructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, annotations, nullcModuleInstance, null, null); return(new DkmStackWalkFrame[2] { frame, input }); } } } } return(new DkmStackWalkFrame[1] { input }); } // Currently we want to provide info only for JiT frames if (!input.Flags.HasFlag(DkmStackWalkFrameFlags.UserStatusNotDetermined)) { return(new DkmStackWalkFrame[1] { input }); } try { var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(input.Thread.Process); InitNullcDebugFunctions(processData, input.RuntimeInstance); if (processData.nullcIsMissing) { return new DkmStackWalkFrame[1] { input } } ; string stackFrameDesc = ExecuteExpression($"((char*(*)(void*, unsigned)){processData.nullcDebugGetNativeAddressLocation})((void*)0x{input.InstructionAddress.CPUInstructionPart.InstructionPointer:X}, 0),sb", stackContext, input, false); if (stackFrameDesc != null) { var flags = input.Flags; flags = flags & ~(DkmStackWalkFrameFlags.NonuserCode | DkmStackWalkFrameFlags.UserStatusNotDetermined); if (stackFrameDesc == "[Transition to nullc]") { return(new DkmStackWalkFrame[1] { DkmStackWalkFrame.Create(stackContext.Thread, input.InstructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, input.Annotations) }); } DkmStackWalkFrame frame = null; var nullcCustomRuntime = input.Thread.Process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid); var nullcNativeRuntime = DebugHelpers.useDefaultRuntimeInstance ? input.Thread.Process.GetNativeRuntimeInstance() : input.Thread.Process.GetRuntimeInstances().OfType <DkmNativeRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid); if (DebugHelpers.useNativeInterfaces ? nullcNativeRuntime != null : nullcCustomRuntime != null) { DkmModuleInstance nullcModuleInstance; if (DebugHelpers.useNativeInterfaces) { nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmNativeModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid); } else { nullcModuleInstance = nullcCustomRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid); } if (nullcModuleInstance != null) { // If the top of the call stack is a nullc frame, nullc call stack wont have an entry for it and we start from 0, otherwise we start from default value of 1 if (input.Flags.HasFlag(DkmStackWalkFrameFlags.TopFrame)) { processData.nullcFramePosition = 0; } string stackFrameBase = ExecuteExpression($"((unsigned(*)(unsigned)){processData.nullcDebugGetReversedStackDataBase})({processData.nullcFramePosition})", stackContext, input, true); processData.nullcFramePosition++; if (int.TryParse(stackFrameBase, out int stackFrameBaseValue)) { DkmInstructionAddress instructionAddress; if (DebugHelpers.useNativeInterfaces) { var rva = (uint)(input.InstructionAddress.CPUInstructionPart.InstructionPointer - nullcModuleInstance.BaseAddress); instructionAddress = DkmNativeInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance as DkmNativeModuleInstance, rva, input.InstructionAddress.CPUInstructionPart); } else { instructionAddress = DkmCustomInstructionAddress.Create(nullcCustomRuntime, nullcModuleInstance as DkmCustomModuleInstance, null, input.InstructionAddress.CPUInstructionPart.InstructionPointer, null, input.InstructionAddress.CPUInstructionPart); } var rawAnnotations = new List <DkmStackWalkFrameAnnotation>(); // Additional unique request id rawAnnotations.Add(DkmStackWalkFrameAnnotation.Create(DebugHelpers.NullcCallStackDataBaseGuid, (ulong)(stackFrameBaseValue))); var annotations = new ReadOnlyCollection <DkmStackWalkFrameAnnotation>(rawAnnotations); frame = DkmStackWalkFrame.Create(stackContext.Thread, instructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, annotations, nullcModuleInstance, null, null); } } } if (frame == null) { frame = DkmStackWalkFrame.Create(stackContext.Thread, input.InstructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, input.Annotations); } return(new DkmStackWalkFrame[1] { frame }); } } catch (Exception ex) { Console.WriteLine("Failed to evaluate: " + ex.ToString()); } return(new DkmStackWalkFrame[1] { input }); }