1、.NET 程序故障的动态跟踪方法 演讲人:一线码农 Part.11.动态跟踪前置基础Part.22.注入点分层解读Part.33.动态追踪三大战役Part.11.动态跟踪前置基础1.为什么要 动态追踪01Dump 分析的局限性Dump分析就像是 法医 去命案现场。你可以看到那一刻的如下细节。1)谁在场?(提取指纹、DNA、衣物碎片)2)他们手里拿着什么?(尸体手握的物品、身旁散落的物件)3)他们当时在做什么?(尸体的姿势、创伤的位置、血迹的形态)通过精湛的法医技术可以推断出大体的死因,但遗憾的是:1)凶手是如何进入房间的?2)事件发生前他们有什么异常行为?这类问题,只看命案现场是没有用的,需要
2、利用 摄像头 开启动态追踪。02什么是 动态追踪动态追踪则会在系统中布下“天眼”监控网络,它能完整回放“案发”前后所有的一举一动,让你不仅能锁定“嫌疑人”,更能清晰还原其行动路线、与其他第三方的互动关系,以及每一步的快慢节奏,从而建立起问题与根源之间的因果关系。2.动态追踪 的体系结构01体系层面介绍以 Windows 为例,在其上部署的.NET程序 往往会有 5 个层级,从上往下 依次为:1)应用程序层2)SDK层3)CLR层4)Win32层5)操作系统&驱动程序层Part.22.注入点分层解读1.C#应用层&SDK 层注入01Harmony 原理介绍它是一个强大的.NET 运行时代码注入库
3、,可在运行时修改、替换,扩展已编织的.NET 应用程序 的方法,简单的说 Harmony 是一个 IL代码修改器,但在某些情况下,它会利用汇编代码级别的技巧来实现其目标。tips:1)Dynamic method:动态生成的方法。2)Prefix calls:AOP 中的 前置方法。3)modified:可被修改的 主方法体。4)Postfix calls:AOP的后置方法。1.1 C#应用层&SDK 层注入追踪篇(上)01Harmony 案例之对 new Thread()追踪如果你要调查是谁在不断的 new Thread().Start(),可以用 harmony 给 Start()的底层
4、Thread.StartCore()方法加日志拦截。1)HarmonyPatch:用特性方式对 StartCore 进行拦截。2)Prefix:这是 Thread.StartCore()执行之前要执行的方法。3)Osid:记录这个 Thread.Start()所对应的 操作系统线程id。4)StackTrace:记录调用线程的 函数调用栈。1.2 C#应用层&SDK 层注入追踪篇(下)01DnSpy 案例之 new Thread()追踪dnSpy 是一款免费开源轻量级的.NET 程序反编译和调试神器,让你能查看、修改甚至调试没有源代码的.NET 程序。如果你想要寻找一款 无侵入 的工具,那就是
5、 dnspy 了,可以把它当成 应用程序 直接部署在用户机器上,并采用 断点日志 功能实现 harmony 同样的效果。tips:1)$CALLSTACK:输出调用栈2.CLR 基础承载层 注入01perfview 原理介绍perfView 是一款由微软开发的、免费且功能强大的性能分析工具,主要用于帮助开发者诊断.NET 应用程序以及 Windows 操作系统自身的性能问题,其底层使用 Windows 事件跟踪(Event Tracing for Windows,ETW)技术。ETW 是 Windows 内核级的高性能事件记录系统,可以提供非常详细且低开销的诊断信息。tips:在 CLR 中有
6、大量的日志操作,默认是关闭的,由 informational_event_enabled_p 全局变量控制。一旦 perfview 开启,这个开关就会打开,随后 大量的日志写入,比如 gc 处理日志。2.1 CLR 基础承载层追踪篇(上)01perfview 案例之 观察 GC 详情你发现程序运行了一段时间之后出现系统级变慢,想知道是不是因为高频GC触发所致,这时候就可以通过 perfview 的 stats 视图观察 GC 的所有详情。eg:下面是向程序灌 1.5G 数据的 GC 触发详情。2.2 CLR 基础承载层追踪篇(下)01dottrace 案