Index: experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/BreakpointInfo.cs |
diff --git a/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/BreakpointInfo.cs b/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/BreakpointInfo.cs |
deleted file mode 100644 |
index ab0c32338ee5a9f82b38e19e66deac3482377bf7..0000000000000000000000000000000000000000 |
--- a/experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/BreakpointInfo.cs |
+++ /dev/null |
@@ -1,269 +0,0 @@ |
-// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#region |
- |
-using System.Collections.Generic; |
-using System.IO; |
-using System.Linq; |
-using Google.MsAd7.BaseImpl; |
-using Google.MsAd7.BaseImpl.Ad7Enumerators; |
-using Google.MsAd7.BaseImpl.Interfaces; |
-using Google.NaClVsx.DebugSupport.DWARF; |
-using Microsoft.VisualStudio; |
-using Microsoft.VisualStudio.Debugger.Interop; |
-using NaClVsx; |
- |
-#endregion |
- |
-namespace Google.NaClVsx.DebugSupport { |
- /// <summary> |
- /// Provides address and code look-ups specific to breakpoint operations. |
- /// </summary> |
- public class BreakpointInfo : IBreakpointInfo { |
- #region constants |
- |
- public const int kBindErrorWarning = 2; |
- |
- #endregion |
- |
- public BreakpointInfo(SymbolDatabase database, |
- ISimpleSymbolProvider symbolProvider) { |
- database_ = database; |
- symbolProvider_ = symbolProvider; |
- } |
- |
- #region IBreakpointInfo Members |
- |
- /// <summary> |
- /// This function can be called to determine what errors would occur if |
- /// an attempt were made to bind a breakpoint at a given location. |
- /// </summary> |
- /// <param name = "pos"> |
- /// The position at which a breakpoint is being considered. |
- /// </param> |
- /// <param name = "ppErrorEnum"> |
- /// Any errors that might be encountered if an attempt was made to set a |
- /// breakpoint at the current location. |
- /// </param> |
- /// <returns>Whether or not the function successfully checked for errors. |
- /// </returns> |
- public int GetBindErrors(DocumentPosition pos, |
- out IEnumDebugErrorBreakpoints2 ppErrorEnum) { |
- IEnumerable<ulong> addresses; |
- return GetBindAddresses(pos, out addresses, out ppErrorEnum); |
- } |
- |
- /// <summary> |
- /// This function exists separately from AddressFromPosition because the debugger needs |
- /// different rules for matching addresses. If no address is found that matches "position" |
- /// exactly, this function will return addresses for the next appropriate position if there |
- /// is one. |
- /// </summary> |
- /// <param name = "msvcPosition">The position in the source code where the user is trying to |
- /// set a breakpoint. Since this is supplied by msvc, it's 0-indexed</param> |
- /// <param name = "outAddresses">Any memory addresses that can be appropriately mapped to |
- /// position</param> |
- /// <param name = "outErrorEnum">Any errors encountered while this breakpoint was being set. |
- /// </param> |
- /// <returns>If the breakpoint was set successfully at the exact location requested, this |
- /// function returns VSConstants.S_OK. If the breakpoint was set in a different location, |
- /// the function returns kBindErrorWarning. If the breakpoint cannot be set at all, it |
- /// returns S_FALSE.</returns> |
- public int GetBindAddresses(DocumentPosition msvcPosition, |
- out IEnumerable<ulong> outAddresses, |
- out IEnumDebugErrorBreakpoints2 outErrorEnum) { |
- var addressesBound = VSConstants.S_FALSE; |
- outAddresses = new List<ulong>(); |
- var addresses = outAddresses as List<ulong>; |
- outErrorEnum = new ErrorBreakpointEnumerator(); |
- var breakpointErrorEnum = outErrorEnum as ErrorBreakpointEnumerator; |
- |
- var fileName = GetFileName(msvcPosition); |
- if (fileName != null) { |
- var files = |
- database_.SourceFilesByFilename[fileName]; |
- |
- if (files.Count() >= 1) { |
- var file = files.First(); |
- // Remember the path that was passed in, since that's where |
- // the current debugging session knows where to find this |
- // file |
- file.CurrentAbsolutePath = msvcPosition.Path; |
- |
- // Internally, MSVC uses zero-based lines. This is in contrast |
- // to both DWARF and MSVC's own user interface, but whatever. |
- var line = |
- NaClSymbolProvider.GetDwarfLineIndex(msvcPosition.BeginPos.dwLine); |
- var locations = |
- GetBreakpointLocations(file, line); |
- |
- foreach (var loc in locations) { |
- var address = loc.StartAddress + symbolProvider_.GetBaseAddress(); |
- addresses.Add(address); |
- |
- var documentContext = new DocumentContext( |
- msvcPosition.Path, |
- NaClSymbolProvider.GetMSVCLineIndex(loc.Line), |
- loc.Column); |
- |
- // The check decides whether we move the breakpoint to compensate for user |
- // error. We have to get the addresses first because they are needed for the |
- // code context part of the error. |
- if (loc.Line != line) { |
- var resolution = new ErrorBreakpointResolution(); |
- resolution.Type = enum_BP_ERROR_TYPE.BPET_SEV_LOW | |
- enum_BP_ERROR_TYPE.BPET_TYPE_WARNING; |
- |
- resolution.SetLocation( |
- enum_BP_TYPE.BPT_CODE, address, documentContext); |
- resolution.Message = "Had to move breakpoint to a different line."; |
- |
- var breakpointError = new ErrorBreakpoint(resolution); |
- breakpointErrorEnum.Insert(breakpointError); |
- } |
- } |
- |
- uint count; |
- var getCountSuccess = outErrorEnum.GetCount(out count); |
- if (getCountSuccess == VSConstants.S_OK && count > 0) { |
- addressesBound = kBindErrorWarning; |
- } else { |
- addressesBound = VSConstants.S_OK; |
- } |
- } |
- } |
- |
- // There are any number of reasons why this could have failed completely |
- if (addresses.Count() == 0) { |
- var resolution = new ErrorBreakpointResolution(); |
- resolution.Type = enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR; |
- resolution.Message = |
- "Could not set a breakpoint at the requested location."; |
- var error = new ErrorBreakpoint(resolution); |
- breakpointErrorEnum.Insert(error); |
- addressesBound = VSConstants.S_FALSE; |
- } |
- return addressesBound; |
- } |
- |
- #endregion |
- |
- #region Private Implementation |
- |
- private readonly SymbolDatabase database_; |
- private readonly ISimpleSymbolProvider symbolProvider_; |
- |
- #endregion |
- |
- #region Private Implementation |
- |
- /// <summary> |
- /// This function retrieves plausible code locations for the given |
- /// breakpoint information. |
- /// </summary> |
- /// <param name = "file"></param> |
- /// <param name = "line"></param> |
- /// <returns></returns> |
- private IEnumerable<SymbolDatabase.SourceLocation> GetBreakpointLocations( |
- SymbolDatabase.SourceFile file, |
- uint line) { |
- IEnumerable<SymbolDatabase.SourceLocation> finalLocations = |
- new List<SymbolDatabase.SourceLocation>(); |
- |
- // This will match any lines of code in a compatible scope at or after the |
- // line where the breakpoint was requested. |
- var locationGuesses = |
- new Dictionary<ulong, List<SymbolDatabase.SourceLocation>>(); |
- foreach (var loc in database_.LocationsByFile[file.Key]) { |
- if (IsSuitableBreakpoint(loc, line)) { |
- if (!locationGuesses.ContainsKey(loc.Line)) { |
- locationGuesses.Add( |
- loc.Line, new List<SymbolDatabase.SourceLocation>()); |
- } |
- locationGuesses[loc.Line].Add(loc); |
- } |
- } |
- |
- if (locationGuesses.Count() > 0) { |
- var locationLines = new List<ulong>(); |
- locationLines.AddRange(locationGuesses.Keys); |
- locationLines.Sort(); |
- finalLocations = locationGuesses[locationLines.First()]; |
- } |
- |
- return finalLocations; |
- } |
- |
- /// <summary> |
- /// Gets the name of hte file that contains |position|. |
- /// </summary> |
- /// <param name = "position"> |
- /// The position whose file name is needed. |
- /// </param> |
- /// <returns> |
- /// Returns the name of the file that contains |position|. |
- /// </returns> |
- private string GetFileName(DocumentPosition position) { |
- string rValue = null; |
- var fileName = Path.GetFileName(position.Path); |
- if (fileName != null) { |
- if (database_.SourceFilesByFilename.ContainsKey(fileName)) { |
- rValue = fileName; |
- } |
- } |
- return rValue; |
- } |
- |
- /// <summary> |
- /// This function checks whether a given |location| would make a |
- /// suitable breakpoint for a |originalLine| of code the user requested. |
- /// In order to qualify the location must be either equal to or greater |
- /// than the requested line of code and must be in the same scope. |
- /// The caller of this function will then have to resolve the suitable |
- /// location that is closest to what the user requested. |
- /// </summary> |
- /// <param name = "location"> |
- /// A source code location to examine as a possible breakpoint location. |
- /// </param> |
- /// <param name = "originalLine"> |
- /// The line at which the user wants to set the breakpoint. |
- /// </param> |
- /// <returns> |
- /// |true| iff the location could serve as a breakpoint location. |
- /// </returns> |
- private bool IsSuitableBreakpoint(SymbolDatabase.SourceLocation location, |
- uint originalLine) { |
- var suitableBreakpoint = false; |
- |
- if (location.Line >= originalLine) { |
- // This could be suitable breakpoint if the current location's |
- // line is in the same scope as the original line. |
- var scope = |
- database_.GetScopeForAddress(location.StartAddress); |
- |
- var sortedLocationsInScope = |
- database_.GetLocationsByLine(scope, location.StartAddress); |
- if (sortedLocationsInScope.First().Line <= originalLine) { |
- suitableBreakpoint = true; |
- } else if (scope.Tag == DwarfTag.DW_TAG_catch_block || |
- scope.Tag == DwarfTag.DW_TAG_try_block || |
- scope.Tag == DwarfTag.DW_TAG_lexical_block) { |
- // This could still be a suitable breakpoint if this scope entry |
- // is for a subscope of a function that begins before the |
- // original line. |
- var outerScope = scope.OuterScope; |
- var sortedLocationsInOuterScope = |
- database_.GetLocationsByLine(outerScope, location.StartAddress); |
- if (sortedLocationsInOuterScope.First().Line <= originalLine) { |
- suitableBreakpoint = true; |
- } |
- } |
- } |
- return suitableBreakpoint; |
- } |
- |
- #endregion |
- } |
-} |