internal static string ResolveAddresses(string[] lines, IReadOnlyList <ReordableListItem> regexes, IReadOnlyList <ReordableListItem> symbolPaths, AndroidTools tools) { var output = string.Empty; // Calling addr2line for every address is costly, that's why we need to do it in batch var unresolved = new UnresolvedAddresses(); foreach (var l in lines) { string address; string library; if (!AndroidLogcatUtilities.ParseCrashLine(regexes, l, out address, out library)) { continue; } unresolved.CreateAddressEntry(library, address); } var libraries = unresolved.GetAllLibraries(); foreach (var library in libraries) { var addresses = unresolved.GetAllAddresses(library); var symbolFile = AndroidLogcatUtilities.GetSymbolFile(symbolPaths, library); // Symbol file not found, set 'not found' messages for all addresses of this library if (string.IsNullOrEmpty(symbolFile)) { var value = $"<color={m_RedColor}>({library} not found)</color>"; foreach (var a in addresses) { unresolved.SetAddressValue(library, a, value); } continue; } try { var result = tools.RunAddr2Line(symbolFile, addresses.ToArray()); if (result.Length != addresses.Count) { return($"Failed to run addr2line, expected to receive {addresses.Count} addresses, but received {result.Length}"); } for (int i = 0; i < addresses.Count; i++) { AndroidLogcatInternalLog.Log($"{addresses[i]} ---> {result[i]}"); unresolved.SetAddressValue(library, addresses[i], $"<color={m_GreenColor}>({result[i].Trim()})</color>"); } } catch (Exception ex) { return($"Exception while running addr2line:\n{ex.Message}"); } } foreach (var l in lines) { string address; string library; if (!AndroidLogcatUtilities.ParseCrashLine(regexes, l, out address, out library)) { output += l; } else { /* * string resolved = string.Format(" <color={0}>(Not resolved)</color>", m_RedColor); * var symbolFile = AndroidLogcatUtilities.GetSymbolFile(symbolPaths, library); * if (string.IsNullOrEmpty(symbolFile)) * { * resolved = string.Format(" <color={0}>({1} not found)</color>", m_RedColor, library); * } * else * { * try * { * var result = tools.RunAddr2Line(symbolFile, new[] { address }); * AndroidLogcatInternalLog.Log("addr2line \"{0}\" {1}", symbolFile, address); * if (!string.IsNullOrEmpty(result[0])) * resolved = string.Format(" <color={0}>({1})</color>", m_GreenColor, result[0].Trim()); * } * catch (Exception ex) * { * return string.Format("Exception while running addr2line ('{0}', {1}):\n{2}", symbolFile, address, ex.Message); * } * } */ output += l.Replace(address, address + " " + unresolved.GetAddressValue(library, address)); } output += Environment.NewLine; } return(output); }
internal static string ResolveAddresses(string[] lines, IReadOnlyList <ReordableListItem> regexes, IReadOnlyList <ReordableListItem> symbolPaths, AndroidTools tools) { var output = string.Empty; // Calling addr2line for every address is costly, that's why we need to do it in batch var unresolved = new UnresolvedAddresses(); foreach (var l in lines) { string address; string library; string abi; if (!AndroidLogcatUtilities.ParseCrashLine(regexes, l, out abi, out address, out library)) { continue; } unresolved.CreateAddressEntry(new UnresolvedAddresses.AddressKey() { ABI = abi, Library = library }, address); } var keys = unresolved.GetKeys(); foreach (var key in keys) { var addresses = unresolved.GetAllAddresses(key); var symbolFile = AndroidLogcatUtilities.GetSymbolFile(symbolPaths, key.ABI, key.Library); // Symbol file not found, set 'not found' messages for all addresses of this library if (string.IsNullOrEmpty(symbolFile)) { var value = $"<color={m_RedColor}>({key.Library} not found)</color>"; foreach (var a in addresses) { unresolved.SetAddressValue(key, a, value); } continue; } try { var result = tools.RunAddr2Line(symbolFile, addresses.ToArray()); if (result.Length != addresses.Count) { return($"Failed to run addr2line, expected to receive {addresses.Count} addresses, but received {result.Length}"); } for (int i = 0; i < addresses.Count; i++) { AndroidLogcatInternalLog.Log($"{addresses[i]} ---> {result[i]}"); unresolved.SetAddressValue(key, addresses[i], $"<color={m_GreenColor}>({result[i].Trim()})</color>"); } } catch (Exception ex) { return($"Exception while running addr2line:\n{ex.Message}"); } } foreach (var l in lines) { string address; string library; string abi; if (!AndroidLogcatUtilities.ParseCrashLine(regexes, l, out abi, out address, out library)) { output += l; } else { output += l.Replace(address, address + " " + unresolved.GetAddressValue(new UnresolvedAddresses.AddressKey() { ABI = abi, Library = library }, address)); } output += Environment.NewLine; } return(output); }