using System.IO;
using UnityEditor;
using UnityEngine;
using System.Diagnostics;
public class SymbolViewerEditor : EditorWindow
{
private string m_content = "";
private System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("#\\d+\\s+pc\\s+(.{8})\\s+.*/lib/.*(lib.*?.so)");
private string addr2Line = @"D:/dev/android-ndk-r19/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-addr2line";
private string symbolil2cpp = @"./Temp/StagingArea/symbols/armeabi-v7a/libil2cpp.dbg.so";
private string symbolunity = @"C:/Program Files/Unity/Editor/Data/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Release/Symbols/armeabi-v7a/libunity.sym.so";
[MenuItem("Window/自定义/符号查看器")]
private static void ShowWin()
{
var window = EditorWindow.GetWindow<SymbolViewerEditor>();
window.titleContent = new GUIContent("符号查看器");
window.Show();
}
private void OnInspectorUpdate()
{
this.Repaint();
}
private void OnGUI()
{
minSize = maxSize = new Vector2(1920, 1080);
GUILayout.BeginHorizontal();
GUILayout.Label("addr2Line:",GUILayout.Width(120));
addr2Line = GUILayout.TextField(addr2Line, GUILayout.Width(1000));
if (GUILayout.Button("选择目录", GUILayout.Width(120)))
{
addr2Line = EditorUtility.OpenFilePanel("选择addr2Line", @"D:/dev/android-ndk-r19/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin", "");
}
GUILayout.EndHorizontal();
if (!File.Exists(addr2Line))
{
return;
}
GUILayout.BeginHorizontal();
GUILayout.Label("il2cpp:", GUILayout.Width(120));
symbolil2cpp = GUILayout.TextField(symbolil2cpp, GUILayout.Width(1000));
if (GUILayout.Button("选择目录", GUILayout.Width(120)))
{
symbolil2cpp = EditorUtility.OpenFilePanel("选择il2cpp", @"./Temp/StagingArea/symbols/armeabi-v7a", "*.so");
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("unity:", GUILayout.Width(120));
symbolunity = GUILayout.TextField(symbolunity, GUILayout.Width(1000));
if (GUILayout.Button("选择目录", GUILayout.Width(120)))
{
symbolunity = EditorUtility.OpenFilePanel("选择unity", @"C:/Program Files/Unity/Editor/Data/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Release/Symbols/armeabi-v7a", "*.so");
}
GUILayout.EndHorizontal();
m_content = GUILayout.TextArea(m_content, GUILayout.Width(1500), GUILayout.Height(800));
if(GUILayout.Button("解析"))
{
var lines = m_content.Split(new char[] { '\r', '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (string.IsNullOrEmpty(line)) continue;
if (reg.IsMatch(line))
{
var match = reg.Match(line);
var addr = match.Groups[1].Value;
var file = match.Groups[2].Value;
var ret = Execute(file, addr);
if (string.IsNullOrEmpty(ret)) continue;
var lines2 = ret.Split('\n');
string fn = string.Empty;
string lineNo = string.Empty;
if(lines2.Length==2)
{
var parts = lines2[1].Split(':');
fn = parts[0].Replace(@"D:\work\branches\November\Client\COF\", "").Replace("\\", "/");
lineNo = parts[1];
}
UnityEngine.Object obj = null;
if (File.Exists(fn))
obj = AssetDatabase.LoadAssetAtPath<TextAsset>(fn);
UnityEngine.Debug.Log(ret, obj);
}
}
}
}
private string Execute(string file,string addr)
{
var so = string.Empty;
switch(file)
{
case "libil2cpp.so":
so = symbolil2cpp;
break;
case "libunity.so":
so = symbolunity;
break;
case "libhoudini.so":
so = "d:\\libhoudini.so";
break;
}
if (string.IsNullOrEmpty(so)) return string.Empty;
var arg = "-f -C -e \"" + so + "\" " + addr;
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(addr2Line);
info.CreateNoWindow = false;
info.ErrorDialog = true;
info.Arguments = arg;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
info.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
var process = Process.Start(info);
var ret = (process.StandardOutput.ReadToEnd());
process.WaitForExit();
return ret;
}
}