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;
}