.NET运行时中的监测和可观测性

今年5月份的时候研究分布式追踪的问题知道了的拦截方式比较零散, 刚好8月份的时候看到这篇文章,这个文章总结的比较完整。存档了很久,趁今天有空翻译给大家。原文地址,校验:张蘅水

.NET是一个托管运行时,这意味着它提供了“管理”您的程序的高级功能,从简介到公共语言运行时(CLR)(2007年编写):

运行时具有许多功能,因此按如下方式对它们进行分类很有用:

  1. 基本功能 对其他功能设计有广泛影响的功能。这些包括:
    1.垃圾收集
    2.记忆安全和类型安全
    3.对编程语言的高级支持。

  2. 辅助功能 - 许多有用的程序可能不需要基本特性所支持的功能:
    1.使用AppDomains进行程序隔离
    2.程序安全和沙盒

  3. 其他功能 - 所有运行时环境都需要但不利用CLR基本功能的功能。相反,它们是创建完整编程环境的结果。其中包括:
    1.版本
    2.Debugging/Profiling
    3.互操作

您可以看到,“Debugging/Profiling”虽然不是基本或辅助功能,但由于“ 需要创建完整的编程环境 ” ,它仍然会进入列表。

这篇文章的其余部分将看什么 监测,可观测性和内省功能核心CLR提供,为什么他们是有用的,如何提供他们。

为了便于浏览,帖子分为3个主要部分(最后有一些“额外阅读材料”):

  • 诊断(Diagnostics)

    • Perf View(性能分析工具)

    • 共同基础设施

    • 未来的计划

  • 剖析(Profiling)

    • ICorProfiler API

    • 分析 v .调试

  • 调试(Debugging)

    • ICorDebug API

    • SOS和DAC

    • 第三方调试器

    • 记忆转储

0|1诊断(Diagnostics)



首先,我们将查看CLR提供的诊断信息,传统上这些信息是通过“Windows事件跟踪”(ETW)提供的。

CLR提供的各种事件涉及:

  • 垃圾收集(GC)

  • 即时(JIT)编译

  • 模块和AppDomains

  • 线程和锁争用

  • 以及更多

例如,这是触发AppDomain Load事件的地方,这是Exception Thrown事件,这里是GC Allocation Tick事件。

Perf View

如果你想看到来自你的.NET程序的ETW事件,我建议使用优秀的PerfView工具,从这些PerfView教程开始,或者这个优秀的演讲PerfView:终极.NET性能工具。PerfView被广泛认可,因为它提供了宝贵的信息,例如Microsoft工程师经常将其用于性能调查。

640?wx_fmt=png

共同基础设施

但是,如果从名称中不清楚,ETW事件仅在Windows上可用,这并不适合新的.NET“跨平台”世界。您可以在Linux上使用PerfView进行性能跟踪(通过LTTng),但这只是cmd-line集合工具,称为“PerfCollect”,分析和丰富的UI(包括flamegraphs)目前仅适用于Windows。

但是如果你想分析.NET Performance Linux,还有其他一些方法:

  • 在Linux上使用.NET Core获取LTTng事件的堆栈

  • Linux性能问题

上面的第二个链接讨论了在.NET Core中正在使用的新“EventPipe”基础架构(以及EventSources和EventListeners,你能发现一个主题!),你可以看到它在跨平台性能监控设计中的目标。在高层次上,它将为CLR提供一个单独的位置来推动与诊断和性能相关的“事件”。然后,这些“事件”将被路由到一个或多个记录器,例如,可能包括ETW,LTTng和BPF,精确记录器由CLR运行的OS /平台确定。.NET Cross-Plat性能和事件设计中还有更多背景信息可以解释不同日志记录技术的优缺点。

“事件管道”中正在进行的所有工作都在“性能监控”项目和相关的“EventPipe”问题中进行跟踪。

未来的计划

最后,还有一个性能分析控制器的(Performance Profiling Controller )未来计划,其目标如下:

