UH4L15——调试相关
UH4L15——调试相关
本章代码关键字
1 | appDomain.DebugService.StartDebugService() //注册调试服务 |
ILRuntime调试相关
注:笔者实际测试下来出现了无法命中断点的问题,原因不明且无法解决
- 进行ILRuntime调试需要安装插件
- 想要进行断点调试,我们需要注册调试服务,想要及时进断点,那么可以配合协同程序等待调试器链接
- 可以利用IP和端口调试特点来调试移动设备
准备ILRuntime调试相关插件
-
ILRuntime 2.1.0以下的版本 需要前往ILRuntime的Github页面获取插件
地址:Releases · Ourpalm/ILRuntime (github.com)
打开页面后,点击右侧的Releases,在对应版本处下载调试插件
-
ILRuntime 2.1.0及其以上的版本
在VS上方的:拓展-管理拓展-搜索ILRuntime后安装
当VS的菜单栏的调试处多了一个Attach to ILRuntime时,就说明安装成功
断点调试的必备工作
-
在初始化处 注册调试服务
appDomain.DebugService.StartDebugService(端口号)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//初始化ILRuntime相关的方法
private unsafe void InitILRuntime()
{
//注册委托和委托转换器
//注册跨域继承类
appDomain.RegisterCrossBindingAdaptor(new ILRuntimeAdapter.Lesson11_TestAdapter());
appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter());
appDomain.RegisterCrossBindingAdaptor(new IAsyncStateMachineClassInheritanceAdaptor());
//初始化LitJson相关内容
LitJson.JsonMapper.RegisterILRuntimeCLRRedirection(appDomain);
//注册值类型
appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder());
appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
//CLR重定向内容,必须要写到CLR绑定之前!!!
System.Type debugType = typeof(Debug);
MethodInfo methodInfo = debugType.GetMethod("Log", new System.Type[] { typeof(object) });
appDomain.RegisterCLRMethodRedirection(methodInfo, MyLog);
//注册 CLR绑定相关信息
ILRuntime.Runtime.Generated.CLRBindings.Initialize(appDomain);
//初始化ILRuntime相关信息(目前只需要告诉ILRuntime主线程的线程ID,主要目的是能够在Unity的Profiler剖析器窗口中分析问题)
appDomain.UnityMainThreadID = Thread.CurrentThread.ManagedThreadId;
//启动调试服务
appDomain.DebugService.StartDebugService(56000);
} -
通过协同程序,等待调试器链接(否则我们无法对一开始的逻辑 进行断点)
判断调试器链接的API为appDomain.DebugService.IsDebuggerAttached
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49public class ILRuntimeMgr : MonoBehaviour
{
private IEnumerator LoadHotUpdateInfo(UnityAction callBack)
{
//异步加载DLL文件
UnityWebRequest reqDll = UnityWebRequest.Get(Application.streamingAssetsPath + "/HotFix_Project.dll");
UnityWebRequest reqDll = UnityWebRequest.Get("file:///" + Application.streamingAssetsPath + "/HotFix_Project.dll");
yield return reqDll.SendWebRequest();
if (reqDll.result != UnityWebRequest.Result.Success)
Debug.Log("加载DLL文件失败" + reqDll.responseCode + reqDll.result);
//读取加载的DLL数据
byte[] dll = reqDll.downloadHandler.data;
reqDll.Dispose();
//编辑器环境下,我们可以加载调试用的pdb文件
UnityWebRequest reqpdb = UnityWebRequest.Get(Application.streamingAssetsPath + "/HotFix_Project.pdb");
yield return reqpdb.SendWebRequest();
//如果加载失败
if (reqpdb.result != UnityWebRequest.Result.Success)
{
Debug.LogError("加载DLL文件失败" + reqpdb.responseCode + reqpdb.result);
StopILRuntime();
yield break;
}
//读取加载的DLL数据
byte[] pdb = reqpdb.downloadHandler.data;
reqpdb.Dispose();
pdbStream = new MemoryStream(pdb);
dllStream = new MemoryStream(dll);
//将我们两个文件的内存流用于初始化 appDomain 我们之后就可以通过该对象来执行我们对应的热更代码了
appDomain.LoadAssembly(dllStream, pdbStream, new PdbReaderProvider());
InitILRuntime();
//如果想要调试我们的项目,那么就加一个协同程序去等待,等待调试器链接进入过后,再去这些我们后续的逻辑
StartCoroutine(WaitDebugger(callBack));
}
IEnumerator WaitDebugger(UnityAction callBack)
{
while (!appDomain.DebugService.IsDebuggerAttached)
{
yield return null;
}
ILRuntimeLoadOverDo();
callBack?.Invoke();
}
}
注意:一般只有在开发周期 才会这样去处理,如果最终发布了 就不用启动我们的调试服务 也不用去通过协程延迟执行后面的逻辑
1 | private bool isDebug = true; |
进行断点调试
在热更工程的 调试页签中 选择 Attach to ILRuntime,即可开始断点调试
先运行Unity程序,让协同程序开始等待调试器的接入
输出:
然后 Attach to ILRuntime 输入调试设备IP地址(本机使用127.0.0.1
即可),端口号填入在主工程内启动调试服务时传入的端口号
注意:
- 附加到ILRuntime后,弹出窗口中填写的内容为IP地址和端口号,意味着我们可以调试各种设备,只要保证IP地址和端口号正确即可
- 如果ILRuntime相关的dll和pdb文件没有加载成功,调试会失败
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文KRIFE齐的博客!