protected override BreakEventInfo OnInsertBreakEvent (BreakEvent ev) { if (exited) return null; var bi = new BreakInfo (); if (ev is FunctionBreakpoint) { var fb = (FunctionBreakpoint) ev; bool generic; bi.Location = FindLocationByFunction (fb.FunctionName, fb.ParamTypes, fb.Line, out generic); if (bi.Location != null) { fb.SetResolvedFileName (bi.Location.SourceFile); bi.FileName = fb.FileName; InsertBreakpoint (fb, bi); bi.SetStatus (BreakEventStatus.Bound, null); // Note: if the type or method is generic, there may be more instances so don't assume we are done resolving the breakpoint if (generic) pending_bes.Add (bi); } else { int dot = fb.FunctionName.LastIndexOf ('.'); if (dot != -1) bi.TypeName = fb.FunctionName.Substring (0, dot); pending_bes.Add (bi); bi.SetStatus (BreakEventStatus.NotBound, null); } } else if (ev is Breakpoint) { var bp = (Breakpoint) ev; bool insideLoadedRange; bool generic; bi.Location = FindLocationByFile (bp.FileName, bp.Line, out generic, out insideLoadedRange); bi.FileName = bp.FileName; if (bi.Location != null) { InsertBreakpoint (bp, bi); bi.SetStatus (BreakEventStatus.Bound, null); // Note: if the type or method is generic, there may be more instances so don't assume we are done resolving the breakpoint if (generic) pending_bes.Add (bi); } else { pending_bes.Add (bi); if (insideLoadedRange) bi.SetStatus (BreakEventStatus.Invalid, null); else bi.SetStatus (BreakEventStatus.NotBound, null); } } else if (ev is Catchpoint) { var cp = (Catchpoint) ev; TypeMirror type; if (!types.TryGetValue (cp.ExceptionName, out type)) { // // Same as in FindLocationByFile (), fetch types matching the type name if (vm.Version.AtLeast (2, 9)) { foreach (TypeMirror t in vm.GetTypes (cp.ExceptionName, false)) ProcessType (t); } } if (types.TryGetValue (cp.ExceptionName, out type)) { InsertCatchpoint (cp, bi, type); bi.SetStatus (BreakEventStatus.Bound, null); } else { bi.TypeName = cp.ExceptionName; pending_bes.Add (bi); bi.SetStatus (BreakEventStatus.NotBound, null); } } /* * TypeLoad events lead to too much wire traffic + suspend/resume work, so * filter them using the file names used by pending breakpoints. */ if (vm.Version.AtLeast (2, 9)) { var sourceFileList = pending_bes.Where (b => b.FileName != null).Select (b => b.FileName).ToArray (); if (sourceFileList.Length > 0) { //HACK: explicitly try lowercased drivename on windows, since csc (when not hosted in VS) lowercases //the drivename in the pdb files that get converted to mdbs as-is //FIXME: we should really do a case-insensitive request on Win/Mac, when sdb supports that if (IsWindows) { int originalCount = sourceFileList.Length; Array.Resize (ref sourceFileList, originalCount * 2); for (int i = 0; i < originalCount; i++) { string n = sourceFileList[i]; sourceFileList[originalCount + i] = char.ToLower (n[0]) + n.Substring (1); } } if (typeLoadReq == null) { typeLoadReq = vm.CreateTypeLoadRequest (); } typeLoadReq.Enabled = false; typeLoadReq.SourceFileFilter = sourceFileList; typeLoadReq.Enabled = true; } var typeNameList = pending_bes.Where (b => b.TypeName != null).Select (b => b.TypeName).ToArray (); if (typeNameList.Length > 0) { // Use a separate request since the filters are ANDed together if (typeLoadTypeNameReq == null) { typeLoadTypeNameReq = vm.CreateTypeLoadRequest (); } typeLoadTypeNameReq.Enabled = false; typeLoadTypeNameReq.TypeNameFilter = typeNameList; typeLoadTypeNameReq.Enabled = true; } } return bi; }
protected override BreakEventInfo OnInsertBreakEvent (BreakEvent ev) { if (exited) return null; var bi = new BreakInfo (); if (ev is Breakpoint) { var bp = (Breakpoint) ev; bool inisideLoadedRange; bi.FileName = bp.FileName; bi.Location = FindLocation (bp.FileName, bp.Line, out inisideLoadedRange); if (bi.Location != null) { InsertBreakpoint (bp, bi); bi.SetStatus (BreakEventStatus.Bound, null); } else { pending_bes.Add (bi); if (inisideLoadedRange) bi.SetStatus (BreakEventStatus.Invalid, null); else bi.SetStatus (BreakEventStatus.NotBound, null); } } else if (ev is Catchpoint) { var cp = (Catchpoint) ev; TypeMirror type; if (!types.TryGetValue (cp.ExceptionName, out type)) { // // Same as in FindLocation (), fetch types matching the type name if (vm.Version.AtLeast (2, 9)) { foreach (TypeMirror t in vm.GetTypes (cp.ExceptionName, false)) ProcessType (t); } } if (types.TryGetValue (cp.ExceptionName, out type)) { InsertCatchpoint (cp, bi, type); bi.SetStatus (BreakEventStatus.Bound, null); } else { bi.ExceptionName = cp.ExceptionName; pending_bes.Add (bi); bi.SetStatus (BreakEventStatus.NotBound, null); } } /* * TypeLoad events lead to too much wire traffic + suspend/resume work, so * filter them using the file names used by pending breakpoints. */ if (vm.Version.AtLeast (2, 9)) { var sourceFileList = pending_bes.Where (b => b.FileName != null).Select (b => b.FileName).ToArray (); if (sourceFileList.Length > 0) { if (typeLoadReq == null) { typeLoadReq = vm.CreateTypeLoadRequest (); } typeLoadReq.Enabled = false; typeLoadReq.SourceFileFilter = sourceFileList; typeLoadReq.Enabled = true; } var typeNameList = pending_bes.Where (b => b.ExceptionName != null).Select (b => b.ExceptionName).ToArray (); if (typeNameList.Length > 0) { // Use a separate request since the filters are ANDed together if (typeLoadTypeNameReq == null) { typeLoadTypeNameReq = vm.CreateTypeLoadRequest (); } typeLoadTypeNameReq.Enabled = false; typeLoadTypeNameReq.TypeNameFilter = typeNameList; typeLoadTypeNameReq.Enabled = true; } } return bi; }