控制器负责以简单和跨平台的方式控制性能分析基础结构和.NET性能诊断组件生成的性能数据。

我们的想法是通过从“事件管道”中提取所有相关数据,通过HTTP服务器公开以下功能:

REST API

  • Pri 1:简单分析:为运行时间配置X个时间并返回跟踪。

  • Pri 1:高级分析:开始跟踪(以及配置)

  • Pri 1:高级分析:停止跟踪(对此调用的响应将是跟踪本身)

  • Pri 2:获取与所有EventCounters或指定EventCounter相关的统计信息。

可浏览的HTML页面

  • Pri 1:流程中所有托管代码堆栈的文本表示。

  • 提供当前正在运行的用作简单诊断报告的快照概述。

  • Pri 2:显示EventCounters的当前状态(可能具有历史记录)。
    * 提供现有计数器及其值的概述。
    * 开放性问题:我不相信存在必要的公共API来枚举EventCounters。

我很高兴看到“性能分析控制器(Performance Profiling Controller)”(PPC?)的位置,我认为将这种内置到CLR中确实非常有价值,这是其他运行时的内容。

0|1剖析(Profiling)



CLR提供的另一个强大功能是Profiling API,它(大部分)被第三方工具用于在非常低级别挂钩到运行时。您可以在此概述中找到有关API的更多信息,但在较高级别,它允许您连接在以下情况下触发的回调:

  • GC相关事件发生

  • 抛出异常

  • 装配/卸载装配

  • 更多,更多

640?wx_fmt=png

来自BOTR页面的图像分析API - 概述

此外还有其他非常强大的功能。首先,您可以设置每次执行.NET方法时调用的挂钩,无论是在运行时还是用户代码中。这些回调被称为“进入/离开”钩子,并且有一个很好的示例显示如何使用它们,但为了使它们工作,您需要了解不同操作系统和CPU架构的“调用约定”,这并不总是容易的。另外,作为警告,Profiling API是一个只能通过C / C ++代码访问的COM组件,你不能在C#/ F#/ VB.NET中使用它!

其次,Profiler能够通过SetILFunctionBody()API在JIT 之前重写任何.NET方法的IL代码。这个API功能非常强大,构成了许多.NET APM工具的基础,您可以在我之前的文章中了解更多关于如何使用它的方法。如何模拟密封类和静态方法以及随附的代码。

ICorProfiler API

事实证明,运行时必须执行各种疯狂的技巧才能使Profiling API正常工作,只需查看进入此PR的内容允许重新连接(有关'ReJIT'的详细信息,请参阅ReJIT:A How-To指南)。

所有Profiling API接口和回调的总体定义可在\vm\inc\corprof.idl中找到(请参阅接口说明语言)。但它分为2个逻辑部分,一个是Profiler - >'Execution Engine'(EE)接口,称为ICorProfilerInfo

// Declaration of class that implements the ICorProfilerInfo* interfaces, which allow the// Profiler to communicate with the EE.  This allows the Profiler DLL to get// access to private EE data structures and other things that should never be exported// outside of the EE.

这在以下文件中实现:

  • \VM\proftoeeinterfaceimpl.h

  • \VM\proftoeeinterfaceimpl.inl

  • \VM\proftoeeinterfaceimpl.cpp

另一个主要部分是EE - > Profiler回调,它们在ICorProfilerCallback界面下组合在一起:

// This module implements wrappers around calling the profiler's // ICorProfilerCallaback* interfaces. When code in the EE needs to call the// profiler, it goes through EEToProfInterfaceImpl to do so.

这些回调在以下文件中实现:

  • VM\eetoprofinterfaceimpl.h

  • VM\eetoprofinterfaceimpl.inl

  • VM\eetoprofinterfaceimpl.cpp

  • VM\eetoprofinterfacewrapper.inl

最后,值得指出的是,Profiler API可能无法在.NET Core运行的所有操作系统和CPU-arch上运行,例如Linux上的ELT调用存根问题,有关详细信息,请参阅CoreCLR Profiler API的状态。

