设置分析环境

注释

.NET Framework 4 中的分析发生了重大更改。

当托管进程(应用程序或服务)启动时,它将加载公共语言运行时(CLR)。 初始化 CLR 时,它会评估以下两个环境变量,以确定进程是否应连接到探查器:

  • COR_ENABLE_PROFILING:仅当此环境变量存在且设置为 1 时,CLR 才会连接到探查器。

  • COR_PROFILER:如果COR_ENABLE_PROFILING检查通过,CLR 将连接到具有此 CLSID 或 ProgID 的探查器,该探查器必须以前存储在注册表中。 COR_PROFILER环境变量定义为字符串,如以下两个示例所示。

    set COR_PROFILER={32E2F4DA-1BEA-47ea-88F9-C5DAF691C94A}
    set COR_PROFILER="MyProfiler"
    

若要分析 CLR 应用程序,必须在运行应用程序之前设置COR_ENABLE_PROFILING和COR_PROFILER环境变量。 还必须确保已注册探查器 DLL。

注释

从 .NET Framework 4 开始,探查器无需注册。

注释

若要在 .NET Framework 4 及更高版本中使用 .NET Framework 2.0、3.0 和 3.5 探查器,必须设置COMPLUS_ProfAPI_ProfilerCompatibilitySetting环境变量。

环境变量范围

如何设置COR_ENABLE_PROFILING和COR_PROFILER环境变量将确定其影响范围。 可通过以下方式之一设置这些变量:

  • 如果在 ICorDebug::CreateProcess 调用中设置变量,它们将仅适用于当时运行的应用程序。 (它们也适用于继承环境的应用程序启动的其他应用程序。

  • 如果在命令提示符窗口中设置变量,它们将应用于从该窗口启动的所有应用程序。

  • 如果在用户级别设置变量,它们将应用于以文件资源管理器开头的所有应用程序。 设置变量后打开的命令提示符窗口将具有这些环境设置,从该窗口开始的任何应用程序也是如此。 若要在用户级别设置环境变量,请右键单击 “我的计算机”,单击“ 属性”,单击“ 高级 ”选项卡,单击“ 环境变量”,然后将变量添加到 “用户变量 ”列表中。

  • 如果在计算机级别设置变量,它们将应用于在该计算机上启动的所有应用程序。 在该计算机上打开的命令提示符窗口将具有这些环境设置,从该窗口启动的任何应用程序也是如此。 这意味着该计算机上的每个托管进程都将从探查器开始。 若要在计算机级别设置环境变量,请右键单击“ 我的计算机”,单击“ 属性”,单击“ 高级 ”选项卡,单击“ 环境变量”,将变量添加到 “系统变量 ”列表中,然后重新启动计算机。 重启后,变量将适用于系统范围。

如果要分析 Windows 服务,则必须在设置环境变量并注册探查器 DLL 后重新启动计算机。 有关这些注意事项的详细信息,请参阅 分析 Windows 服务部分。

其他注意事项

  • 探查器类实现 ICorProfilerCallbackICorProfilerCallback2 接口。 在 .NET Framework 版本 2.0 中,探查器必须实现 ICorProfilerCallback2。 如果未加载, ICorProfilerCallback2 则不会加载。

  • 在给定环境中,只有一个探查器可以一次分析进程。 可以在不同的环境中注册两个不同的探查器,但每个探查器必须分析单独的进程。 探查器必须作为进程内 COM 服务器 DLL 实现,该 DLL 映射到所分析进程的同一地址空间。 这意味着探查器在进程内运行。 .NET Framework 不支持任何其他类型的 COM 服务器。 例如,如果探查器想要从远程计算机监视应用程序,则必须在每台计算机上实现收集器代理。 这些代理将批处理结果并将其传达给中央数据收集计算机。

  • 由于探查器是进程内实例化的 COM 对象,因此每个被分析的应用程序都将有自己的探查器副本。 因此,单个探查器实例不必处理来自多个应用程序的数据。 但是,必须向探查器的日志记录代码添加逻辑,以防止日志文件从其他分析的应用程序覆盖。

初始化探查器

当两个环境变量检查通过时,CLR 会以与 COM CoCreateInstance 函数类似的方式创建探查器的实例。 不会通过直接调用 CoCreateInstance加载探查器。 因此,避免调用 CoInitialize需要设置线程模型。 然后,CLR 在探查器中调用 ICorProfilerCallback::Initialize 方法。 此方法的签名如下所示。

HRESULT Initialize(IUnknown *pICorProfilerInfoUnk)

探查器必须查询 pICorProfilerInfoUnkICorProfilerInfoICorProfilerInfo2 接口指针,并保存它,以便在分析期间稍后可以请求更多信息。

设置事件通知

然后,探查器调用 ICorProfilerInfo::SetEventMask 方法,以指定它感兴趣的通知类别。 例如,如果探查器只对函数输入和离开通知和垃圾回收通知感兴趣,则指定以下内容。

ICorProfilerInfo* pInfo;
pICorProfilerInfoUnk->QueryInterface(IID_ICorProfilerInfo, (void**)&pInfo);
pInfo->SetEventMask(COR_PRF_MONITOR_ENTERLEAVE | COR_PRF_MONITOR_GC)

通过以这种方式设置通知掩码,探查器可以限制接收的通知。 此方法可帮助用户构建简单或特殊用途探查器。 它还会减少 CPU 时间,这会浪费发送探查器只会忽略的通知。

某些探查器事件是不可变的。 这意味着,在回调中 ICorProfilerCallback::Initialize 设置这些事件后,它们将无法关闭,并且无法打开新事件。 尝试更改不可变事件将导致 ICorProfilerInfo::SetEventMask 返回失败的 HRESULT。

分析 Windows 服务

分析 Windows 服务类似于分析公共语言运行时应用程序。 这两个分析作都通过环境变量启用。 由于作系统启动时会启动 Windows 服务,因此本主题中前面讨论的环境变量必须已存在,并设置为系统启动前所需的值。 此外,必须在系统上注册分析 DLL。

设置COR_ENABLE_PROFILING并COR_PROFILER环境变量并注册探查器 DLL 后,应重启目标计算机,以便 Windows 服务能够检测这些更改。

请注意,这些更改将在系统范围内启用分析。 若要防止随后运行的每个托管应用程序被分析,应在重启目标计算机后删除系统环境变量。

此方法还会导致分析每个 CLR 过程。 探查器应将逻辑添加到其 ICorProfilerCallback::Initialize 回调,以检测当前进程是否感兴趣。 如果不是,探查器可以在不执行初始化的情况下失败回调。

另请参阅