internal async Task <SourceLineMap> GetLinesForFile(string file) { string fileKey = file; lock (_mapFileToLinenums) { if (_mapFileToLinenums.ContainsKey(fileKey)) { return(_mapFileToLinenums[fileKey]); } } SourceLineMap linesMap = null; linesMap = await LinesForFile(fileKey); lock (_mapFileToLinenums) { if (_mapFileToLinenums.ContainsKey(fileKey)) { return(_mapFileToLinenums[fileKey]); } if (linesMap != null) { _mapFileToLinenums.Add(fileKey, linesMap); } else { _mapFileToLinenums.Add(fileKey, new SourceLineMap(0)); // empty list to prevent requerying. Release this list on dynamic library loading } return(_mapFileToLinenums[fileKey]); } }
private async Task <SourceLineMap> LinesForFile(string file) { string cmd = "-symbol-list-lines " + _process.EscapePath(file); Results results = await _process.CmdAsync(cmd, ResultClass.None); if (results.ResultClass != ResultClass.done) { return(null); } ValueListValue lines = results.Find <ValueListValue>("lines"); SourceLineMap linesMap = new SourceLineMap(lines.Content.Length); for (int i = 0; i < lines.Content.Length; ++i) { ulong addr = lines.Content[i].FindAddr("pc"); uint line = lines.Content[i].FindUint("line"); linesMap.Add(addr, line); } return(linesMap); }
private async Task <SourceLineMap> LinesForFile(string file) { string cmd = "-symbol-list-lines " + _process.EscapeSymbolPath(file); Results results = await _process.CmdAsync(cmd, ResultClass.None); if (results.ResultClass != ResultClass.done) { return(null); } ValueListValue lines = results.Find <ValueListValue>("lines"); SourceLineMap linesMap = new SourceLineMap(lines.Content.Length); for (int i = 0; i < lines.Content.Length; ++i) { ulong addr = lines.Content[i].FindAddr("pc"); uint line = lines.Content[i].FindUint("line"); if (linesMap.ContainsKey(addr)) { // It is actually fairly common for an address to map to more than one line. For instance, // in debug builds destructors can have an entry to line 0 as well as one to the correct line. // Release builds with inlining will hit this very often. // Unforunately, without more context, it is impossible to know which line is the "right" line. // For the inline case, any line will be acceptable. For the destructor case, we should prefer // a non-zero line. if (linesMap[addr].Line == 0) { linesMap.Replace(addr, line); } } else { linesMap.Add(addr, line); } } return(linesMap); }