分析和调试(Profiling v. Debugging)

除此之外,“分析”和“调试”确实有一些重叠,因此从CLR调试与CLR分析中了解.NET运行时上下文中不同的API提供什么是有帮助的。

640?wx_fmt=png

0|1调试(Debugging)



调试意味着不同的事情不同的人,比如我问在Twitter上“ 什么是你调试的.NET程序的途径 ”,并得到了广泛的不同反应,虽然反应两组含有一个很好的工具清单和技术,所以他们值得一试,谢谢#LazyWeb!

但也许这句话最好总结一下Debugging究竟是什么?

640?wx_fmt=jpeg

CLR提供了与调试相关的非常广泛的功能,但为什么需要提供这些服务,优秀的帖子为什么托管调试与本机调试不同?提供了3个理由:

  1. 可以在硬件级别抽象本机调试,但需要在IL级别抽象管理调试

  2. 托管调试需要大量的信息,直到运行时才可用

  3. 托管调试器需要与垃圾收集器(GC)协调

所以给一个体面的经验,CLR 具有提供更高级别的调试API称ICorDebug,这将在下面从“常用的调试方案”的图像中显示的BOTR:

640?wx_fmt=png

此外,还有很好的描述了不同部分如何在管理断点如何工作中相互作用?,虽然描述是上图中的相反!

Here’s an overview of the pipeline of components:1) End-user2) Debugger (such as Visual Studio or MDbg).3) CLR Debugging Services (which we call "The Right Side"). This is the implementation of ICorDebug (in mscordbi.dll).
---- process boundary between Debugger and Debuggee ----4) CLR. This is mscorwks.dll. This contains the in-process portion of the debugging services (which we call "The Left Side") which communicates directly with the RS in stage #3.5) Debuggee's code (such as end users C# program)

ICorDebug API

但是如何实现所有这些以及从CLR Debugging简要介绍的不同组件是什么:

所有.Net调试支持都在我们称之为“The Dac”的dll之上实现。此文件(通常命名mscordacwks.dll)是我们的公共调试API(ICorDebug)以及两个私有调试API 的构建块:SOS-Dac API和IXCLR。

在一个完美的世界中,每个人都会使用ICorDebug我们的公共调试API。但是,像您这样的工具开发人员所需的绝大多数功能都缺乏ICorDebug。这是我们正在修复的问题,但这些改进将进入CLR v.next,而不是旧版本的CLR。实际上,ICorDebugAPI仅在CLR v4中添加了对故障转储调试的支持。任何调试CLR v2崩溃转储的人根本无法使用ICorDebug

(有关其他文章,请参阅SOS和ICorDebug)

ICorDebugAPI实际上是分成多个接口,也有在他们的70!我不会在这里列出所有内容,但是我将展示它们所属的类别,有关更多信息,请参阅ICorDebug的分区,其中包含此列表,因为它更详细。

  • 顶级(Debugging): ICorDebug + ICorDebug2是顶级接口,有效地充当ICorDebugProcess对象的集合。

  • 回调(Callbacks):通过调试器实现的回调对象上的方法调度托管调试事件

  • 进程(Process):这组接口表示正在运行的代码,并包含与事件相关的API。

  • 代码/类型检查(Code / Type Inspection): 主要可以在静态PE映像上运行,但实时数据有一些便捷方法。

  • 执行控制(Execution Control):执行是“检查”线程执行的能力。实际上,这意味着放置断点(F9)和踩踏(F11步入,F10步进,S + F11步出)等。ICorDebug的执行控制仅在托管代码中运行。

  • 线程+调用堆栈(Threads + Callstacks):调用堆栈是调试器检查功能的支柱。以下接口与获取callstack有关。ICorDebug仅公开调试托管代码,因此堆栈跟踪仅受管理。

  • 对象检查(Object Inspection):对象检查是API的一部分,它允许您在整个调试对象中查看变量的值。对于每个接口,我列出了“MVP”方法,我认为必须简洁地传达该接口的用途。

