设置分析环境

更新:2007 年 11 月

在前面的主题中,我们描述了当应用程序和探查器运行时发生的情况。但是,当应用程序启动时,应用程序和探查器怎样进行连接? 公共语言运行库 (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 已注册。

环境变量范围

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

  • 如果在 ICorDebug::CreateProcess 调用中设置变量,这些变量将只应用于当时正在运行的应用程序。(它们还将应用于由该应用程序启动的其他应用程序,这些应用程序继承环境。)

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

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

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

如果要分析 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)

探查器必须查询 pICorProfilerInfoUnk 来检索 ICorProfilerInfoICorProfilerInfo2 接口指针,并保存该指针以便稍后在分析过程中能够请求更多信息。

设置事件通知

探查器随后将调用 ICorProfilerInfo::SetEventMask 方法来指定它关注的通知类别。例如,如果探查器只关注函数进入和离开通知以及垃圾回收通知,它将指定以下内容。

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

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

某些探查器事件是不可变的。这意味着,一旦在 ICorProfilerCallback::Initialize 回调中设置了这些事件,就无法禁用这些事件,并且无法启用新事件。尝试更改不可变的事件将导致返回失败 HRESULT 的 ICorProfilerInfo::SetEventMask

请参见

其他资源

.NET Framework 中的分析

分析概述