Create Custom Instruments
内置的工具提供了大量关于应用程序内部工作的信息。有时,您可能希望更紧密地将这些信息与自己的代码相结合。例如,不是每次调用函数时收集数据,而是在收集数据时设置条件。或者,您可能希望深入了解自己的代码,而不是内置的工具允许。Built-in instruments provide a great deal of information about the inner workings of your app. Sometimes, though, you may want to tailor this information more closely to your own code. For example, instead of gathering data every time a function is called, you might set conditions on when data is gathered. Alternatively, you might want to dig deeper into your own code than the built-in instruments allow.
IMPORTANT
只要有可能,建议您使用现有的工具,而不是创建新的工具。创建自定义工具是一个高级特性。Whenever possible, it is recommended that you use an existing instrument instead of creating a new instrument. Creating custom instruments is an advanced feature.
有关自定义工具About Custom Instruments
自定义工具使用DTrace的实施。DTrace动态跟踪设备是由太阳最初创建和移植到OS X,因为DTrace嵌入操作系统内核,它允许您访问底层信息的内核和用户在您的计算机上运行的进程。许多内置工具已经基于DTrace。DTrace本身是一个复杂的工具,但工具提供了一个简单的界面,让您无需复杂访问DTrace的力量。Custom instruments use DTrace for their implementation. DTrace is a dynamic tracing facility originally created by Sun and ported to OS X. Because DTrace taps into the operating system kernel, it allows you to access low-level information about the kernel itself and the user processes running on your computer. Many of the built-in instruments are already based on DTrace. DTrace is itself a complex tool, but Instruments provides a simple interface that lets you access the power of DTrace without the complexity.
DTrace没有被移植到iOS,所以它是不可能的设备上运行的iOS创建自定义工具。DTrace has not been ported to iOS, so it is not possible to create custom instruments for devices running iOS.
IMPORTANT
虽然简化了创建自定义工具制造商DTrace探测过程中,你还应该熟悉DTrace和它如何工作之前,创造新的工具。许多更强大的调试和数据采集行动需要你写DTrace脚本。学习DTrace和D的脚本语言,看到Solaris动态跟踪指导,可以从Oracle技术网。关于dtrace命令行工具的信息,看到DTrace(1)Mac OS X的手册页。Although the custom instrument builder simplifies the process of creating DTrace probes, you should still be familiar with DTrace and how it works before creating new instruments. Many of the more powerful debugging and data gathering actions require you to write DTrace scripts. To learn about DTrace and the D scripting language, see the Solaris Dynamic Tracing Guide, available from the Oracle Technology Network. For information about the dtrace
command-line tool, see the dtrace(1) Mac OS X Manual Page.
NOTE
几个苹果应用程序即iTunes,DVD播放器和应用程序使用QuickTime防止数据采集通过DTrace(暂时或永久)为了保护敏感和受版权保护的资料。因此,不运行这些应用程序执行时,系统数据采集。Several Apple apps—namely, iTunes, DVD Player, and apps that use QuickTime—prevent the collection of data through DTrace (either temporarily or permanently) in order to protect sensitive and copyrighted data. Therefore, do not run those apps when performing systemwide data collection.
自定义工具使用DTrace探测器建造。探针就像一个传感器,放置在代码中。它相当于一个地点或事件,比如一个函数的入口点,而DTrace可以绑定。当执行函数或事件发生,相关的探测火灾,和DTrace运行任何行动与探头有关。最简单的收集关于DTrace行动操作系统和用户应用程序的行为在那一刻的数据。然而,作为操作的一部分运行自定义脚本是可能的。脚本让您使用DTrace功能微调你收集的资料。Custom instruments are built using DTrace probes. A probe is like a sensor that you place in your code. It corresponds to a location or event, such as a function entry point, to which DTrace can bind. When the function executes or the event is generated, the associated probe fires, and DTrace runs whatever actions are associated with the probe. Most DTrace actions simply collect data about the operating system and user app behavior at that moment. It is possible, however, to run custom scripts as part of an action. Scripts let you use the features of DTrace to fine tune the data you gather.
探针每遇到一次就开火,但每次探针点火时,与探针相关的动作不需要运行。谓词是一个条件语句,允许在探测操作运行时限制它。例如,您可以将探针限制到特定的进程或用户,或者当工具中的某个特定条件为真时,可以运行一个操作。默认情况下,探针没有任何谓词,这意味着每次探针触发时关联操作都会运行。但是,可以将任意数量的谓词添加到探针中,并使用运算符和运算符将它们连接起来,从而创建复杂的决策树。Probes fire each time they are encountered, but the action associated with the probe doesn’t need to run every time the probe fires. A predicate is a conditional statement that allows you to restrict when the probe’s action is run. For example, you can restrict a probe to a specific process or user, or you can run an action when a specific condition in your instrument is true. By default, probes do not have any predicates, meaning that the associated action runs every time the probe fires. You can add any number of predicates to a probe, however, and link them together using AND
and OR
operators to create complex decision trees.
一个定制的仪器由以下几个模块组成:A custom instrument consists of the following blocks:
-
一个描述块,包含该仪器的名称、类别和描述A description block, containing the name, category, and description of the instrument
-
一个或多个探针,每个探针包含其相关的动作和谓词。One or more probes, each containing its associated actions and predicates
-
一个数据声明区域,用于可选地声明所有探针共享的全局变量。A Data declaration area, for optionally declaring global variables shared by all probes
-
一个开始脚本,它可以选择性地初始化全局变量并执行该工具所需的启动任务。A Begin script, which optionally initializes global variables and performs startup tasks required by the instrument
-
一个结束脚本,可选执行最终的清理操作。An End script, which optionally performs final cleanup actions
自定义仪器必须至少有一个具有相关动作的探针。类似地,自定义工具应该有一个适当的名称和描述,将其标识给仪器用户。工具在库调色板中显示此描述性信息。提供良好的信息使人们更容易记住仪器的用途和使用方法。A custom instrument must have at least one probe with associated actions. Similarly, a custom instrument should have an appropriate name and description that identifies it to Instruments users. Instruments displays this descriptive information in the Library palette. Providing good information makes it easier to remember what the instrument does and how it should be used.
探针不需要有全局数据声明,也不需要开始和结束脚本。当您想在探针之间共享数据或为仪器提供某种初始配置时,这些元素用于高级仪器设计。在编写自定义脚本时描述了数据、开始和结束块的创建。Probes are not required to have a global Data declaration, or Begin and End scripts. These elements are used in advanced instrument design when you want to share data among probes or provide some sort of initial configuration for your instrument. The creation of Data, Begin, and End blocks is described in Write Custom Scripts.
创建自定义工具Create a Custom Instrument
创建一个自定义的DTrace工具,选择工具>建立新的仪器。这个命令显示仪表配置对话框,显示在图25-1。使用此表指定您的仪器信息,包括任何探针和自定义脚本。To create a custom DTrace instrument, choose Instrument > Build New Instrument. This command displays the instrument configuration dialog, shown in Figure 25-1. You use this sheet to specify your instrument information, including any probes and custom scripts.
至少,为您创建的每个自定义工具提供以下信息:At a minimum, provide the following information for every custom instrument you create:
-
名称。与库中的自定义工具相关联的名称。Name. The name associated with your custom instrument in the library.
-
类别.你的乐器出现在图书馆的类别。可以指定现有类别的名称,例如内存或创建自己的类。Category. The category in which your instrument appears in the library. You can specify the name of an existing category—such as Memory—or create your own.
-
描述。在库调色板和工具的工具提示中使用的工具描述。Description. The instrument description, used in both the Library palette and in the instrument’s tooltip.
-
探针供应商。探针类型和应该何时点火的细节。通常,这涉及指定探针应用的方法或函数。参见指定探测提供程序。Probe provider. The probe type and the details of when it should fire. Typically, this involves specifying the method or function to which the probe applies. See Specify the Probe Provider.
-
探头的作用。当探针触发时要记录的数据或要执行的脚本。Probe action. The data to record or the script to execute when your probe fires; see Add Actions to a Probe.
仪器应该至少包含一个探头,并且可能包含不止一个探头。探针定义由提供者信息、谓词信息和动作组成。所有探测必须至少指定提供者信息,并且几乎所有探测都定义某种行为。探针定义的谓词部分是可选的,但可以是一个非常有用的工具,用于将工具集中在正确的数据上。An instrument should contain at least one probe and may contain more than one. The probe definition consists of the provider information, predicate information, and action. All probes must specify the provider information at a minimum, and nearly all probes define some sort of action. The predicate portion of a probe definition is optional but can be a very useful tool for focusing your instrument on the correct data.
添加和删除探针Add and Delete Probes
每台新仪器都配有一个探头,可以配置。若要添加更多的探针,请单击工具配置对话框底部的Add按钮(+)。参见图25-2。Every new instrument comes with one probe that you can configure. To add more probes, click the Add button (+) at the bottom of the instrument configuration dialog. See Figure 25-2.
要从工具中删除探针,请单击探针选择它,然后单击工具配置对话框底部的“删除”按钮(-)。To remove a probe from your instrument, click the probe to select it and click the Remove button (-) at the bottom of the instrument configuration dialog.
添加探针时,为探针提供描述性名称是个好主意。默认情况下,仪器将每个探针分配一个顺序编号的名称,如探针1和探针2。When adding a probe, it is a good idea to provide a descriptive name for the probe. By default, Instruments assigns each probe a sequentially numbered name, such as Probe 1 and Probe 2.
指定探针提供程序Specify the Probe Provider
若要指定触发探针的位置点或事件,请将适当的提供者与探针关联起来。供应商是内核模块,代理DTrace,提供必要创建探针的仪器。您不需要知道提供者如何操作来创建一个工具,但是您需要知道每个提供者的基本功能。表25-1列出的应用程序和工具可用于自定义工具支持提供者。供应商列在仪器配置对话框中显示的名称,和DTrace提供者列用于DTrace脚本提供者的名称。To specify the location point or event that triggers a probe, associate the appropriate provider with the probe. Providers are kernel modules that act as agents for DTrace, providing the instrumentation necessary to create probes. You do not need to know how providers operate to create an instrument, but you do need to know the basic capabilities of each provider. Table 25-1 lists the providers that are supported by the Instruments app and available for use in your custom instruments. The Provider column lists the name displayed in the instrument configuration dialog, and the DTrace provider column lists the actual name of the provider used in the corresponding DTrace script.
Provider |
DTrace provider |
Description |
---|---|---|
User Process |
|
The probe fires on entry (or return) of the specified function in your code. You must provide the function name and the name of the library that contains it. |
Objective-C |
|
The probe fires on entry (or return) of the specified Objective-C method. You must provide the method name and the class to which it belongs. |
System Call |
|
The probe fires on entry (or return) of the specified system library function. |
DTrace |
|
The probe fires when DTrace itself enters a Begin, End, or Error block. |
Kernel Function Boundaries |
|
The probe fires on entry (or return) of the specified kernel function in your code. You must provide the kernel function name and the name of the library that contains it. |
Mach |
|
The probe fires on entry (or return) of the specified Mach library function. |
Profile |
|
The probe fires regularly at the specified time interval on each core of the machine. Profile probes can fire with a granularity that ranges from microseconds to days. |
Tick |
|
The probe fires at periodic intervals on one core of the machine. Tick probes can fire with a granularity that ranges from microseconds to days. You might use this provider to perform periodic tasks that are not required to be on a particular core. |
I/O |
|
The probe fires at the start of the specified kernel routine. For a list of functions monitored by this probe, use the |
Kernel Process |
|
The probe fires on the initiation of one of several kernel-level routines. For a list of functions monitored by this probe, use the |
User-Level Synchronization |
|
The probe fires at one of several synchronization points. You can use this provider to monitor mutex and read-write lock events. |
CPU Scheduling |
|
The probe fires when CPU scheduling events occur. |
在为探针选择提供程序之后,指定探针所需的信息。例如,对于某些函数级探测,提供者可能需要函数或方法名,以及您的代码模块或包含模块的类。其他提供者可能只需要您从弹出菜单中选择适当的事件。After selecting the provider for your probe, specify the information needed by the probe. For example, for some function-level probes, providers may need function or method names, along with your code module or else the class containing your module. Other providers may only need you to select appropriate events from a pop-up menu.
在配置了一个探针之后,您可以向它添加额外的谓词(以确定它应该何时触发),或者您可以继续定义该探针的操作。After you have configured a probe, you can add additional predicates to it (to determine when it should fire) or you can go ahead and define the action for that probe.
向探针添加谓词Add Predicates to a Probe
谓词使您能够控制探针动作何时由仪器执行。您可以使用谓词来防止工具在不需要时收集数据,或者认为数据可能是错误的。例如,如果代码只有在堆栈达到一定深度时才会显示异常行为,则使用谓词指定最小目标堆栈深度。每当探针触发时,仪器都会对相关谓词进行评估。只有当他们评估为true是DTrace执行相关行动。Predicates give you control over when a probe’s action is executed by Instruments. You can use predicates to prevent Instruments from gathering data when you don’t want it or think the data might be erroneous. For example, if your code exhibits unusual behavior only when the stack reaches a certain depth, use a predicate to specify the minimum target stack depth. Every time a probe fires, Instruments evaluates the associated predicates. Only if they evaluate to true does DTrace perform the associated actions.
-
在探测条件下单击Add按钮(+)。Click the Add button (+) in the probe conditions.
-
选择谓词类型。Select the type of predicate.
-
定义谓词值。Define the predicate values.
可以使用探针或谓词的Add按钮(+)添加后续谓词。若要删除谓词,请单击谓词旁边的“删除”按钮(-)。You can add subsequent predicates using the Add buttons (+) of either the probe or the predicate. To remove a predicate, click the Remove button (-) next to the predicate.
仪器根据它们出现的顺序从上到下对谓词进行求值。若要重新排列谓词,请单击谓词行,并将其拖到表中的新位置。可以使用和或运算符链接谓词,但不能将它们分组以创建嵌套条件块。相反,要谨慎地排列谓词,以确保检查适当的条件。Instruments evaluates predicates from top to bottom in the order in which they appear. To rearrange predicates, click the predicate’s row and drag it to a new location in the table. You can link predicates using AND
and OR
operators, but you cannot group them to create nested condition blocks. Instead, order your predicates carefully to ensure that the appropriate conditions are checked.
使用谓词行中的第一个弹出菜单选择要检查的数据作为条件的一部分。表25-2列出DTrace定义的标准变量,您可以使用您的谓词或脚本代码。可变列列出的名字出现在仪器的配置面板,和“DTrace变量”列对应的DTrace脚本中使用的变量的名称。除了测试标准变量之外,还可以通过在谓词字段中指定自定义变量类型来测试脚本代码中的自定义变量和常量。Use the first pop-up menu in a predicate row to choose the data to inspect as part of the condition. Table 25-2 lists the standard variables defined by DTrace that you can use in your predicates or script code. The Variable column lists the name as it appears in the instrument configuration panel, and the “DTrace variable” column lists the actual name of the variable used in corresponding DTrace scripts. In addition to testing the standard variables, you can test against custom variables and constants from your script code by specifying the Custom variable type in the predicate field.
Variable |
DTrace variable |
Description |
---|---|---|
Caller |
|
The value of the current thread’s program counter just before entering the probe. This variable contains an integer value. |
Chip |
|
The identifier for the physical chip executing the probe. This is a 0-based integer indicating the index of the current core. For example, a four-core machine has cores 0 through 3. |
CPU |
|
The identifier for the CPU executing the probe. This is a 0-based integer indicating the index of the current core. For example, a four-core machine has cores 0 through 3. |
Current Working Directory |
|
The current working directory of the current process. This variable contains a string value. |
Last Error # |
|
The error value returned by the last system call made on the current thread. This variable contains an integer value. |
Executable |
|
The name that was passed to |
User ID |
|
The real user ID of the current process. This variable contains an integer value. |
Group ID |
|
The real group ID of the current process. This variable contains an integer value. |
Process ID |
|
The process ID of the current process. This variable contains an integer value. |
Parent ID |
|
The process ID of the parent process. This variable contains an integer value. |
Interrupt Priority Level |
|
The interrupt priority level on the current CPU at the time the probe fired. This variable contains an unsigned integer value. |
Function |
|
The function name part of the probe’s description. This variable contains a string value. |
Module |
|
The module name part of the probe’s description. This variable contains a string value. |
Name |
|
The name portion of the probe’s description. This variable contains a string value. |
Provider |
|
The provider name part of the probe’s description. This variable contains a string value. |
Root Directory |
|
The root directory of the process. This variable contains a string value. |
Stack Depth |
|
The stack frame depth of the current thread at the time the thread fired. This variable contains an unsigned integer value. |
User Stack Depth |
|
The stack frame depth for user frames (omitting kernel mode frames) of the current thread at the time the thread fired. This variable contains an unsigned integer value. |
Relative Timestamp |
|
The current value of the system’s timestamp counter, in nanoseconds. Because this counter increments from an arbitrary point in the past, use it to calculate only relative time differences. This variable contains an unsigned 64-bit integer value. |
Virtual Timestamp |
|
The amount of time the current thread has been running, in nanoseconds. This value does not include time spent in DTrace predicates and actions. This variable contains an unsigned 64-bit integer value. |
Timestamp |
|
The current number of nanoseconds that have elapsed since 00:00 Universal coordinated Time, January 1, 1970. This variable contains an unsigned 64-bit integer value. |
|
|
The first 10 arguments to the probe, represented as raw 64-bit integers. If fewer than ten arguments were passed to the probe, the remaining variables contain the value 0. |
Custom |
The name of your variable |
Use this option to specify a variable or constant from one of your scripts. |
除了指定要检查的变量外,还必须指定比较运算符(等于、不等于等)和用于与变量进行比较的值。In addition to specifying a variable to inspect, you must specify a comparison operator (equals, does not equal, etc.) and a value to use for comparison against the variable.
向探针添加操作Add Actions to a Probe
当一个探测点定义你的乐器打探头的谓词条件评估为true,DTrace运行与探针相关的动作。您使用探针的操作来收集数据或执行附加处理。例如,如果您的探针监视特定的函数或方法,则可以将该函数的调用方和任何堆栈跟踪信息返回到仪表。如果您想要稍微高级一些的操作,您可以使用脚本变量来跟踪调用函数的次数,并报告该信息。如果你想要一个更高级的动作,你可以写一个脚本,使用内核级DTrace功能确定的函数使用锁的状态。在后一种情况下,脚本代码也可能返回锁的当前所有者(如果有的话),以帮助您确定代码不同线程之间的交互。When a probe point defined by your instrument is hit and the probe’s predicate conditions evaluate to true, DTrace runs the actions associated with the probe. You use your probe’s actions to gather data or to perform additional processing. For example, if your probe monitors a specific function or method, you could have it return the caller of that function and any stack trace information to Instruments. If you wanted a slightly more advanced action, you could use a script variable to track the number of times the function was called and report that information as well. And if you wanted an even more advanced action, you could write a script that uses kernel-level DTrace functions to determine the status of a lock used by your function. In this latter case, your script code might also return the current owner of the lock (if there is one) to help you determine the interactions among your code’s different threads.
图25-3展示仪器配置对话框让你指定你的探索行动的部分。脚本部分只包含一个文本字段,供您键入脚本代码。(仪器不验证你的代码之前通过DTrace,那么仔细,检查你的代码)底部包含指定你想要回到工具DTrace数据控件。你可以使用弹出式菜单配置内置DTrace变量你想回来。当第一个弹出菜单设置为记录在仪器中时,您可以选择从第二个弹出菜单中选择自定义,并返回其中一个脚本变量。Figure 25-3 shows the portion of the instrument configuration dialog where you specify your probe’s actions. The script portion simply contains a text field for you to type in your script code. (Instruments does not validate your code before passing it to DTrace, so check your code carefully.) The bottom section contains controls for specifying the data you want DTrace to return to Instruments. You can use the pop-up menus to configure the built-in DTrace variables you want to return. When the first pop-up menu is set to Record in Instruments, you can optionally choose Custom from the second pop-up menu and return one of your script variables.
当您配置工具返回一个自定义变量时,仪器要求您提供以下信息:When you configure your instrument to return a custom variable, Instruments asks you to provide the following information:
-
包含数据的脚本变量The script variable containing the data
-
应用于仪表接口中变量的名称。The name to apply to the variable in your instrument interface
-
变量的类型The type of the variable
您的探针返回到仪器的任何数据都被收集并显示在仪器的详细窗格中。细节窗格显示所有数据变量,无论类型如何。如果堆栈跟踪信息可用于特定的探针,则仪器将在仪表板的扩展详细区域显示该信息。此外,仪器自动查找由工具返回的整数数据类型,并将这些类型添加到您的工具可以在轨道窗格中显示的统计列表中。Any data your probe returned to Instruments is collected and displayed in your instrument’s detail pane. The detail pane displays all data variables regardless of type. If stack trace information is available for a specific probe, Instruments displays that information in the extended detail area of the inspector pane for your instrument. In addition, Instruments automatically looks for integer data types returned by your instrument and adds those types to the list of statistics your instrument can display in the track pane.
因为DTrace脚本运行在内核空间和仪器的应用程序运行在用户空间中,如果要返回一个自定义的指针的值基于脚本的变量工具,您必须创建一个缓冲区来保存变量的数据。最简单的方法来创建一个缓冲区使用制作或找到DTrace copyinstr函数子程序。子程序的copyinstr函数接受指向字符串并返回字符串中的一种形式,你可以返回到仪器的内容。同样,在制作子程序接受一个指针和大小的值,并返回一个缓冲区的数据,你可以稍后格式转化为字符串使用的系列关键词。这两个子程序的DTrace环境的一部分,可以从你的行动定义的任何部分使用探针。例如,返回C风格字符串指针的字符串,你只需把变量名与copyinstr函数子程序,如图25-4所示。Because DTrace scripts run in kernel space and the Instruments app runs in user space, if you want to return the value of a custom pointer-based script variable to Instruments, you must create a buffer to hold the variable’s data. The simplest way to create a buffer is to use the copyin
or copyinstr
subroutines found in DTrace. The copyinstr
subroutine takes a pointer to a C string and returns the contents of the string in a form you can return to Instruments. Similarly, the copyin
subroutine takes a pointer and size value and returns a buffer to the data, which you can later format into a string using the stringof
keyword. Both of these subroutines are part of the DTrace environment and can be used from any part of your probe’s action definition. For example, to return the string from a C-style string pointer, you simply wrap the variable name with the copyinstr
subroutine, as shown in Figure 25-4.
IMPORTANT
仪器自动将内置变量(如通过函数参数arg0 Arg9)与调用copyinstr函数如果变量类型设置为字符串。然而,工具不会自动包装脚本的自定义变量。您负责确保自定义变量中的数据与该变量指定的类型实际匹配。Instruments automatically wraps built-in variables (such as the arg0
through arg9
function arguments) with a call to copyinstr
if the variable type is set to string
. Instruments does not automatically wrap a script’s custom variables, however. You are responsible for ensuring that the data in a custom variable actually matches the type specified for that variable.
在一系列的内置变量支持的工具,见表25-2。有关脚本和脚本变量的更多信息,请参见编写自定义脚本。在DTrace子程序的更多信息,包括制作与copyinstr函数子程序,看到Solaris动态跟踪指导,可以从Oracle技术网。For a list of the built-in variables supported by Instruments, see Table 25-2. For more information on scripts and script variables, see Write Custom Scripts. For more information on DTrace subroutines, including the copyin
and copyinstr
subroutines, see the Solaris Dynamic Tracing Guide, available from the Oracle Technology Network.
Write Custom Scripts
你写的DTrace脚本使用的脚本语言,其语法是从C语言编程的一个大的子集。D语言将C语言的编程结构与一组特殊的函数和变量结合起来,帮助您跟踪应用程序中的信息。You write DTrace scripts using the D scripting language, whose syntax is derived from a large subset of the C programming language. The D language combines the programming constructs of the C language with a special set of functions and variables to help you trace information in your app.
下面的小节描述了在自定义工具中使用脚本的常用方法。这部分没有写DTrace脚本提供一个全面的概述的语言或过程。有关脚本和d语言的信息,请参见从Oracle技术网络中获得的Solaris动态跟踪指南。The following sections describe common ways to use scripts in your custom instruments. These sections do not provide a comprehensive overview of the D language or the process for writing DTrace scripts. For information about scripting and the D language, see the Solaris Dynamic Tracing Guide, available from the Oracle Technology Network.
编写开始和结束脚本Write Begin and End Scripts
如果你想做更多的返回信息的内置变量工具DTrace每当你行动的火灾,你需要编写自定义脚本。脚本直接与在内核级DTrace,提供有关核和活动过程的底层信息。大多数仪器使用脚本来收集信息不易从DTrace。还可以使用脚本在返回原始数据之前对原始数据进行操作。例如,您可以使用脚本将数据值标准化为特定的范围,如果您希望更容易地将该值与您的工具的跟踪窗格中的其他值进行图形比较。If you want to do more than return the information in DTrace’s built-in variables to Instruments whenever your action fires, you need to write custom scripts. Scripts interact directly with DTrace at the kernel level, providing access to low-level information about the kernel and the active process. Most instruments use scripts to gather information not readily available from DTrace. You can also use scripts to manipulate raw data before returning it to Instruments. For example, you can use a script to normalize a data value to a specific range if you want to make it easier to compare that value graphically with other values in your instrument’s track pane.
在仪器仪表配置,自定义对话框提供了几个地方,你可以写DTrace脚本:In Instruments, the custom instrument configuration dialog provides several areas where you can write DTrace scripts:
-
数据部分包含要在工具中使用的所有全局变量的定义。The Data section contains definitions of any global variables you want to use in your instrument.
-
开始部分包含工具的任何初始化代码。The Begin section contains any initialization code for your instrument.
-
每个探针都包含脚本代码作为动作的一部分。Each probe contains script code as part of its action.
-
结束部分包含用于工具的任何清理代码。The End section contains any cleanup code for your instrument.
所有脚本部分都是可选的。如果您的工具不需要它们,则不需要初始化脚本或清除脚本。但是,如果您的工具在其数据部分定义了全局变量,建议您还提供一个初始化脚本,将这些变量设置为已知值。d语言不允许您在全局变量声明中内联值,因此必须将这些赋值放在开始部分。例如,一个简单的数据段可能由一个变量声明组成,如以下:All script sections are optional. You are not required to have initialization scripts or cleanup scripts if your instrument does not need them. If your instrument defines global variables in its Data section, however, it is recommended that you also provide an initialization script to set those variables to a known value. The D language does not allow you to assign values inline with your global variable declarations, so you must put those assignments in your Begin section. For example, a simple Data section might consist of a single variable declaration, such as the following:
int myVariable;
相应的开始部分将包含以下代码来初始化该变量:The corresponding Begin section would then contain the following code to initialize that variable:
myVariable = 0;
如果你的行动改变相应的探针myVariable的值,你可以使用你的头端部分的格式和打印出变量的最终值。If your corresponding probe actions change the value of myVariable
, you can use the End section of your probe to format and print out the final value of the variable.
大多数脚本代码很可能与单个探针相关联。每个探针都有一个与其动作相关联的脚本。执行的时候一个探头的动作,DTrace运行脚本代码然后再返回所请求的任何数据恢复工具。因为将数据传递给仪器需要将数据从内核空间复制到工具应用程序空间,所以您应该通过在“仪表配置”对话框中记录“以下数据”部分中配置适当的条目,将数据返回给仪器。从脚本代码手动返回的变量可能无法正确返回到仪表。Most of your script code is likely to be associated with individual probes. Each probe can have a script associated with its action. When it comes time to execute a probe’s action, DTrace runs your script code first and then returns any requested data back to Instruments. Because passing data back to Instruments involves copying data from the kernel space back to the Instruments app space, you should always pass data back to Instruments by configuring the appropriate entries in the “Record the following data” section of the instrument configuration dialog. Variables returned manually from your script code may not be returned correctly to Instruments.
从自定义脚本访问内核数据Access Kernel Data from Custom Scripts
因为DTrace脚本执行系统内核,他们可以访问内核符号。看看全球的核心变量和数据在你的DTrace脚本自定义仪器结构,在与反引号字符的变量名(`)。的反引号字符告诉DTrace寻找指定的变量的当前脚本之外。Because DTrace scripts execute inside the system kernel, they have access to kernel symbols. To look at a global kernel variable and data structure from your custom instrument in your DTrace scripts, precede the name of the variable with the backquote character (`
). The backquote character tells DTrace to look for the specified variable outside of the current script.
上市25-1说明动作脚本检索当前的负载信息从avenrun核心变量,使用变量来计算一分钟内的平均负载的系统。如果使用配置文件提供程序创建一个探针,您可以让此脚本定期收集负载数据,然后在仪器中绘制该信息。Listing 25-1 shows a sample action script that retrieves the current load information from the avenrun
kernel variable and uses that variable to calculate a one-minute average load of the system. If you create a probe using the Profile provider, you can have this script gather load data periodically and then graph that information in Instruments.
this->load1a = `avenrun[0]/1000;
this->load1b = ((`avenrun[0] % 1000) * 100) / 1000;
this->load1 = (100 * this->load1a) + this->load1b;
范围变量的合理Scope Variables Appropriately
DTrace脚本有一个基本上平的结构,由于缺乏流程控制语句和欲望保持探头的执行时间降到最低。就是说,你可以在DTrace脚本变量范围的不同取决于你的需要。表25-3列表范围级别变量和使用在每个级别的变量的语法。DTrace scripts have an essentially flat structure, due to a lack of flow control statements and the desire to keep probe execution time to a minimum. That said, you can scope the variables in DTrace scripts to different levels depending on your need. Table 25-3 lists the scoping levels for variables and the syntax for using variables at each level.
Scope |
Syntax example |
Description |
---|---|---|
Global |
|
Global variables are identified by the variable name. All probe actions on all system threads have access to variables in this space. |
Thread |
|
Thread-local variables are dereferenced from the |
Probe |
|
Probe-local variables are dereferenced using the |
找到脚本错误Find Script Errors
如果一个自定义工具脚本代码包含一个错误,仪器会显示一条错误信息在编译时跟踪窗格DTrace脚本。当您在跟踪文档中单击记录按钮,但在实际开始跟踪之前,仪器会报告错误。在错误消息气泡内部是一个编辑按钮。单击此按钮打开仪器配置对话框,该对话框现在标识带有错误的探针。If the script code for one of your custom instruments contains an error, Instruments displays an error message in the track pane when DTrace compiles the script. Instruments reports the error after you click the Record button in your trace document but before tracing actually begins. Inside the error message bubble is an Edit button. Clicking this button opens the instrument configuration dialog, which now identifies the probe with the error.
出口和进口DTrace脚本Export and Import DTrace Scripts
虽然仪器提供了收集跟踪数据接口方便,有时它是收集跟踪数据,直接使用DTrace更方便。如果你是系统管理员或是例如编写自动化测试脚本,,你可能喜欢DTrace命令行界面发射过程和数据收集。使用命令行工具需要你写你自己的DTrace脚本,可耗费的时间,可能会导致错误。如果你已经有了一个跟踪文件与一个或多个DTrace为基础的工具,你可以使用工具软件生成DTrace脚本提供相同的行为在你的跟踪文件的工具。Although Instruments provides a convenient interface for gathering trace data, sometimes it is more convenient to gather trace data directly using DTrace. If you are a system administrator or are writing automated test scripts, for example, you might prefer the DTrace command-line interface to launch a process and gather the data. Using the command-line tool requires you to write your own DTrace scripts, which can be time consuming and can lead to errors. If you already have a trace document with one or more DTrace-based instruments, you can use the Instruments app to generate a DTrace script that provides the same behavior as the instruments in your trace document.
仪器支持出口的DTrace脚本只对其中所有的仪器都是基于DTrace文件。这意味着,您的文档可以包含自定义工具和少数内置的工具,如在图书馆调色板中的文件系统相关的核心数据工具。Instruments supports exporting DTrace scripts only for documents in which all of the instruments are based on DTrace. This means that your document can include custom instruments and a handful of the built-in instruments, such as the file system-related and Core Data instruments in the Library palette.
-
选择跟踪文档。Select the trace document.
-
Choose File > DTrace Script Export.
-
Enter a name for the DTrace script.
-
Select a location for the DTrace script.
-
Click Save.
DTrace脚本导出命令地方脚本命令你的仪器在一个文本文件,然后你可以通过DTrace命令行工具使用-选择。例如,如果你出口脚本命名myinstrumentsscript。D、运行终端使用下面的命令:The DTrace Script Export command places the script commands for your instruments in a text file that you can then pass to the dtrace
command-line tool using the -s
option. For example, if you export a script named MyInstrumentsScript.d
, run it from Terminal using the following command:
sudo dtrace -s MyInstrumentsScript.d
NOTE
你必须有超级用户权限运行在大多数情况下,DTrace,这就是为什么sudo命令用于在前面的例子中运行DTrace。You must have superuser privileges to run dtrace
in most instances, which is why the sudo
command is used to run dtrace
in the preceding example.
从工具导出脚本(而不是手动编写脚本)的另一个好处是,在运行脚本之后,您可以将结果数据导入到工具中并在那里进行检查。出口从仪器脚本打印开始标记(与文本dtrace_output_begin)在DTrace输出开始。收集的数据,简单地复制所有的DTrace输出(包括开始标记)从终端并粘贴到一个文本文件,或者将输出重定向从DTrace工具直接到文件。在仪器导入数据,选择跟踪文件,你生成的原始剧本,并选择文件> DTrace数据导入。Another advantage of exporting your scripts from Instruments (as opposed to writing them manually) is that after running the script, you can import the resulting data back into Instruments and review it there. Scripts exported from Instruments print a start marker (with the text dtrace_output_begin
) at the beginning of the DTrace output. To gather the data, simply copy all of the DTrace output (including the start marker) from Terminal and paste it into a text file, or just redirect the output from the dtrace
tool directly to a file. To import the data in Instruments, select the trace document from which you generated the original script, and choose File > DTrace Data Import.