另外需要注意的是,与Profiling APIs一样,调试API的支持级别因操作系统和CPU架构而异。例如,截至2018年8月,“没有针对Linux ARM进行托管调试和诊断的解决方案”。有关“Linux”支持的更多信息,请参阅这篇很棒的文章,在Linux上使用LLDB调试.NET Core,并从Microsoft 检出诊断存储库,其目标是更容易在Linux上调试.NET程序。

最后,如果你想看看ICorDebugAPI在C#中的样子,看一下CLRMD库中包含的包装器,包括所有可用的回调(CLRMD将在后面的文章中进行更深入的介绍)。

SOS和DAC

“数据访问组件(Data Access Component)”(DAC)在BOTR页面中有详细讨论,但实际上它提供了对CLR数据结构的“进程外”访问,因此可以从另一个进程读取其内部详细信息。这允许调试器(via ICorDebug)或'Son of Strike'(SOS)扩展进入CLR的运行实例或内存转储,并找到如下内容:

  • 所有正在运行的线程

  • 托管堆上有哪些对象

  • 有关方法的完整信息,包括机器代码

  • 当前的'堆栈跟踪'

除此之外,如果您想要解释所有奇怪的名称和一点'.NET历史课',请参阅此Stack Overflow答案。

SOS命令的完整列表非常令人印象深刻,并且在WinDBG旁边使用它可以让您非常低级地了解程序和CLR中发生的情况。要了解它是如何实现的,让我们看一下这个!HeapStat命令,该命令可以为您提供.NET GC正在使用的不同堆大小的摘要:

640?wx_fmt=png

(来自SOS的图片:即将发布的版本有一些新命令 - HeapStat)

这是代码流,显示了SOS和DAC如何协同工作:

  • SOS完整!HeapStat命令(链接)

  • SOS!HeapStat处理'Workstation GC' 的命令中的代码(链接)

  • SOS GCHeapUsageStats(..)功能,重负荷(链接)

  • 共享DacpGcHeapDetails包含指向GC堆中主数据的指针的数据结构,例如段,卡表和各代(链接)

  • GetGCHeapStaticData填充DacpGcHeapDetails结构的DAC函数(链接)

  • 共享DacpHeapSegmentData包含GC堆的单个“段”的详细信息的数据结构(链接)

  • GetHeapSegmentData(..)填充DacpHeapSegmentData结构的DAC(链接)

第三方'调试器'(3rd Party ‘Debuggers’)

由于Microsoft发布了调试API,它允许第三方使用ICorDebug接口,这里列出了我遇到的一些内容:

  • 调试器.NET Core运行时来自三星

    • 调试器提供GDB / MI或VSCode调试适配器接口,并允许在.NET Core运行时下调试.NET应用程序。

    • 可能是他们将.NET Core移植到他们的Tizen OS的工作的一部分

  • dnSpy - “.NET调试器和汇编编辑器”

    • 一个非常令人印象深刻的工具,它是一个'调试器','汇编编辑器','十六进制编辑器','反编译器'等等!

  • MDbg.exe(.NET Framework命令行调试程序)

    • 可以作为NuGet包和GitHub存储库使用,也可以从Microsoft下载。

    • 但是,目前MDBG似乎不适用于.NET Core,请参阅端口MDBG到CoreCLR和ETA以将mdbg移植到coreclr以获取更多信息。

  • JetBrains'Rider'允许在Windows上进行.NET Core调试

    • 虽然由于许可问题引起了一些争议

    • 有关更多信息,请参阅此HackerNews主题

记忆转储(Memory Dumps)

我们要看的最后一个区域是“内存转储”,可以从实时系统中捕获并离线分析。.NET运行时一直很好地支持在Windows上创建“内存转储”,现在.NET Core是“跨平台”,也可以在其他操作系统上使用相同的工具。

“内存转储”的一个问题是,获取SOS和DAC文件的正确匹配版本可能会非常棘手。幸运的是,Microsoft刚刚发布了以下dotnet symbolCLI工具:

