/// <summary> /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata. /// Shall only be called while in debug mode. /// </summary> public ModuleMetadata TryGetBaselineMetadata(Guid mvid) { return(_baselineMetadata.GetOrAdd(mvid, m => { using (DebuggerComponent.ManagedEditAndContinueService()) { var clrModuleInstance = FindClrModuleInstance(m); if (clrModuleInstance == null) { return default; } var metadata = GetBaselineModuleMetadata(clrModuleInstance); if (metadata == null) { return default; } // hook up a callback on module unload (the call blocks until the message is processed): DkmCustomMessage.Create( Connection: clrModuleInstance.Process.Connection, Process: clrModuleInstance.Process, SourceId: DebuggerService.MessageSourceId, MessageCode: 0, Parameter1: this, Parameter2: clrModuleInstance).SendLower(); return metadata; } })); }
private static bool ShouldEnable(DkmProcess process) { var message = DkmCustomMessage.Create( process.Connection, process, s_messageSourceId, MessageCode: 1, // Is legacy EE enabled? Parameter1: null, Parameter2: null); try { var reply = message.SendLower(); var result = (int)reply.Parameter1; // Possible values are 0 = false, 1 = true, 2 = not ready. // At this point, we should only get 0 or 1, but to be // safe, treat values other than 0 or 1 as false. Debug.Assert(result == 0 || result == 1); return(result == 0); } catch (NotImplementedException) { return(false); } }
DkmCustomMessage?IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { // Initialize the listener before OnModuleInstanceLoad/OnModuleInstanceUnload can be triggered. // These events are only called when managed debugging is being used due to RuntimeId=DkmRuntimeId.Clr filter in vsdconfigxml. _encService = (IEditAndContinueWorkspaceService)customMessage.Parameter1; return(null); }
public void StartDebugging(DebugSessionOptions options) { _debuggingService.OnBeforeDebuggingStateChanged(DebuggingState.Design, DebuggingState.Run); if ((options & DebugSessionOptions.EditAndContinueDisabled) == 0) { _encService = _workspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>(); // hook up a callbacks (the call blocks until the message is processed): using (DebuggerComponent.ManagedEditAndContinueService()) { DkmCustomMessage.Create( Connection: null, Process: null, SourceId: DebuggerService.MessageSourceId, MessageCode: 0, Parameter1: _encService, Parameter2: null).SendLower(); } _encService.StartDebuggingSession(); } else { _encService = null; } }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { // Initialize the listener before OnModuleInstanceLoad/OnModuleInstanceUnload can be triggered. // These events are only called when managed debugging is being used due to RuntimeId=DkmRuntimeId.Clr filter in vsdconfigxml. _listener = (VisualStudioDebugStateChangeListener)customMessage.Parameter1; return(null); }
/// <summary> /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata. /// Shall only be called while in debug mode. /// Shall only be called on MTA thread. /// </summary> public DebuggeeModuleInfo TryGetBaselineModuleInfo(Guid mvid) { Contract.ThrowIfFalse(Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA); return(_baselineMetadata.GetOrAdd(mvid, m => { using (DebuggerComponent.ManagedEditAndContinueService()) { var clrModuleInstance = FindClrModuleInstance(m); if (clrModuleInstance == null) { return default; } if (!TryGetBaselineModuleInfo(clrModuleInstance, out var metadata, out var symReader)) { return default; } // hook up a callback on module unload (the call blocks until the message is processed): DkmCustomMessage.Create( Connection: clrModuleInstance.Process.Connection, Process: clrModuleInstance.Process, SourceId: DebuggerService.MessageSourceId, MessageCode: 0, Parameter1: this, Parameter2: clrModuleInstance).SendLower(); return new DebuggeeModuleInfo(metadata, symReader); }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { var process = customMessage.Process; if (customMessage.MessageCode == MessageToLocalWorker.fetchLuaSymbols) { var moduleUniqueId = new Guid(customMessage.Parameter1 as byte[]); var nativeModuleInstance = process.GetNativeRuntimeInstance().GetNativeModuleInstances().FirstOrDefault(el => el.UniqueId == moduleUniqueId); if (nativeModuleInstance == null) { return(null); } // Check if Lua library is loaded ulong luaNewState = AttachmentHelpers.TryGetFunctionAddress(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0); ulong luaLibNewState = AttachmentHelpers.TryGetFunctionAddress(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0); if (luaNewState != 0 || luaLibNewState != 0) { var locations = new LuaLocationsMessage(); locations.luaExecuteAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaV_execute", out _).GetValueOrDefault(0); locations.luaExecuteAtEnd = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "luaV_execute", out _).GetValueOrDefault(0); if (luaNewState != 0) { locations.luaNewStateAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0); locations.luaNewStateAtEnd = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "lua_newstate", out _).GetValueOrDefault(0); } else { locations.luaNewStateAtStart = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0); locations.luaNewStateAtEnd = AttachmentHelpers.TryGetFunctionAddressAtDebugEnd(nativeModuleInstance, "luaL_newstate", out _).GetValueOrDefault(0); } locations.luaClose = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_close", out _).GetValueOrDefault(0); locations.closeState = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "close_state", out _).GetValueOrDefault(0); locations.luaLoadFileEx = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadfilex", out _).GetValueOrDefault(0); locations.luaLoadFile = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadfile", out _).GetValueOrDefault(0); locations.solCompatLoadFileEx = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "kp_compat53L_loadfilex", out _).GetValueOrDefault(0); locations.luaLoadBufferEx = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadbufferx", out _).GetValueOrDefault(0); locations.luaLoadBuffer = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaL_loadbuffer", out _).GetValueOrDefault(0); locations.luaLoad = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "lua_load", out _).GetValueOrDefault(0); locations.luaError = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaB_error", out _).GetValueOrDefault(0); locations.luaRunError = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaG_runerror", out _).GetValueOrDefault(0); locations.luaThrow = AttachmentHelpers.TryGetFunctionAddressAtDebugStart(nativeModuleInstance, "luaD_throw", out _).GetValueOrDefault(0); return(DkmCustomMessage.Create(process.Connection, process, MessageToLocal.guid, MessageToLocal.luaSymbols, locations.Encode(), null)); } } return(null); }
private DkmCustomMessage Handle(DkmCustomMessage customMessage) { var requestSerializer = _messageSerializers[customMessage.MessageCode]; var requestData = (byte[])customMessage.Parameter1; var request = (IMessage)requestSerializer.ReadObject(new MemoryStream(requestData, false)); return(request.Handle(customMessage.Process)); }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { var provider = (VisualStudioDebuggeeModuleMetadataProvider)customMessage.Parameter1; var clrModuleInstance = (DkmClrModuleInstance)customMessage.Parameter2; // Note that this call has to be made in a Concord component. // The debugger tracks what the current Concord component is and associates the data item with it. clrModuleInstance.SetDataItem(DkmDataCreationDisposition.CreateAlways, new DataItem(provider, clrModuleInstance.Mvid)); return(null); }
/// <summary> /// Called by the debugger when a debugging session starts and managed debugging is being used. /// </summary> public void StartDebugging() { // Hook up a callbacks (the call blocks until the message is processed). using (DebuggerComponent.ManagedEditAndContinueService()) { DkmCustomMessage.Create( Connection: null, Process: null, SourceId: DebuggerService.MessageSourceId, MessageCode: 0, Parameter1: this, Parameter2: null).SendLower(); } _debuggingService.OnBeforeDebuggingStateChanged(DebuggingState.Design, DebuggingState.Run); _encService.StartDebuggingSession(); }
public DkmCustomMessage SendLower(DkmCustomMessage customMessage) { try { Debug.Assert(customMessage.SourceId == PackageServices.VsDebuggerMessageGuid); VsDebuggerMessage code = (VsDebuggerMessage)customMessage.MessageCode; switch (code) { case VsDebuggerMessage.EnableChildProcessDebugging: Guid processGuid = (Guid)customMessage.Parameter1; DkmProcess process = DkmProcess.FindProcess(processGuid); if (process != null) { process.SetDataItem( DkmDataCreationDisposition.CreateNew, new RuntimeBreakpointHandler()); process.SetDataItem( DkmDataCreationDisposition.CreateNew, new AutoAttachToChildHandler()); Logger.LogInfo( "Successfully delay-enabled child debugging for process {0}.", processGuid); } else { Logger.LogError( "Unable to find process {0} while trying to enable child process debugging.", processGuid); } break; default: Logger.LogError("Debug component received unknown message code {0}.", code); break; } } catch (DkmException exception) { Logger.LogError( exception, "An error occurred while handling a debugger message. HR = 0x{0:X}", exception.HResult); } return(null); }
public DkmCustomMessage SendLower(DkmCustomMessage message) { object result; byte[] bytes; MessageCodes messageCode = (MessageCodes)message.MessageCode; try { bytes = (byte[])message.Parameter1; result = ProcessMessage(messageCode, bytes); } catch (Exception e) { result = e.ToString(); messageCode = MessageCodes.Exception; } bytes = MessageSerializer.Serialize(result); return(DkmCustomMessage.Create(message.Connection, message.Process, Guid.Empty, (int)messageCode, bytes, null)); }
void createProcessTracer_OnFunctionExited( DkmStackWalkFrame frame, StackFrameAnalyzer frameAnalyzer) { try { ulong processInfoAddr = Convert.ToUInt64( frameAnalyzer.GetArgumentValue(frame, "lpProcessInformation")); // Check the return address first, it should be in EAX. CreateProcessAsUser and // CreateProcess both return 0 on failure. If the function failed, there is no child to // attach to. if (0 == frame.VscxGetRegisterValue32(CpuRegister.Eax)) { return; } // The process was successfully created. Extract the PID from the PROCESS_INFORMATION // output param. An attachment request must happend through the EnvDTE, which can only // be accessed from the VsPackage, so a request must be sent via a component message. DkmProcess process = frame.Process; int size = Marshal.SizeOf(typeof(PROCESS_INFORMATION)); byte[] buffer = new byte[size]; process.ReadMemory(processInfoAddr, DkmReadMemoryFlags.None, buffer); PROCESS_INFORMATION info = MarshalUtility.ByteArrayToStructure <PROCESS_INFORMATION>(buffer); DkmCustomMessage attachRequest = DkmCustomMessage.Create( process.Connection, process, PackageServices.VsPackageMessageGuid, (int)VsPackageMessage.AttachToChild, process.LivePart.Id, info.dwProcessId); attachRequest.SendToVsService(PackageServices.DkmComponentEventHandler, false); } catch (Exception exception) { Logger.LogError( exception, "An error occured handling the exit breakpoint. HR = 0x{0:X}", exception.HResult); } }
/// <summary> /// Finds a module of given MVID in one of the processes being debugged and returns its baseline metadata. /// Shall only be called while in debug mode. /// Shall only be called on MTA thread. /// </summary> /// <returns>Null, if the module with the specified MVID is not found.</returns> public DebuggeeModuleInfo TryGetBaselineModuleInfo(Guid mvid) { Contract.ThrowIfFalse(Thread.CurrentThread.GetApartmentState() == ApartmentState.MTA); return(_baselineMetadata.GetOrAdd(mvid, m => { using (DebuggerComponent.ManagedEditAndContinueService()) { var clrModuleInstance = EnumerateClrModuleInstances(m).FirstOrDefault(); if (clrModuleInstance == null) { return null; } // The DebuggeeModuleInfo holds on a pointer to module metadata and on a SymReader instance. // // The module metadata lifetime is that of the module instance, so we need to stop using the module // as soon as the module instance is unloaded. We do so by associating a DataItem with the module // instance and removing the metadata from our cache when the DataItem is disposed. // // The SymReader instance is shared across all instancese of the module. if (!clrModuleInstance.TryGetModuleInfo(out var info)) { return null; } // hook up a callback on module unload (the call blocks until the message is processed): DkmCustomMessage.Create( Connection: clrModuleInstance.Process.Connection, Process: clrModuleInstance.Process, SourceId: DebuggerService.MessageSourceId, MessageCode: 0, Parameter1: this, Parameter2: clrModuleInstance).SendLower(); return info; }
public DkmCustomMessage SendLower(DkmCustomMessage customMessage) { try { Debug.Assert(customMessage.SourceId == PackageServices.VsDebuggerMessageGuid); VsDebuggerMessage code = (VsDebuggerMessage)customMessage.MessageCode; switch (code) { case VsDebuggerMessage.EnableChildProcessDebugging: Guid processGuid = (Guid)customMessage.Parameter1; DkmProcess process = DkmProcess.FindProcess(processGuid); if (process != null) { process.SetDataItem( DkmDataCreationDisposition.CreateNew, new RuntimeBreakpointHandler()); process.SetDataItem( DkmDataCreationDisposition.CreateNew, new AutoAttachToChildHandler()); Logger.Log( "Successfully delay-enabled child debugging for process {0}.", processGuid); } else { Logger.LogError( "Unable to find process {0} while trying to enable child process debugging.", processGuid); } break; default: Logger.LogError("Debug component received unknown message code {0}.", code); break; } } catch (DkmException exception) { Logger.LogException( exception, "An error occurred while handling a debugger message. HR = 0x{0:X}", exception.HResult); } return null; }
void IDkmProcessExecutionNotification.OnProcessPause(DkmProcess process, DkmProcessExecutionCounters processCounters) { try { ulong?moduleBaseOpt = DebugHelpers.ReadPointerVariable(process, "nullcModuleStartAddress"); // Check if nullc is available if (moduleBaseOpt == null) { return; } var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(process); if (processData.language == null) { processData.compilerId = new DkmCompilerId(DebugHelpers.NullcCompilerGuid, DebugHelpers.NullcLanguageGuid); processData.language = DkmLanguage.Create("nullc", processData.compilerId); } // Create VM runtime and module if (processData.vmRuntimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(DebugHelpers.NullcVmRuntimeGuid, 0); processData.vmRuntimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } if (processData.vmModule == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), DebugHelpers.NullcSymbolProviderGuid); processData.vmModule = DkmModule.Create(moduleId, "nullc.vm.code", processData.compilerId, process.Connection, null); } if (processData.vmModuleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(DebugHelpers.NullcSymbolProviderGuid); processData.vmModuleInstance = DkmCustomModuleInstance.Create("nullc_vm", "nullc.vm.code", 0, processData.vmRuntimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 0, 1, 0, "nullc vm code", false, null, null, null); processData.vmModuleInstance.SetModule(processData.vmModule, true); // Can use reload? } ulong moduleBase = moduleBaseOpt.GetValueOrDefault(0); uint moduleSize = (uint)(DebugHelpers.ReadPointerVariable(process, "nullcModuleEndAddress").GetValueOrDefault(0) - moduleBase); // Create JiT runtime and module if (moduleBase != 0 && moduleSize != 0) { if (processData.runtimeInstance == null && processData.nativeRuntimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(DebugHelpers.NullcRuntimeGuid, 0); if (DebugHelpers.useNativeInterfaces) { processData.nativeRuntimeInstance = DebugHelpers.useDefaultRuntimeInstance ? process.GetNativeRuntimeInstance() : DkmNativeRuntimeInstance.Create(process, runtimeId, DkmRuntimeCapabilities.None, process.GetNativeRuntimeInstance(), null); } else { processData.runtimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } } if (processData.module == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), DebugHelpers.NullcSymbolProviderGuid); processData.module = DkmModule.Create(moduleId, "nullc.embedded.code", processData.compilerId, process.Connection, null); } if (processData.moduleInstance == null && processData.nativeModuleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(DebugHelpers.NullcSymbolProviderGuid); if (DebugHelpers.useNativeInterfaces) { processData.nativeModuleInstance = DkmNativeModuleInstance.Create("nullc", "nullc.embedded.code", 0, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 1, "nullc embedded code", processData.nativeRuntimeInstance, moduleBase, moduleSize, Microsoft.VisualStudio.Debugger.Clr.DkmClrHeaderStatus.NativeBinary, false, null, null, null); processData.nativeModuleInstance.SetModule(processData.module, true); // Can use reload? } else { processData.moduleInstance = DkmCustomModuleInstance.Create("nullc", "nullc.embedded.code", 0, processData.runtimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, moduleBase, 1, moduleSize, "nullc embedded code", false, null, null, null); processData.moduleInstance.SetModule(processData.module, true); // Can use reload? } } } // Update bytecode var moduleBytecodeVersion = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeVersion").GetValueOrDefault(0); if (processData.moduleBytecodeLocation != 0 && moduleBytecodeVersion != processData.moduleBytecodeVersion) { processData.moduleBytecodeLocation = 0; processData.moduleBytecodeSize = 0; processData.moduleBytecodeRaw = null; processData.bytecode = null; } if (processData.moduleBytecodeLocation == 0) { processData.moduleBytecodeLocation = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeLocation").GetValueOrDefault(0); processData.moduleBytecodeSize = DebugHelpers.ReadPointerVariable(process, "nullcModuleBytecodeSize").GetValueOrDefault(0); processData.moduleBytecodeVersion = moduleBytecodeVersion; if (processData.moduleBytecodeLocation != 0) { processData.moduleBytecodeRaw = new byte[processData.moduleBytecodeSize]; process.ReadMemory(processData.moduleBytecodeLocation, DkmReadMemoryFlags.None, processData.moduleBytecodeRaw); processData.bytecode = new NullcBytecode(); processData.bytecode.ReadFrom(processData.moduleBytecodeRaw, DebugHelpers.Is64Bit(process)); // Notify local component about bytecode update var message = DkmCustomMessage.Create(process.Connection, process, DebugHelpers.NullcReloadSymbolsMessageGuid, 1, null, null); message.SendHigher(); } } } catch (Exception ex) { Console.WriteLine("OnProcessPause failed with: " + ex.ToString()); } }
DkmCustomMessage IDkmCustomMessageCallbackReceiver.SendHigher(DkmCustomMessage customMessage) { return((customMessage.SourceId == _sourceId) ? Handle(customMessage) : null); }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { return((customMessage.SourceId == _sourceId) ? Handle(customMessage) : null); }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { var process = customMessage.Process; var processData = DebugHelpers.GetOrCreateDataItem <LuaRemoteProcessData>(process); if (customMessage.MessageCode == MessageToRemote.createRuntime) { if (processData.language == null) { processData.compilerId = new DkmCompilerId(Guids.luaCompilerGuid, Guids.luaLanguageGuid); processData.language = DkmLanguage.Create("Lua", processData.compilerId); } if (processData.runtimeInstance == null) { DkmRuntimeInstanceId runtimeId = new DkmRuntimeInstanceId(Guids.luaRuntimeGuid, 0); processData.runtimeInstance = DkmCustomRuntimeInstance.Create(process, runtimeId, null); } if (processData.module == null) { DkmModuleId moduleId = new DkmModuleId(Guid.NewGuid(), Guids.luaSymbolProviderGuid); processData.module = DkmModule.Create(moduleId, "lua.vm.code", processData.compilerId, process.Connection, null); } if (processData.moduleInstance == null) { DkmDynamicSymbolFileId symbolFileId = DkmDynamicSymbolFileId.Create(Guids.luaSymbolProviderGuid); processData.moduleInstance = DkmCustomModuleInstance.Create("lua_vm", "lua.vm.code", 0, processData.runtimeInstance, null, symbolFileId, DkmModuleFlags.None, DkmModuleMemoryLayout.Unknown, 0, 1, 0, "Lua vm code", false, null, null, null); processData.moduleInstance.SetModule(processData.module, true); // Can use reload? } } else if (customMessage.MessageCode == MessageToRemote.luaHelperDataLocations) { var data = new HelperLocationsMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); processData.locations = data; } else if (customMessage.MessageCode == MessageToRemote.pauseBreakpoints) { processData.pauseBreakpoints = true; } else if (customMessage.MessageCode == MessageToRemote.resumeBreakpoints) { processData.pauseBreakpoints = false; } else if (customMessage.MessageCode == MessageToRemote.luaVersionInfo) { processData.luaVersion = (customMessage.Parameter1 as int?).GetValueOrDefault(0); LuaHelpers.luaVersion = processData.luaVersion; } else if (customMessage.MessageCode == MessageToRemote.registerLuaState) { var data = new RegisterStateMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); Debug.Assert(processData.knownStates.ContainsKey(data.stateAddress) == false); if (processData.knownStates.ContainsKey(data.stateAddress)) { Debug.WriteLine("IDkmCustomMessageForwardReceiver.SendLower() Duplicate Lua state registration, destruction was probably missed!"); } else { processData.knownStates.Add(data.stateAddress, data); if (processData.hooksEnabled) { SetupHooks(process, processData); } } } else if (customMessage.MessageCode == MessageToRemote.unregisterLuaState) { var data = new UnregisterStateMessage(); data.ReadFrom(customMessage.Parameter1 as byte[]); // Registration is called only for states that can be hooked, unregistration is always called if (processData.knownStates.ContainsKey(data.stateAddress)) { processData.knownStates.Remove(data.stateAddress); } } return(null); }
void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint runtimeBreakpoint, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor) { var process = thread.Process; var processData = DebugHelpers.GetOrCreateDataItem <LuaRemoteProcessData>(process); if (runtimeBreakpoint.SourceId == Guids.luaSupportBreakpointGuid) { if (processData.locations != null) { if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperBreakpointHit) { // Breakpoint can get hit again after expression evaluation 'slips' the thread if (processData.pauseBreakpoints) { return; } eventDescriptor.Suppress(); var breakpointPos = DebugHelpers.ReadUintVariable(process, processData.locations.helperBreakHitIdAddress); if (!breakpointPos.HasValue) { return; } if (breakpointPos.Value < processData.activeBreakpoints.Count) { try { var breakpoint = processData.activeBreakpoints[(int)breakpointPos.Value]; if (breakpoint.runtimeBreakpoint != null) { breakpoint.runtimeBreakpoint.OnHit(thread, false); } } catch (System.ObjectDisposedException) { // Breakpoint was implicitly closed processData.activeBreakpoints.RemoveAt((int)breakpointPos.Value); } catch (DkmException) { // In case another component evaluates a function } } return; } else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepComplete) { if (processData.activeStepper != null) { var activeStepper = processData.activeStepper; ClearStepperData(process, processData); activeStepper.OnStepComplete(thread, false); } return; } else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepInto) { if (processData.activeStepper != null) { var activeStepper = processData.activeStepper; ClearStepperData(process, processData); activeStepper.OnStepComplete(thread, false); } return; } else if (runtimeBreakpoint.UniqueId == processData.locations.breakpointLuaHelperStepOut) { if (processData.activeStepper != null) { var activeStepper = processData.activeStepper; ClearStepperData(process, processData); activeStepper.OnStepComplete(thread, false); } return; } } thread.GetCurrentFrameInfo(out ulong retAddr, out ulong frameBase, out ulong vframe); var data = new SupportBreakpointHitMessage { breakpointId = runtimeBreakpoint.UniqueId, threadId = thread.UniqueId, retAddr = retAddr, frameBase = frameBase, vframe = vframe }; var message = DkmCustomMessage.Create(process.Connection, process, MessageToLocal.guid, MessageToLocal.luaSupportBreakpointHit, data.Encode(), null); var response = message.SendHigher(); if (response?.MessageCode == MessageToRemote.throwException) { if (runtimeBreakpoint is DkmRuntimeInstructionBreakpoint runtimeInstructionBreakpoint) { var exceptionInformation = DkmCustomExceptionInformation.Create(processData.runtimeInstance, Guids.luaExceptionGuid, thread, runtimeInstructionBreakpoint.InstructionAddress, "LuaError", 0, DkmExceptionProcessingStage.Thrown | DkmExceptionProcessingStage.UserVisible | DkmExceptionProcessingStage.Unhandled, null, new ReadOnlyCollection <byte>(response.Parameter1 as byte[])); exceptionInformation.OnDebugMonitorException(); } } } }
DkmCustomMessage IDkmCustomMessageForwardReceiver.SendLower(DkmCustomMessage customMessage) { _listener = (VisualStudioDebugStateChangeListener)customMessage.Parameter1; return(null); }