Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: experimental/visual_studio_plugin/src/NaClVsx.Package/DebugSupport/BreakpointInfo.cs

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #region
6
7 using System.Collections.Generic;
8 using System.IO;
9 using System.Linq;
10 using Google.MsAd7.BaseImpl;
11 using Google.MsAd7.BaseImpl.Ad7Enumerators;
12 using Google.MsAd7.BaseImpl.Interfaces;
13 using Google.NaClVsx.DebugSupport.DWARF;
14 using Microsoft.VisualStudio;
15 using Microsoft.VisualStudio.Debugger.Interop;
16 using NaClVsx;
17
18 #endregion
19
20 namespace Google.NaClVsx.DebugSupport {
21 /// <summary>
22 /// Provides address and code look-ups specific to breakpoint operations.
23 /// </summary>
24 public class BreakpointInfo : IBreakpointInfo {
25 #region constants
26
27 public const int kBindErrorWarning = 2;
28
29 #endregion
30
31 public BreakpointInfo(SymbolDatabase database,
32 ISimpleSymbolProvider symbolProvider) {
33 database_ = database;
34 symbolProvider_ = symbolProvider;
35 }
36
37 #region IBreakpointInfo Members
38
39 /// <summary>
40 /// This function can be called to determine what errors would occur if
41 /// an attempt were made to bind a breakpoint at a given location.
42 /// </summary>
43 /// <param name = "pos">
44 /// The position at which a breakpoint is being considered.
45 /// </param>
46 /// <param name = "ppErrorEnum">
47 /// Any errors that might be encountered if an attempt was made to set a
48 /// breakpoint at the current location.
49 /// </param>
50 /// <returns>Whether or not the function successfully checked for errors.
51 /// </returns>
52 public int GetBindErrors(DocumentPosition pos,
53 out IEnumDebugErrorBreakpoints2 ppErrorEnum) {
54 IEnumerable<ulong> addresses;
55 return GetBindAddresses(pos, out addresses, out ppErrorEnum);
56 }
57
58 /// <summary>
59 /// This function exists separately from AddressFromPosition because the d ebugger needs
60 /// different rules for matching addresses. If no address is found that m atches "position"
61 /// exactly, this function will return addresses for the next appropriate position if there
62 /// is one.
63 /// </summary>
64 /// <param name = "msvcPosition">The position in the source code where the u ser is trying to
65 /// set a breakpoint. Since this is supplied by msvc, it's 0-indexed</par am>
66 /// <param name = "outAddresses">Any memory addresses that can be appropriat ely mapped to
67 /// position</param>
68 /// <param name = "outErrorEnum">Any errors encountered while this breakpoin t was being set.
69 /// </param>
70 /// <returns>If the breakpoint was set successfully at the exact location re quested, this
71 /// function returns VSConstants.S_OK. If the breakpoint was set in a dif ferent location,
72 /// the function returns kBindErrorWarning. If the breakpoint cannot be s et at all, it
73 /// returns S_FALSE.</returns>
74 public int GetBindAddresses(DocumentPosition msvcPosition,
75 out IEnumerable<ulong> outAddresses,
76 out IEnumDebugErrorBreakpoints2 outErrorEnum) {
77 var addressesBound = VSConstants.S_FALSE;
78 outAddresses = new List<ulong>();
79 var addresses = outAddresses as List<ulong>;
80 outErrorEnum = new ErrorBreakpointEnumerator();
81 var breakpointErrorEnum = outErrorEnum as ErrorBreakpointEnumerator;
82
83 var fileName = GetFileName(msvcPosition);
84 if (fileName != null) {
85 var files =
86 database_.SourceFilesByFilename[fileName];
87
88 if (files.Count() >= 1) {
89 var file = files.First();
90 // Remember the path that was passed in, since that's where
91 // the current debugging session knows where to find this
92 // file
93 file.CurrentAbsolutePath = msvcPosition.Path;
94
95 // Internally, MSVC uses zero-based lines. This is in contrast
96 // to both DWARF and MSVC's own user interface, but whatever.
97 var line =
98 NaClSymbolProvider.GetDwarfLineIndex(msvcPosition.BeginPos.dwLine) ;
99 var locations =
100 GetBreakpointLocations(file, line);
101
102 foreach (var loc in locations) {
103 var address = loc.StartAddress + symbolProvider_.GetBaseAddress();
104 addresses.Add(address);
105
106 var documentContext = new DocumentContext(
107 msvcPosition.Path,
108 NaClSymbolProvider.GetMSVCLineIndex(loc.Line),
109 loc.Column);
110
111 // The check decides whether we move the breakpoint to compensate fo r user
112 // error. We have to get the addresses first because they are needed for the
113 // code context part of the error.
114 if (loc.Line != line) {
115 var resolution = new ErrorBreakpointResolution();
116 resolution.Type = enum_BP_ERROR_TYPE.BPET_SEV_LOW |
117 enum_BP_ERROR_TYPE.BPET_TYPE_WARNING;
118
119 resolution.SetLocation(
120 enum_BP_TYPE.BPT_CODE, address, documentContext);
121 resolution.Message = "Had to move breakpoint to a different line." ;
122
123 var breakpointError = new ErrorBreakpoint(resolution);
124 breakpointErrorEnum.Insert(breakpointError);
125 }
126 }
127
128 uint count;
129 var getCountSuccess = outErrorEnum.GetCount(out count);
130 if (getCountSuccess == VSConstants.S_OK && count > 0) {
131 addressesBound = kBindErrorWarning;
132 } else {
133 addressesBound = VSConstants.S_OK;
134 }
135 }
136 }
137
138 // There are any number of reasons why this could have failed completely
139 if (addresses.Count() == 0) {
140 var resolution = new ErrorBreakpointResolution();
141 resolution.Type = enum_BP_ERROR_TYPE.BPET_GENERAL_ERROR;
142 resolution.Message =
143 "Could not set a breakpoint at the requested location.";
144 var error = new ErrorBreakpoint(resolution);
145 breakpointErrorEnum.Insert(error);
146 addressesBound = VSConstants.S_FALSE;
147 }
148 return addressesBound;
149 }
150
151 #endregion
152
153 #region Private Implementation
154
155 private readonly SymbolDatabase database_;
156 private readonly ISimpleSymbolProvider symbolProvider_;
157
158 #endregion
159
160 #region Private Implementation
161
162 /// <summary>
163 /// This function retrieves plausible code locations for the given
164 /// breakpoint information.
165 /// </summary>
166 /// <param name = "file"></param>
167 /// <param name = "line"></param>
168 /// <returns></returns>
169 private IEnumerable<SymbolDatabase.SourceLocation> GetBreakpointLocations(
170 SymbolDatabase.SourceFile file,
171 uint line) {
172 IEnumerable<SymbolDatabase.SourceLocation> finalLocations =
173 new List<SymbolDatabase.SourceLocation>();
174
175 // This will match any lines of code in a compatible scope at or after the
176 // line where the breakpoint was requested.
177 var locationGuesses =
178 new Dictionary<ulong, List<SymbolDatabase.SourceLocation>>();
179 foreach (var loc in database_.LocationsByFile[file.Key]) {
180 if (IsSuitableBreakpoint(loc, line)) {
181 if (!locationGuesses.ContainsKey(loc.Line)) {
182 locationGuesses.Add(
183 loc.Line, new List<SymbolDatabase.SourceLocation>());
184 }
185 locationGuesses[loc.Line].Add(loc);
186 }
187 }
188
189 if (locationGuesses.Count() > 0) {
190 var locationLines = new List<ulong>();
191 locationLines.AddRange(locationGuesses.Keys);
192 locationLines.Sort();
193 finalLocations = locationGuesses[locationLines.First()];
194 }
195
196 return finalLocations;
197 }
198
199 /// <summary>
200 /// Gets the name of hte file that contains |position|.
201 /// </summary>
202 /// <param name = "position">
203 /// The position whose file name is needed.
204 /// </param>
205 /// <returns>
206 /// Returns the name of the file that contains |position|.
207 /// </returns>
208 private string GetFileName(DocumentPosition position) {
209 string rValue = null;
210 var fileName = Path.GetFileName(position.Path);
211 if (fileName != null) {
212 if (database_.SourceFilesByFilename.ContainsKey(fileName)) {
213 rValue = fileName;
214 }
215 }
216 return rValue;
217 }
218
219 /// <summary>
220 /// This function checks whether a given |location| would make a
221 /// suitable breakpoint for a |originalLine| of code the user requested.
222 /// In order to qualify the location must be either equal to or greater
223 /// than the requested line of code and must be in the same scope.
224 /// The caller of this function will then have to resolve the suitable
225 /// location that is closest to what the user requested.
226 /// </summary>
227 /// <param name = "location">
228 /// A source code location to examine as a possible breakpoint location.
229 /// </param>
230 /// <param name = "originalLine">
231 /// The line at which the user wants to set the breakpoint.
232 /// </param>
233 /// <returns>
234 /// |true| iff the location could serve as a breakpoint location.
235 /// </returns>
236 private bool IsSuitableBreakpoint(SymbolDatabase.SourceLocation location,
237 uint originalLine) {
238 var suitableBreakpoint = false;
239
240 if (location.Line >= originalLine) {
241 // This could be suitable breakpoint if the current location's
242 // line is in the same scope as the original line.
243 var scope =
244 database_.GetScopeForAddress(location.StartAddress);
245
246 var sortedLocationsInScope =
247 database_.GetLocationsByLine(scope, location.StartAddress);
248 if (sortedLocationsInScope.First().Line <= originalLine) {
249 suitableBreakpoint = true;
250 } else if (scope.Tag == DwarfTag.DW_TAG_catch_block ||
251 scope.Tag == DwarfTag.DW_TAG_try_block ||
252 scope.Tag == DwarfTag.DW_TAG_lexical_block) {
253 // This could still be a suitable breakpoint if this scope entry
254 // is for a subscope of a function that begins before the
255 // original line.
256 var outerScope = scope.OuterScope;
257 var sortedLocationsInOuterScope =
258 database_.GetLocationsByLine(outerScope, location.StartAddress);
259 if (sortedLocationsInOuterScope.First().Line <= originalLine) {
260 suitableBreakpoint = true;
261 }
262 }
263 }
264 return suitableBreakpoint;
265 }
266
267 #endregion
268 }
269 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698