可以下载任何给定核心转储,minidump或任何支持平台的文件格式(如ELF,MachO,Windows DLL,PDB和便携式PDB)的调试所需的所有文件(给出coreclr模块的符号,模块,SOS和DAC)。

最后,如果你花费任何时间分析'内存转储',你真的应该看看微软几年前发布的优秀的CLR MD库。我之前已经写过你可以用它做什么,但简而言之,它允许你通过一个直观的C#API与内存转储交互,其中的类可以访问ClrHeap,GC Roots,CLR Threads,Stack Frames和更多。实际上,除了实现工作所需的时间之外,CLR MD还可以实现大多数(如果不是全部)SOS命令。

但是从宣布帖子来看它是如何运作的:

ClrMD托管库是CLR仅内部调试API的包装器。虽然这些仅内部API对于诊断非常有用,但我们不支持它们作为公开的,有文档的版本,因为它们非常难以使用并且与CLR的其他实现细节紧密耦合。ClrMD通过围绕这些低级调试API提供易于使用的托管包装来解决此问题。

通过在官方支持的库中提供这些API,Microsoft使开发人员能够在CLRMD之上构建各种工具,这是一个很好的结果!


总而言之,.NET Runtime提供了广泛的诊断,调试和分析功能,可以深入了解CLR内部的情况。

原文地址:https://www.cnblogs.com/WithLin/p/9798485.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YbtOJ#532-往事之树【广义SAM,线段树合并】

正题 题目链接:https://www.ybtoj.com.cn/problem/532 题目大意 给出nnn个点的一个TrieTrieTrie树,定义SxS_xSx​表示节点xxx代表的字符串 求max{∣LCP(Sx,Sy)∣∣LCS(Sx,Sy)∣}(x≠y)max\{|LCP(S_x,S_y)||LCS(S_x,S_y)|\}(x\neq y)max{∣LCP(Sx​,Sy​)∣∣LCS(S…

【并查集】公司搬迁

