void OnGUI() { Event evt = Event.current; bool hitEnter = evt.type == EventType.KeyDown && (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter); GUI.SetNextControlName(kIpTextFieldId); EditorGUILayout.BeginVertical(); { GUILayout.Space(5); m_IpString = EditorGUILayout.TextField(m_IpString); if (!m_DidFocus) { m_DidFocus = true; EditorGUI.FocusTextInControl(kIpTextFieldId); } GUI.enabled = !string.IsNullOrEmpty(m_IpString); if (GUILayout.Button("Connect") || hitEnter) { Close(); EditorPrefs.SetString(kAndroidLogcatLastIp, m_IpString); AndroidLogcatUtilities.ConnectDevice(m_Adb, m_IpString); GUIUtility.ExitGUI(); } } EditorGUILayout.EndVertical(); }
private void UpdateDebuggablePackages() { // When running test Tools don't exist if (m_Runtime.Tools == null) { return; } var startTime = DateTime.Now; var packagePIDCache = new Dictionary <string, int>(); CheckIfPackagesExited(packagePIDCache); int topActivityPid = 0; string topActivityPackageName = string.Empty; bool checkProjectPackage = true; var selectedDevice = m_Runtime.DeviceQuery.SelectedDevice; if (AndroidLogcatUtilities.GetTopActivityInfo(m_Runtime.Tools.ADB, selectedDevice, ref topActivityPackageName, ref topActivityPid) && topActivityPid > 0) { m_Runtime.UserSettings.CreatePackageInformation(topActivityPackageName, topActivityPid, selectedDevice); checkProjectPackage = topActivityPackageName != PlayerSettings.applicationIdentifier; } if (checkProjectPackage) { int projectApplicationPid = GetPidFromPackageName(packagePIDCache, PlayerSettings.applicationIdentifier, selectedDevice); m_Runtime.UserSettings.CreatePackageInformation(PlayerSettings.applicationIdentifier, projectApplicationPid, selectedDevice); } m_Runtime.UserSettings.CleanupDeadPackagesForDevice(m_Runtime.DeviceQuery.SelectedDevice); AndroidLogcatInternalLog.Log("UpdateDebuggablePackages finished in " + (DateTime.Now - startTime).Milliseconds + " ms"); }
private int GetPidFromPackageName(string packageName, string deviceId) { var adb = GetCachedAdb(); var device = GetAndroidDeviceFromCache(adb, deviceId); return(AndroidLogcatUtilities.GetPidFromPackageName(adb, device, deviceId, packageName)); }
private void MenuToolsSelection(object userData, string[] options, int selected) { switch (selected) { case 0: AndroidLogcatScreenCaptureWindow.ShowWindow(); break; case 1: AndroidLogcatUtilities.OpenTerminal(Path.GetDirectoryName(m_Runtime.Tools.ADB.GetADBPath())); break; case 2: AndroidLogcatStacktraceWindow.ShowStacktraceWindow(); break; case 3: m_Runtime.ProjectSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Auto; break; case 4: m_Runtime.ProjectSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Manual; break; case 5: m_Runtime.ProjectSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Hidden; break; } }
private static IAndroidLogcatTaskResult ExecuteScreenCapture(IAndroidLogcatTaskInput input) { var i = (AndroidLogcatCaptureScreenCaptureInput)input; string error; var path = AndroidLogcatUtilities.CaptureScreen(i.adb, i.deviceId, out error); return(new AndroidLogcatCaptureScreenCaptureResult() { imagePath = path, error = error }); }
void ResolveStacktraces(string symbolPath, Regex regex) { m_ResolvedStacktraces = String.Empty; if (string.IsNullOrEmpty(m_Text)) { m_ResolvedStacktraces = string.Format(" <color={0}>(Please add some log with addresses first)</color>", m_RedColor); return; } var lines = m_Text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var l in lines) { string address; string library; if (!ParseLine(regex, l, out address, out library)) { m_ResolvedStacktraces += l; } else { string resolved = string.Format(" <color={0}>(Not resolved)</color>", m_RedColor); var symbolFile = AndroidLogcatUtilities.GetSymbolFile(symbolPath, library); if (string.IsNullOrEmpty(symbolFile)) { resolved = string.Format(" <color={0}>({1} not found)</color>", m_RedColor, library); } else { try { var result = AndroidLogcatManager.instance.Runtime.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) { m_ResolvedStacktraces = string.Format("Exception while running addr2line ('{0}', {1}):\n{2}", symbolFile, address, ex.Message); return; } } m_ResolvedStacktraces += l.Replace(address, address + resolved); } m_ResolvedStacktraces += Environment.NewLine; } }
/// <summary> /// Get the top activity on the given device. /// </summary> public static bool GetTopActivityInfo(AndroidBridge.ADB adb, IAndroidLogcatDevice device, ref string packageName, ref int packagePid) { if (device == null) return false; try { var cmd = "-s " + device.Id + " shell \"dumpsys activity\" "; AndroidLogcatInternalLog.Log("{0} {1}", adb.GetADBPath(), cmd); var output = adb.Run(new[] { cmd }, "Unable to get the top activity."); packagePid = AndroidLogcatUtilities.ParseTopActivityPackageInfo(output, out packageName); return packagePid != -1; } catch (Exception) { return false; } }
private void IntegrateUpdateConnectedDevicesList(IAndroidLogcatTaskResult resut) { m_DeviceIds = ((AndroidLogcatRetrieveDeviceIdsResult)resut).deviceIds; var adb = GetCachedAdb(); // Ensure selected device does not change (due to a new device name taking the same index) if (m_SelectedDeviceId != null) { m_SelectedDeviceIndex = m_DeviceIds.IndexOf(m_SelectedDeviceId); } var devicesDetails = new List<string>(); foreach (var deviceId in m_DeviceIds) { devicesDetails.Add(AndroidLogcatUtilities.RetrieveDeviceDetails(GetAndroidDeviceFromCache(adb, deviceId), deviceId)); } m_DeviceDetails = devicesDetails.ToArray(); }
private void FilterByProcessId(int processId) { var packages = m_PackagesForAllDevices[m_SelectedDeviceId]; foreach (var p in packages) { if (p.processId == processId) { SelectPackage(p); return; } } var packageName = AndroidLogcatUtilities.GetPackageNameFromPid(m_Adb, m_SelectedDeviceId, processId); var package = CreatePackageInformation(packageName, processId, m_SelectedDeviceId); SelectPackage(package); }
/// <summary> /// Get the top activity on the given device. /// </summary> public static bool GetTopActivityInfo(ADB adb, string deviceId, ref string packageName, ref int packagePid) { if (string.IsNullOrEmpty(deviceId)) { return(false); } try { var cmd = "-s " + deviceId + " shell \"dumpsys activity\" "; AndroidLogcatInternalLog.Log("{0} {1}", adb.GetADBPath(), cmd); var output = adb.Run(new[] { cmd }, "Unable to get the top activity."); packagePid = AndroidLogcatUtilities.ParseTopActivityPackageInfo(output, out packageName); return(packagePid != -1); } catch (Exception) { return(false); } }
private LogEntry ParseLogEntry(Match m) { DateTime dateTime; var dateValue = m.Groups["date"].Value; if (LogPrintFormat == kThreadTime) { dateValue = "1999-" + dateValue; } try { dateTime = DateTime.Parse(dateValue); } catch (Exception ex) { dateTime = new DateTime(); AndroidLogcatInternalLog.Log("Failed to parse date: " + dateValue + "\n" + ex.Message); } var entry = new LogEntry( dateTime, Int32.Parse(m.Groups["pid"].Value), Int32.Parse(m.Groups["tid"].Value), PriorityStringToEnum(m.Groups["priority"].Value), m.Groups["tag"].Value, m.Groups["msg"].Value); if ((entry.priority == Priority.Info && entry.tag.GetHashCode() == kUnityHashCode && entry.message.StartsWith("Built from")) || (entry.priority == Priority.Error && entry.tag.GetHashCode() == kCrashHashCode && entry.message.StartsWith("Build type"))) { m_BuildInfos[entry.processId] = AndroidLogcatUtilities.ParseBuildInfo(entry.message); } if (entry.priority == Priority.Fatal && entry.tag.GetHashCode() == kDebugHashCode && entry.message.StartsWith("pid:")) { // Crash reported by Android for some pid, need to update buildInfo information for this new pid as well ParseCrashBuildInfo(entry.processId, entry.message); } return(entry); }
private void FilterByProcessId(int processId) { var selectedDevice = m_Runtime.DeviceQuery.SelectedDevice; var packages = m_Runtime.UserSettings.GetKnownPackages(selectedDevice); foreach (var p in packages) { if (p.processId == processId) { SelectPackage(p); return; } } var packageName = AndroidLogcatUtilities.GetPackageNameFromPid(m_Runtime.Tools.ADB, selectedDevice, processId); var package = m_Runtime.UserSettings.CreatePackageInformation(packageName, processId, selectedDevice); SelectPackage(package); }
private void UpdateDebuggablePackages() { CheckIfPackagesExited(); int topActivityPid = 0; string topActivityPackageName = string.Empty; bool checkProjectPackage = true; if (AndroidLogcatUtilities.GetTopActivityInfo(GetCachedAdb(), m_SelectedDeviceId, ref topActivityPackageName, ref topActivityPid) && topActivityPid > 0) { CreatePackageInformation(topActivityPackageName, topActivityPid, m_SelectedDeviceId); checkProjectPackage = topActivityPackageName != PlayerSettings.applicationIdentifier; } if (checkProjectPackage) { int projectApplicationPid = GetPidFromPackageName(PlayerSettings.applicationIdentifier, m_SelectedDeviceId); CreatePackageInformation(PlayerSettings.applicationIdentifier, projectApplicationPid, m_SelectedDeviceId); } }
private int GetPidFromPackageName(Dictionary <string, int> cache, string packageName, IAndroidLogcatDevice device) { if (device == null) { return(-1); } // Getting pid for packages is a very costly operation, use cache to make less queries int pid; if (cache != null && cache.TryGetValue(packageName, out pid)) { return(pid); } pid = AndroidLogcatUtilities.GetPidFromPackageName(m_Runtime.Tools.ADB, device, packageName); if (cache != null) { cache[packageName] = pid; } return(pid); }
public void OnGUI() { if (!AndroidBridge.AndroidExtensionsInstalled) { AndroidLogcatUtilities.ShowAndroidIsNotInstalledMessage(); return; } GUILayout.BeginHorizontal(); int count; lock (ms_LogEntries) { count = ms_LogEntries.Length; } GUILayout.Label("Entries: " + count); if (GUILayout.Button("Clear")) { lock (ms_LogEntries) { ms_LogEntries = new StringBuilder(); } } GUILayout.EndHorizontal(); var e = Event.current; if (e.type == EventType.MouseDown && e.button == 1) { var menuItems = new[] { new GUIContent("Copy All") }; EditorUtility.DisplayCustomMenu(new Rect(e.mousePosition.x, e.mousePosition.y, 0, 0), menuItems.ToArray(), -1, MenuSelection, null); } m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition, true, true); GUILayout.TextArea(ms_LogEntries.ToString(), AndroidLogcatStyles.internalLogStyle, GUILayout.ExpandHeight(true)); GUILayout.EndScrollView(); }
private LogEntry ParseLogEntry(Match m) { DateTime dateTime; switch (LogPrintFormat) { case kThreadTime: dateTime = DateTime.Parse("1999-" + m.Groups["date"].Value); break; case kYearTime: dateTime = DateTime.Parse(m.Groups["date"].Value); break; default: throw new NotImplementedException("Please implement date parsing for log format: " + LogPrintFormat); } var entry = new LogEntry( dateTime, Int32.Parse(m.Groups["pid"].Value), Int32.Parse(m.Groups["tid"].Value), PriorityStringToEnum(m.Groups["priority"].Value), m.Groups["tag"].Value, m.Groups["msg"].Value); if ((entry.priority == Priority.Info && entry.tag.GetHashCode() == kUnityHashCode && entry.message.StartsWith("Built from")) || (entry.priority == Priority.Error && entry.tag.GetHashCode() == kCrashHashCode && entry.message.StartsWith("Build type"))) { m_BuildInfos[entry.processId] = AndroidLogcatUtilities.ParseBuildInfo(entry.message); } if (entry.priority == Priority.Fatal && entry.tag.GetHashCode() == kDebugHashCode && entry.message.StartsWith("pid:")) { // Crash reported by Android for some pid, need to update buildInfo information for this new pid as well ParseCrashBuildInfo(entry.processId, entry.message); } return(entry); }
private void MenuToolsSelection(object userData, string[] options, int selected) { var contextMenu = (AndroidContextMenu <ToolsContextMenu>)userData; var item = contextMenu.GetItemAt(selected); if (item == null) { return; } switch (item.Item) { case ToolsContextMenu.ScreenCapture: AndroidLogcatScreenCaptureWindow.ShowWindow(); break; case ToolsContextMenu.OpenTerminal: AndroidLogcatUtilities.OpenTerminal(Path.GetDirectoryName(m_Runtime.Tools.ADB.GetADBPath())); break; case ToolsContextMenu.StacktraceUtility: AndroidLogcatStacktraceWindow.ShowStacktraceWindow(); break; case ToolsContextMenu.MemoryBehaviorAuto: m_Runtime.UserSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Auto; break; case ToolsContextMenu.MemoryBehaviorManual: m_Runtime.UserSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Manual; break; case ToolsContextMenu.MemoryBehaviorHidden: m_Runtime.UserSettings.MemoryViewerState.Behavior = MemoryViewerBehavior.Hidden; break; } }
void OnGUI() { if (!AndroidBridge.AndroidExtensionsInstalled) { AndroidLogcatUtilities.ShowAndroidIsNotInstalledMessage(); return; } GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); EditorGUI.BeginChangeCheck(); m_WindowMode = (WindowMode)GUILayout.Toolbar((int)m_WindowMode, new[] { new GUIContent("Original"), new GUIContent("Resolved"), }, "LargeButton", GUI.ToolbarButtonSize.Fixed, GUILayout.ExpandWidth(true)); if (EditorGUI.EndChangeCheck()) { SelectWindowMode(m_WindowMode); } m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition); GUI.SetNextControlName(WindowMode.ResolvedLog.ToString()); switch (m_WindowMode) { case WindowMode.ResolvedLog: // Note: Not using EditorGUILayout.SelectableLabel, because scrollbars are not working correctly EditorGUILayout.TextArea(m_ResolvedStacktraces, AndroidLogcatStyles.resolvedStacktraceStyle, GUILayout.ExpandHeight(true)); break; case WindowMode.OriginalLog: m_Text = EditorGUILayout.TextArea(m_Text, AndroidLogcatStyles.stacktraceStyle, GUILayout.ExpandHeight(true)); break; } EditorGUILayout.EndScrollView(); GUILayout.EndVertical(); DoInfoGUI(); GUILayout.EndHorizontal(); }
private void ResolveStackTrace(List <LogEntry> entries) { var unresolvedAddresses = new Dictionary <KeyValuePair <BuildInfo, string>, List <UnresolvedAddress> >(); // Gather unresolved address if there are any for (int i = 0; i < entries.Count; i++) { var entry = entries[i]; // Only process stacktraces from Error/Fatal priorities if (entry.priority != Priority.Error && entry.priority != Priority.Fatal) { continue; } // Only process stacktraces if tag is "CRASH" or "DEBUG" if (entry.tag.GetHashCode() != kCrashHashCode && entry.tag.GetHashCode() != kDebugHashCode) { continue; } BuildInfo buildInfo; // Unknown build info, that means we don't know where the symbols are located if (!m_BuildInfos.TryGetValue(entry.processId, out buildInfo)) { continue; } string address, libName; if (!AndroidLogcatUtilities.ParseCrashLine(m_Runtime.Settings.StacktraceResolveRegex, entry.message, out address, out libName)) { continue; } List <UnresolvedAddress> addresses; var key = new KeyValuePair <BuildInfo, string>(buildInfo, libName); if (!unresolvedAddresses.TryGetValue(key, out addresses)) { unresolvedAddresses[key] = new List <UnresolvedAddress>(); } unresolvedAddresses[key].Add(new UnresolvedAddress() { logEntryIndex = i, unresolvedAddress = address }); } var engineDirectory = BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None); // Resolve addresses foreach (var u in unresolvedAddresses) { var buildInfo = u.Key.Key; var libName = u.Key.Value; var addresses = u.Value; var symbolPath = CombinePaths(engineDirectory, "Variations", buildInfo.scriptingImplementation, buildInfo.buildType, "Symbols", buildInfo.cpu); var libpath = AndroidLogcatUtilities.GetSymbolFile(symbolPath, libName); // For optimizations purposes, we batch addresses which belong to same library, so addr2line can be ran less try { string[] result; if (!string.IsNullOrEmpty(libpath)) { result = m_Runtime.Tools.RunAddr2Line(libpath, addresses.Select(m => m.unresolvedAddress).ToArray()); } else { result = new string[addresses.Count]; for (int i = 0; i < addresses.Count; i++) { result[i] = string.Empty; } } for (int i = 0; i < addresses.Count; i++) { var idx = addresses[i].logEntryIndex; var append = string.IsNullOrEmpty(result[i]) ? "(Not Resolved)" : result[i]; entries[idx] = new LogEntry(entries[idx]) { message = ModifyLogEntry(entries[idx].message, append, false) }; } } catch (Exception ex) { for (int i = 0; i < addresses.Count; i++) { var idx = addresses[i].logEntryIndex; entries[idx] = new LogEntry(entries[idx]) { message = ModifyLogEntry(entries[idx].message, "(Addr2Line failure)", true) }; var errorMessage = new StringBuilder(); errorMessage.AppendLine("Addr2Line failure"); errorMessage.AppendLine("Full Entry Message: " + entries[idx].message); errorMessage.AppendLine("Scripting Backend: " + buildInfo.scriptingImplementation); errorMessage.AppendLine("Build Type: " + buildInfo.buildType); errorMessage.AppendLine("CPU: " + buildInfo.cpu); errorMessage.AppendLine(ex.Message); UnityEngine.Debug.LogError(errorMessage.ToString()); } } } }
void OnGUI() { if (!AndroidBridge.AndroidExtensionsInstalled) { AndroidLogcatUtilities.ShowAndroidIsNotInstalledMessage(); return; } EditorGUILayout.BeginVertical(); { EditorGUILayout.LabelField("Available devices:", EditorStyles.boldLabel); GUI.Box(m_DeviceScrollRect, GUIContent.none, EditorStyles.helpBox); m_DevicesScrollPosition = EditorGUILayout.BeginScrollView(m_DevicesScrollPosition); bool refreshDevices = false; foreach (var deviceValue in m_Runtime.DeviceQuery.Devices) { var device = deviceValue.Value; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(device.DisplayName, EditorStyles.label); EditorGUI.BeginDisabledGroup(device.State != IAndroidLogcatDevice.DeviceState.Connected); if (GUILayout.Button(" Copy IP ", GUILayout.ExpandWidth(false))) { m_IpString = CopyIP(device.Id); EditorGUIUtility.systemCopyBuffer = m_IpString; GUIUtility.keyboardControl = 0; GUIUtility.hotControl = 0; Repaint(); } float connectButtoSize = 100.0f; if (device.ConnectionType == IAndroidLogcatDevice.DeviceConnectionType.Network) { if (GUILayout.Button(kDisconnect, GUILayout.Width(connectButtoSize))) { DisconnectDevice(device); refreshDevices = true; } } else { if (GUILayout.Button(kConnect, GUILayout.Width(connectButtoSize))) { SetTCPIPAndConnectDevice(device.Id, CopyIP(device.Id), "5555"); refreshDevices = true; } } EditorGUI.EndDisabledGroup(); var rc = GUILayoutUtility.GetLastRect(); var orgColor = GUI.color; GUI.color = Color.black; if (Event.current.type == EventType.Repaint) { GUI.DrawTexture(new Rect(0, rc.y + rc.height, m_DeviceScrollRect.width, 1), EditorGUIUtility.whiteTexture); } GUI.color = orgColor; EditorGUILayout.EndHorizontal(); if (refreshDevices) { m_Runtime.DeviceQuery.UpdateConnectedDevicesList(true); GUIUtility.keyboardControl = 0; GUIUtility.hotControl = 0; break; } } EditorGUILayout.EndScrollView(); if (Event.current.type == EventType.Repaint) { m_DeviceScrollRect = GUILayoutUtility.GetLastRect(); } GUILayout.Space(5); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("IP", EditorStyles.boldLabel); EditorGUILayout.LabelField("Port", EditorStyles.boldLabel, GUILayout.Width(100)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); m_IpString = EditorGUILayout.TextField(m_IpString); m_PortString = EditorGUILayout.TextField(m_PortString, GUILayout.Width(100)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(m_IpString)); if (GUILayout.Button("Connect")) { Close(); EditorPrefs.SetString(kAndroidLogcatLastIp, m_IpString); EditorPrefs.SetString(kAndroidLogcatLastPort, m_PortString); ConnectDevice(m_IpString, m_PortString); GUIUtility.ExitGUI(); } EditorGUI.EndDisabledGroup(); if (GUILayout.Button("Refresh Devices")) { m_Runtime.DeviceQuery.UpdateConnectedDevicesList(false); } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); }
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 void OnGUI() { #if !PLATFORM_ANDROID AndroidLogcatUtilities.ShowActivePlatformNotAndroidMessage(); #endif }
internal void OnGUI() { AndroidLogcatUtilities.ShowActivePlatformNotAndroidMessage(); }
void OnGUI() { if (!AndroidBridge.AndroidExtensionsInstalled) { AndroidLogcatUtilities.ShowAndroidIsNotInstalledMessage(); return; } EditorGUILayout.BeginVertical(); GUILayout.Space(5); EditorGUILayout.BeginHorizontal(AndroidLogcatStyles.toolbar); GUIContent statusIcon = GUIContent.none; if (m_CaptureCount > 0) { int frame = (int)Mathf.Repeat(Time.realtimeSinceStartup * 10, 11.99f); statusIcon = AndroidLogcatStyles.Status.GetContent(frame); Repaint(); } GUILayout.Label(statusIcon, AndroidLogcatStyles.StatusIcon, GUILayout.Width(30)); EditorGUI.BeginChangeCheck(); m_SelectedDevice = EditorGUILayout.Popup(m_SelectedDevice, m_Devices, AndroidLogcatStyles.toolbarPopup); if (EditorGUI.EndChangeCheck()) { QueueScreenCapture(); } EditorGUI.BeginDisabledGroup(m_CaptureCount > 0); if (GUILayout.Button("Capture", AndroidLogcatStyles.toolbarButton)) { QueueScreenCapture(); } EditorGUI.EndDisabledGroup(); if (GUILayout.Button("Save...", AndroidLogcatStyles.toolbarButton)) { var path = EditorUtility.SaveFilePanel("Save Screen Capture", "", Path.GetFileName(m_ImagePath), "png"); if (!string.IsNullOrEmpty(path)) { try { File.Copy(m_ImagePath, path, true); } catch (Exception ex) { Debug.LogErrorFormat("Failed to save to '{0}' as '{1}'.", path, ex.Message); } } } EditorGUILayout.EndHorizontal(); GUILayout.Space(10); var id = GetDeviceId(); if (string.IsNullOrEmpty(id)) { EditorGUILayout.HelpBox("No valid device detected, please reopen this window after selecting proper device.", MessageType.Info); } else { if (!string.IsNullOrEmpty(m_Error)) { EditorGUILayout.HelpBox(m_Error, MessageType.Error); } else { if (m_ImageTexture != null) { Rect rect = new Rect(0, kButtonAreaHeight, position.width, position.height - kButtonAreaHeight - kBottomAreaHeight); GUI.DrawTexture(rect, m_ImageTexture, ScaleMode.ScaleToFit); } } } EditorGUILayout.EndVertical(); }
internal void OnGUI() { if (m_ApplySettings) { ApplySettings(m_Runtime.Settings); m_ApplySettings = false; } EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(AndroidLogcatStyles.toolbar); { ShowDuringBuildRun = GUILayout.Toggle(ShowDuringBuildRun, kAutoRunText, AndroidLogcatStyles.toolbarButton); HandleSelectedDeviceField(); EditorGUI.BeginDisabledGroup(!m_StatusBar.Connected); HandleSelectedPackage(); HandleSearchField(); SetRegex(GUILayout.Toggle(m_FilterIsRegularExpression, kRegexText, AndroidLogcatStyles.toolbarButton)); EditorGUI.EndDisabledGroup(); GUILayout.Space(kSpace); if (GUILayout.Button(kReconnect, AndroidLogcatStyles.toolbarButton)) { RestartLogCat(); } if (GUILayout.Button(kDisconnect, AndroidLogcatStyles.toolbarButton)) { StopLogCat(); } GUILayout.Space(kSpace); if (GUILayout.Button(kClearButtonText, AndroidLogcatStyles.toolbarButton)) { ClearLogCat(); Repaint(); } GUILayout.Space(kSpace); if (GUILayout.Button(kCaptureScreenText, AndroidLogcatStyles.toolbarButton)) { var screenFilePath = AndroidLogcatUtilities.CaptureScreen(GetCachedAdb(), m_SelectedDeviceId); if (!string.IsNullOrEmpty(screenFilePath)) { AndroidLogcatScreenCaptureWindow.Show(screenFilePath); } Repaint(); } GUILayout.Space(kSpace); if (GUILayout.Button(kOpenTerminal, AndroidLogcatStyles.toolbarButton)) { AndroidLogcatUtilities.OpenTerminal(Path.GetDirectoryName(GetCachedAdb().GetADBPath())); } GUILayout.Space(kSpace); if (GUILayout.Button(kStacktraceUtility, AndroidLogcatStyles.toolbarButton)) { AndroidLogcatStacktraceWindow.ShowStacktraceWindow(); } } EditorGUILayout.EndHorizontal(); if (Unsupported.IsDeveloperMode()) { DoDebuggingGUI(); } if (DoMessageView()) { Repaint(); } if (m_StatusBar != null) { m_StatusBar.DoGUI(); } EditorGUILayout.EndVertical(); }
internal void OnGUI() { if (!AndroidBridge.AndroidExtensionsInstalled) { AndroidLogcatUtilities.ShowAndroidIsNotInstalledMessage(); return; } if (m_ApplySettings) { ApplySettings(m_Runtime.Settings); m_ApplySettings = false; } EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(AndroidLogcatStyles.toolbar); { ShowDuringBuildRun = GUILayout.Toggle(ShowDuringBuildRun, kAutoRunText, AndroidLogcatStyles.toolbarButton); HandleSelectedDeviceField(); EditorGUI.BeginDisabledGroup(!m_StatusBar.Connected); HandleSelectedPackage(); HandleSearchField(); SetRegex(GUILayout.Toggle(m_Runtime.UserSettings.FilterIsRegularExpression, kRegexText, AndroidLogcatStyles.toolbarButton)); EditorGUI.EndDisabledGroup(); GUILayout.Space(kSpace); if (GUILayout.Button(kReconnect, AndroidLogcatStyles.toolbarButton)) { RestartLogCat(); } if (GUILayout.Button(kDisconnect, AndroidLogcatStyles.toolbarButton)) { StopLogCat(); } GUILayout.Space(kSpace); if (GUILayout.Button(kClearButtonText, AndroidLogcatStyles.toolbarButton)) { ClearLogCat(); Repaint(); } DoToolsGUI(); } EditorGUILayout.EndHorizontal(); if (Unsupported.IsDeveloperMode()) { DoDebuggingGUI(); } if (DoMessageView()) { Repaint(); } m_MemoryViewer.DoGUI(); if (m_StatusBar != null) { m_StatusBar.DoGUI(); } EditorGUILayout.EndVertical(); }
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); }