private void OnAssemblyUnload(AssemblyUnloadEvent e)
        {
            _loadedAssemblies.Remove(e.Assembly);

            var wasEnabled = _methodEntryRequest.Enabled;

            _methodEntryRequest.Disable();
            _methodEntryRequest.AssemblyFilter = _loadedAssemblies;
            if (wasEnabled)
            {
                _methodEntryRequest.Enable();
            }

            _breakpointEventRequests = _breakpointEventRequests.Where(kvp => kvp.Key.Method.DeclaringType.Assembly != e.Assembly).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            Trace("AssemblyUnload: {0}", e.Assembly.GetName().FullName);

            AssemblyUnloaded(DebugAssemblyFor(e.Assembly));
        }
Beispiel #2
0
 public virtual void Visit(AssemblyUnloadEvent ev)
 {
 }
        void HandleEvent(Event e, bool dequeuing)
        {
            if (dequeuing && exited)
            {
                return;
            }

            bool         resume    = true;
            ObjectMirror exception = null;

            TargetEventType etype = TargetEventType.TargetStopped;

#if DEBUG_EVENT_QUEUEING
            if (!(e is TypeLoadEvent))
            {
                Console.WriteLine("pp event: " + e);
            }
#endif

            OnHandleEvent(e);

            if (e is AssemblyLoadEvent)
            {
                AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
                bool   isExternal    = !UpdateAssemblyFilters(ae.Assembly) && userAssemblyNames != null;
                string flagExt       = isExternal? " [External]" : "";
                OnDebuggerOutput(false, string.Format("Loaded assembly: {0}{1}\n", ae.Assembly.Location, flagExt));
            }

            if (e is AssemblyUnloadEvent)
            {
                AssemblyUnloadEvent aue = (AssemblyUnloadEvent)e;

                // Mark affected breakpoints as pending again
                List <KeyValuePair <EventRequest, BreakInfo> > affectedBreakpoints = new List <KeyValuePair <EventRequest, BreakInfo> > (
                    breakpoints.Where(x => (x.Value.Location.Method.DeclaringType.Assembly.Location.Equals(aue.Assembly.Location, StringComparison.OrdinalIgnoreCase)))
                    );
                foreach (KeyValuePair <EventRequest, BreakInfo> breakpoint in affectedBreakpoints)
                {
                    OnDebuggerOutput(false, string.Format("Re-pending breakpoint at {0}:{1}\n",
                                                          Path.GetFileName(breakpoint.Value.Location.SourceFile),
                                                          breakpoint.Value.Location.LineNumber));
                    breakpoints.Remove(breakpoint.Key);
                    pending_bes.Add(breakpoint.Value.BreakEvent);
                }

                // Remove affected types from the loaded types list
                List <string> affectedTypes = new List <string>();
                foreach (var pair in types)
                {
                    try {
                        if (!pair.Value.Assembly.Location.Equals(aue.Assembly.Location, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    } catch {
                    }
                    affectedTypes.Add(pair.Key);
                }
                foreach (string typename in affectedTypes)
                {
                    types.Remove(typename);
                }

                foreach (var pair in source_to_type)
                {
                    pair.Value.RemoveAll(delegate(TypeMirror mirror){
                        try {
                            return(mirror.Assembly.Location.Equals(aue.Assembly.Location, StringComparison.OrdinalIgnoreCase));
                        } catch {
                        }
                        return(true);
                    });
                }
                OnDebuggerOutput(false, string.Format("Unloaded assembly: {0}\n", aue.Assembly.Location));
            }

            if (e is VMStartEvent)
            {
                //HACK: 2.6.1 VM doesn't emit type load event, so work around it
                var t = vm.RootDomain.Corlib.GetType("System.Exception", false, false);
                if (t != null)
                {
                    ResolveBreakpoints(t);
                }
                OnVMStartEvent((VMStartEvent)e);
            }

            if (e is TypeLoadEvent)
            {
                var t = ((TypeLoadEvent)e).Type;

                string typeName = t.FullName;

//                if (types.ContainsKey(typeName)) {
//                    if (typeName != "System.Exception")
//                        LoggingService.LogError("Type '" + typeName + "' loaded more than once", null);
//                }
                ResolveBreakpoints(t);
            }

            if (e is BreakpointEvent)
            {
                BreakpointEvent be = (BreakpointEvent)e;
                if (!HandleBreakpoint(e.Thread, be.Request))
                {
                    etype  = TargetEventType.TargetHitBreakpoint;
                    resume = false;
                }
            }

            if (e is ExceptionEvent)
            {
                etype = TargetEventType.ExceptionThrown;
                var ev = (ExceptionEvent)e;
                exception = ev.Exception;
                if (ev.Request != unhandledExceptionRequest || exception.Type.FullName != "System.Threading.ThreadAbortException")
                {
                    resume = false;
                }
            }

            if (e is StepEvent)
            {
                etype  = TargetEventType.TargetStopped;
                resume = false;
            }

            if (e is ThreadStartEvent)
            {
                ThreadStartEvent ts = (ThreadStartEvent)e;
                OnDebuggerOutput(false, string.Format("Thread started: {0}\n", ts.Thread.Name));
            }

            if (resume)
            {
                vm.Resume();
            }
            else
            {
                if (currentStepRequest != null)
                {
                    currentStepRequest.Enabled = false;
                    currentStepRequest         = null;
                }
                current_thread = recent_thread = e.Thread;
                TargetEventArgs args = new TargetEventArgs(etype);
                args.Process   = OnGetProcesses() [0];
                args.Thread    = GetThread(args.Process, current_thread);
                args.Backtrace = GetThreadBacktrace(current_thread);

                if (exception != null)
                {
                    activeExceptionsByThread [current_thread.Id] = exception;
                }

                OnTargetEvent(args);
            }
        }