题目大意 给出n,a,b和n个数,有两个集合A,B,如果x放在A中则a-x必须存在且在A中,B同理,问你是否有合法方案 解题思路 不难发现,如果a-x或b-x存在,那么和x必须在同一个集合(若x放A中b-x放B中则不…

牛客练习赛 71 AC

A - 回文数 回文数条件:奇数个数的个数最多有一个 如果0的数量是0,那么直接先找到奇数个数的数是谁,然后正序输出一半逆序输出一半即可。 如果0的数量不是0,只需要找到一个偶数个个数的数放置第一个即可(只需要放一个…

开源文件服务器file-service介绍

File-service一个基于ASP.NET Core的可伸缩、通用的文件服务器。通常后端项目可能会有头像、图片、音频、视频等上传/下载需求,这些需求都可以抽象为文件服务。功能特点支持Linux(推荐)、Windows可伸缩式架构,支持部署1-N台文件服…

【二分】走亲戚

题目大意 平面上有n个点,给出m个询问,每个询问要回答从x轮流往右往左去到最远的点,最后到达的点 解题思路 对于每个询问,每次二分左右可以到多远,直到不能动为止 考虑时间,对于重复走一个范围的&#xf…

CF1375F-Integer Game【交互】

正题 题目链接:https://www.luogu.com.cn/problem/CF1375F 题目大意 给出a,b,ca,b,ca,b,c。先手每次指定一个数kkk,然后后手指定一个数字加上kkk,若有相同的数则先手胜利,操作次数超过100010001000后后手胜。后手不能两次操作同一个数。 你…

Stars(树状数组)

题意: m个星星,一个星星的等级取决于有多少其他星星的横纵坐标不大于它,如果有x个,该星星等级为x 问各个等级的星星有多少个? (题目会按照y的升序给出星星坐标) 题解: 树状数组入…

AtCoder Regular Contest 105 部分 NIM游戏

TESyyds,本来以为又要3:1,结果创造历史!!!非常激动啊好久好久没看过让二追三了。 无缝衔接回旋踢,qa插眼we。送给雷达哥 A - Fourtune Cookies 签到题 #define IO ios::sync_with_stdio(false);cin.tie(…

【状压DP】作业

题目大意 有n个数,让你对其排列,令排列后的第i个数字为sis_isi​,该排列要满足: ∀i∈[1,n),si≤si1\forall i\in [1,n),s_i\leq s_{i1}∀i∈[1,n),si​≤si1​∀i∈[1,n),∣(min(si,si1),max(si,si1))∩{sj∣k>i}∣≤bi\fora…

Lost Cows(树状数组)

试题链接 题意: 求出一个1到n的排列,这个排列只告诉了你从第二个数字开始的比这个数字小的数的个数。 题解: 如果一个数p,p的前面有m个比他小的数,后面有n个比他小的数,那p的位置…

P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】

正题 题目链接:https://www.luogu.com.cn/problem/P2611 题目大意 r∗cr*cr∗c的网格上有nnn个标记点,然后求有多少个矩形包含至少一个标记点。 1≤r,c≤4104,1≤n≤1051\leq r,c\leq 4\times 10^4,1\leq n\leq 10^51≤r,c≤4104,1≤n≤105 保证数据随机 解题思路…

上学要迟到了【最短路转化】

上学要迟到了 题目 牛牛早上起床一看,自己睡过了,赶紧起床准备去学校,他去学校只有两种方式,坐公交车和步行,牛牛去学校是一条直线,这条直线上总共有 nnn 个车站,车站之间的距离都是相等的&am…

Microsoft Tech Summit 2018 课程简述:利用 Windows 新特性开发出更好的手绘视频应用...

概述Microsoft Tech Summit 2018 微软技术暨生态大会将于10月24日至27日在上海世博中心举行,这也会是国内举办的最后一届 Tech Summit,2019 年开始会以 Microsoft Ignite Tour 的形式出现,大家可以在官网查看本次会议信息:https:/…

牛牛和牛可乐的赌约

来源:牛客网: 牛牛和牛可乐的赌约 时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 牛可乐发明了一种n面骰子(点数分别从1{}1到{}nn&…

【结论】友谊序列

题目大意 有两个大小为n的数组a,b(所有数互不相等,且大于0),a,b中的数组成集合S,问可以构成aixorbj∈Sa_i\ xor\ b_j\in Sai​ xor bj​∈S的数对(i,j)的方案数的奇偶性 解题思路 若aixorbjaka_i\ xor\ b_ja_kai​ x…

GitHub 发布 2018 年开源项目趋势预测

Github 发布了一篇博客,预测了 2018 年开源项目的发展趋势,这些趋势可以帮助开发人员在共享知识的同时,寻求方法简化流程,并 get 新技能。去年,Github 有来自将近 200 个国家的 2400 万的开发者聚集在一起,…

YbtOJ#652-集合比较【Treap】

正题 题目链接:http://www.ybtoj.com.cn/problem/652 题目大意 定义一个元素为一个有序集合包含两个元素C{A,B}C\{A,B\}C{A,B} 集合C{A,B}C\{A,B\}C{A,B}的大小以AAA为第一关键字,BBB为第二关键字比较大小。 开始有两个元素S{S,S},T{T,T}S\{S,S\},T\{T,T\}S{S,S},…

牛牛和牛可乐的赌约2

来源:牛客网: 时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 262144K,其他语言524288K 64bit IO Format: %lld题目描述 牛牛感觉在上一次赌约中,情况对于自己非常不利,所以决定再赌一…

【线段树】二进制

题目大意 有一个二进制数&#xff0c;让你进行以下操作&#xff1a; 将一个区间的数字按升/降序排列查询一个区间的数字构成的数 解题思路 可以用线段树来维护每一位&#xff0c;预处理出2的整次幂&#xff0c;上传时把左儿子乘上右儿子长度次幂即可 code #include<cstd…