【tampermonkey 源码】【多空加码ea源码】【qq强制分享 源码 免费】源码安装systemtap

1.systemtap从入门到放弃(一)
2.SystemTap工具的使用基础
3.SystemTap GUI特点
4.在ESTABLISHED状态时,源码连接收到SYN会回复什么?
5.如何在 Oracle Linux 上使用 PHP DTrace

源码安装systemtap

systemtap从入门到放弃(一)

       内核调试利器:systemtap从入门到放弃(一)

       systemtap,安装一个用于简化Linux系统运行形态信息收集的源码开源工具,立足于性能诊断与bug调试。安装相较于繁琐的源码工具、耗时的安装tampermonkey 源码重新编译与引导过程,systemtap以动态hook内核代码的源码特性,提供了便捷的安装解决方案。其工作原理与底层kprobe接口紧密相连,源码通过在kprobe基础上引入脚本解析与内核模块编译运行单元,安装使开发人员得以在应用层实现对内核的源码hook,简化了开发流程。安装

       相比传统的源码kernel API与debugfs接口,systemtap提供了更加简洁的安装命令行接口与内核指令脚本语言,对于开发者而言,源码它成为了一款极其实用的工具,尤其在bug调试、性能分析与源码学习方面。

       入门systemtap,多空加码ea源码首先需了解其独特的脚本语法。脚本的编写,就是找到所需事件并设计事件处理流程的过程。系统中常用的语法元素包括脚本命名、注释、变量、数组、条件语句与循环等。其中,变量作用域默认为函数或括号内,全局变量则需在函数外显式声明。数组与关联数组则提供了数据存储与访问的灵活性。

       在systemtap中,通过探针(probe)来触发事件处理,支持对特定内核函数、模块函数进行探测。此外,systemtap还提供了一系列内置探针(tapset),qq强制分享 源码 免费开发者可直接调用,加速调试与分析工作。

       系统中常见的可探测事件包括函数调用、异常处理、系统调用等,这些事件为开发者提供了丰富的调试切入点。通过精心设计的脚本,开发者能够精准捕捉并分析系统行为,优化性能,定位并解决bug。

       systemtap的脚本语言简洁易懂,对于底层开发人员而言,学习曲线相对平缓。然而,掌握其脚本语法与内置探针的使用,对于深入应用systemtap,实现高效、精确的仿小刀网php源码调试至关重要。

       综上所述,systemtap凭借其独特的功能与简洁的语法,为Linux内核调试提供了一种高效、便捷的工具。从入门到掌握,开发者需深入理解其工作原理与脚本语言,灵活应用内置探针,以实现精准的系统调试与优化。

SystemTap工具的使用基础

        查看当前内核版本是哪一个,然后使用

        找到内核构建的详细信息,然后去对应发布网站上找kernel-debuginfo和kernel-debuginfo-common包。

        完成安装后可以通过下面命令测试systemtap

        进行测试,看看systemtap有无安装成功。

        下面命令演示查看__lookup_hash()函数返回时刻可以查看到的变量

        在上表中显示了lookup_hash在文件中的行号,显示了名为$return 的变量,其实这个return变量就是systemtap表示函数返回值的。而$name,$base,$flag我们对着linux源码看发现这是__lookup_hash的三个入参。

        下面命令可以查看__lookup_hash函数入口可以查看的变量

        也可以通过statement方式查看内核符号表里有的__lookup_hash相关的行

        如果查找的内核函数位于某个模块里可以使用下面命令:

        通过下面命令可以查看到某个正在运行的进程的函数

        上例中看到找到了syscall.Mount函数,并且把它的所有参数和参数类型都打印了出来。

        后面可以在stap脚本中,这个函数的上下文里直接使用这些参数,例如通过$source可以访问到参数source

        systemtap支持print()和printf()函数,其中printf使用语法和c语言一致。支持%s,%d,%x格式

        在systemtap里凡是以$开头的变量都是目标变量,如果目标变量结构体指针或者结构体对象,那么可以使用->直接访问其成员。例如上例中:

        常规情况下,printf()打印target变量时刻,只打印其值。如果需要将其成员(指针类型的target需要将其指向的对象的成员展开)可以在target变量后面加$的方式例如:

        一般情况下对struct的展开只会到成员值一级,如果相对成员内部继续展开可以在目标变量后面跟$$

        在systemtap中支持逻辑if语句格式为:

        逻辑语句支持以下比较

        ==,!=,>=,>,<,<=

        上述例子对ls -l下的xmalloc进行堆栈回溯:

        -d 可执行文件名

        --ldd 指明共享库

        -c “ls -l” 执行的子进程体

        下面例子将打印__lookup_hash中return返回dentry*里inode指向的i_ino子成员

        这一例子中-o zxy.txt的意思就是将结果写入文件zxy.txt中(默认输出到控制台)

        下面例子将在内核中使用强制类型转换

        这里解释一下,内核中方法强制转换

        在用systemtap跟踪内核时使用堆栈打印命令,常常打印不出来另外模块的函数,这是因为这些模块没有被加载。可以在systemtap启动命令使用--all-modules 方法强制将所有模块符号加载起来。

        下面例子对用golang写的dockerd进程syscall.Mount调用入口时刻打印syscall.Mount()函数的参数

        source的string字段内容

        下面例子打印golang写的dockerd进程xxx.Get函数返回时刻的参数情况

        }

        systemtap对golang支持不够完美,用户需要自己解析基本结构例如golang的string,array和slice这些都需要用户自己解析。string被systemtap识别为struct string,此结构systemtap可以识别的定义可以简化为:

        需要注意的是通过systemtap打印golang string的string->str会多打很多字符,因为string成员str并非按照c语言定义的字符串以\0表示字符串结束,我们只能结合string的字段len来获取精确的字符串内容

        slice完全不被systemtap识别,我们可以将systemtap可以识别的slice简化为此种定义:

        其中array就是指向slice存储单元的首地址。

        要是我们想获取helo=[]string{ “hello”,”world”}这样的字符串slice的内容可以通过systemtap提供的@cast(addr,”type”,”file”)函数将某个地址强转为file中定义的type结构。具体来说可以如下做获取hello的内容

SystemTap GUI特点

       SystemTap 是一种用于 Linux 内核诊断的创新工具。它让内核开发人员和系统管理员能够迅速、安全地从运行中的内核中获取信息。无需修改源码、编译内核或重启系统,只需编写或重用简单的脚本,就能收集内核实时数据。

       SystemTap 的一个显著特点是其直观的 GUI(图形用户界面)。GUI 提供了一种直观、易用的绑定域名 站群 源码界面,使用户能够轻松执行诊断任务。它简化了数据收集和分析流程,使得即使是经验不足的用户也能快速上手。

       另一个特点是可重用的脚本。SystemTap 允许用户创建可重用的脚本来执行特定的诊断任务。这些脚本可以保存并重复使用,从而节省时间并提高效率。此外,社区贡献了许多现成的脚本,用户可以从中选择适合特定需求的脚本。

       SystemTap 的另一个优点是其灵活的查询语言。该语言允许用户编写复杂的查询,从内核日志中提取所需信息。这使得 SystemTap 能够处理各种诊断需求,从简单的性能监控到复杂的问题定位。

       此外,SystemTap 的安全特性也是其一大亮点。它提供了隔离机制,确保脚本不会对系统造成潜在危害。这意味着用户可以安全地在生产环境中使用 SystemTap,而无需担心对系统稳定性的影响。

       总之,SystemTap 的 GUI 特点使其成为一种强大且易于使用的 Linux 内核诊断工具。通过直观的界面、可重用的脚本、灵活的查询语言和安全特性,SystemTap 为内核开发人员和系统管理员提供了一种高效、便捷的方式来收集和分析内核数据。这一工具的出现,无疑为 Linux 内核诊断领域带来了新的活力。

在ESTABLISHED状态时,连接收到SYN会回复什么?

       最初的问题,读者在阅读我关于《TCP RST 攻击与如何杀掉一条 TCP 连接》时提出,即处于 ESTABLISHED状态的连接为什么还需要响应 SYN 包?接下来,我们通过实验、内核源码分析与工具介绍,详细解答这一问题。

       实验复现

       在机器 A(IP:...)使用 nc 启动服务监听 端口。同时,机器 B 使用 nc 连接 A 的 nc 服务器,并输入 "hello"。通过 tcpdump 观察此次连接信息。随后,机器 B 使用 scapy 模拟发送 SYN 包,并查看 tcpdump 显示的包结果。实验发现,对于一个序列号为随意的 SYN 包,TCP 回复了正确的 ACK 包,确认号为 。RFC 文档也指出,Linux 内核收到乱序 SYN 报文时,会回复携带正确序列号和确认号的 ACK 包,即 Challenge ACK。

       原因分析

       发送 SYN 包的一端记为 A,接收 SYN 的 ESTABLISHED 状态端记为 B。B 对收到的 SYN 包回复 ACK 的目的是验证先前的连接是否失效,以便采取相应处理。若 A 的连接仍在,则正常处理 ACK 包。若连接已不在,此 SYN 包试图发起新连接,收到 ACK 后,A 会立即回复 RST 包,序列号等于 ACK 包的序列号,B 收到合法的 RST 包后释放连接。若 A 想重新与 B 创建连接,则可再次发送 SYN 包。

       内核源码分析

       使用 SystemTap 工具插入探针,观察内核函数 tcp_send_ack 的调用过程。在端口号为 时,打印函数调用堆栈。通过 SystemTap 脚本执行后,发现 ACK 包经过了 tcp_validate_incoming 和 tcp_send_challenge_ack 函数。RFC 提出了 ACK Throttling 方案,限制每秒最多发送 个 Challenge ACK 报文,通过 sysctl 函数可以调整此限制。

       RST 攻击

       RST 攻击通过伪造 RST 包关闭正常连接。攻击难点在于构造序列号落在对方滑动窗口内的包。实验中,启动 tcpkill 工具并发送 RST 包,观察服务端与客户端进程退出。tcpkill 通过 libpcap 库抓取符合条件的包,从而获取序列号,伪造 IP 发送 RST 包。此外,介绍 killcx 工具,用于处理僵死连接。

       工具介绍

       杀掉 TCP 连接的工具包括 tcpkill 和 killcx。tcpkill 假冒 IP 发送 RST 包,依赖有数据传输的连接才能获取序列号。killcx 是一个 perl 编写的脚本,可以在任何 TCP 连接状态下关闭连接。

       总结,本文通过实验、内核源码分析和工具介绍,详细解答了 ESTABLISHED 状态连接为何响应 SYN 包,以及如何使用 Challenge ACK、ACK Throttling、tcpkill 和 killcx 来处理相关连接问题。

如何在 Oracle Linux 上使用 PHP DTrace

       DTrace 是一个受欢迎的、“总是可用”的跟踪实用程序,用于识别开发和生产系统中的性能和行为问题。适用于 Oracle Linux 的标准“UEK3”内核包括了 DTrace 支持。通过跟踪 PHP 核心和 PHP OCI8 扩展中的用户探测器,我们可以有效地识别 PHP 脚本问题。DTrace 让您可以跟踪用户应用程序与操作系统之间的交互。

       åœ¨ Oracle Linux 上,DTrace 实用程序需要一个 Oracle Unbreakable Linux Network (ULN) 订阅。

       å®‰è£… Oracle Linux 和 Oracle Unbreakable Enterprise Kernel 版本 3

       é¦–先,通过 Oracle E-Delivery 安装 Oracle Linux 6.4。

       å®‰è£… Oracle Linux 6.4 之后,确保在 ULN 中启用了“Unbreakable Enterprise Kernel Release 3 for Oracle Linux 6 (x_) - Latest”频道。安装 UEK3 内核:

       # yum install kernel-uek

       åœ¨ ULN 中启用“Oracle Linux 6 Dtrace Userspace Tools (x_) - Latest”频道,安装 DTrace 实用程序:

       # yum install dtrace-utils

       é‡æ–°å¼•å¯¼åˆ°æ–°çš„ UEK3 3.8. 内核。

       å®‰è£… PHP

       éœ€è¦ä½¿ç”¨ --enable-dtrace 参数构建 PHP。您可以安装一些启用了 DTrace 的预先构建的评估版 RPM,请参见“使用 Oracle Linux“playground”预构建软件包的 DTrace PHP”。

       ä¹Ÿå¯ä»¥æŒ‰ç…§å¦‚下所述重新构建 PHP:

       ä»Ž php.net 下载 PHP 5.4. 或 PHP 5.5.4 或更高版本,然后进行解压缩:

       $ tar -xJf php-5.4..tar.bz2

       $ cd php-5.4.

       é…ç½® PHP:

       $ ./configure \

       --prefix=$HOME/p \

       --enable-dtrace \

       --disable-all --disable-cgi \

       --with-pear --enable-xml --enable-libxml --with-zlib

       è¿™å°†æž„建一个启用了 DTrace 的最小的命令行 PHP。所有不需要的扩展均被禁用。您可根据需要包含其他扩展。

       --prefix 选项表示安装到一个本地目录,方便您查看安装的文件。用完快照之后,清理该目录很容易。

       pear、xml 和 zlib 选项允许使用 pecl 命令。

       ç”Ÿæˆ PHP 二进制文件并进行安装:

       $ make

       $ make install

       å°† php.ini-development 复制到 $HOME/p/lib/php.ini,编辑该文件来设置时区,例如:

       date.timezone = America/Los_Angeles

       å®‰è£…适用于 Oracle Database 的 PHP OCI8

       è¯„估版 PHP RPM 包括可以连接到 Oracle Database 的 OCI8 扩展;请参见前面提到的博文。

       ä¸è¿‡ï¼Œå¦‚果您自己编译 PHP,需要手动将 PHP OCI8 作为一个“共享的”扩展添加:

       åœ¨ ULN 上启用“Oracle Software for Oracle Linux 6 (x_)”频道。

       ä»¥ root 用户身份安装 Oracle Instant Client:

       # yum install oracle-instantclient.1-basic oracle-instantclient.1-devel

       ä½œä¸ºæ™®é€šç”¨æˆ·ï¼Œè®¾ç½® PHP 的 PATH:

       $ export PATH=$HOME/p/bin:$PATH

       å¦‚果需要访问 :/

       è®¾ç½®ç”¨æ¥å¯ç”¨ DTrace 的环境变量 PHP_DTRACE,然后安装 PHP OCI8:

       $ PHP_DTRACE=yes pecl install oci8-2.0.2

       æœ¬æ–‡åŽé¢å°†è¦ç”¨åˆ°çš„ DTrace 探测器定义基于 PHP OCI8 2.0.2,因此需要安装明确的版本。如果您要安装更高的版本,请查看探测器及其参数,了解最新版本中的小改进。

       å½“提示 ORACLE_HOME 目录时,无需输入文本,直接按 Return。安装将自动检测 Oracle Instant Client RPM。配置将继续,输出将包含类似下面的内容:

       [ . . . ]

       checking for Oracle Database OCI8 support... yes, shared

       checking PHP version... 5.4., ok

       checking OCI8 DTrace support... yes

       [ . . . ]

       configure: WARNING: OCI8 extension: ORACLE_HOME is not set,

        looking for default Oracle Instant Client instead

       checking Oracle Instant Client directory...

        /usr/lib/oracle/.1/client/lib

       checking Oracle Instant Client SDK header directory...

        /usr/include/oracle/.1/client

       checking Oracle Instant Client library version compatibility... .1

       [ . . . ]

       å†æ¬¡ç¼–辑 php.ini,添加 PHP OCI8:

       extension=oci8.so

       ç¡®è®¤å®‰è£…:

       $ php --ri oci8

       oci8

       OCI8 Support => enabled

       OCI8 DTrace Support => enabled

       OCI8 Version => 2.0.2-dev

       Revision => $Id: bfb4befd9f5ce8abfea0cffef $

       Oracle Run-time Client Library Version => .1.0.1.0

       Oracle Compile-time Instant Client Version => .1

       Directive => Local Value => Master Value

       oci8.max_persistent => -1 => -1

       oci8.persistent_timeout => -1 => -1

       oci8.ping_interval => =>

       oci8.privileged_connect => Off => Off

       oci8.statement_cache_size => =>

       oci8.default_prefetch => =>

       oci8.old_oci_close_semantics => Off => Off

       oci8.connection_class => no value => no value

       oci8.events => Off => Off

       Statistics =>

       Active Persistent Connections => 0

       Active Connections => 0

       PHP OCI8 安装说明

       ä¸ºäº†æ”¯æŒ DTrace,需要从 PECL 安装 PHP OCI8 2.0,因为 PHP 5.4 和 PHP 5.5 包含的 PHP OCI8 1.4 没有 DTrace 探测器。将来,在 PHP 5.6 发布后,您就能够在构建 PHP 时配置支持 DTrace 的 PHP OCI8。

       å½“然,您可以通过 Oracle Instant Client zip 文件安装 PHP OCI8,也可以仅使用现有的 ORACLE_HOME 安装。

       æ‚¨å¯ä»¥åœ¨ä¸åŒ…含或未配置 DTrace 的 PHP 版本上安装启用 DTrace 的 PHP OCI8。这包括 PHP 早期版本。您将能够跟踪 PHP OCI8 探测器,但无法跟踪核心 PHP 探测器。类似地,您可以在启用 DTrace 的 PHP 上安装禁用 DTrace 的 PHP OCI8。

       å¦‚果您使用 phpize 和 configure(而不是 pecl)从 PECL 安装 PHP OCI8 2.0 ,则仍需设置 PHP_DTRACE=yes。这是因为 PECL 软件包有限的 configure 脚本将忽略 --enable-dtrace 选项。

       PHP OCI8 2.0 配置脚本适合“真正的”DTrace 使用,但 Linux SystemTap 不会跟踪扩展。

       æ³¨æ„ï¼ŒDTrace 优化后的二进制文件产生的输出可能与我们所见到的代码不尽相同。

       éªŒè¯ PHP DTrace 探测器

       ä»¥ root 用户身份启用 DTrace,允许普通用户记录跟踪信息:

       # modprobe fasttrap

       # chmod /dev/dtrace/helper

       æ‚¨å¯ä»¥ä½¿ç”¨ ACL 软件包规则限制特定用户对设备的访问,而非使用 chmod 命令。

       ä½œä¸ºæ™®é€šç”¨æˆ·è¿è¡Œ php,不带任何选项。PHP 将启动,然后等待输入:

       $ php

       ä»¥ root 用户身份列出可用的 DTrace 探测器。列出了 PHP 核心探测器和 PHP OCI8 探测器:

       # dtrace -l -m php -m oci8.so

        4 php php dtrace_compile_file compile-file-entry

        5 php php dtrace_compile_file compile-file-return

        6 php php zend_error error

        7 php php ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught

        8 php php zend_throw_exception_internal exception-thrown

        9 php php dtrace_execute_ex execute-entry

        php php dtrace_execute_internal execute-entry

        php php dtrace_execute_ex execute-return

        php php dtrace_execute_internal execute-return

        php php dtrace_execute_ex function-entry

        php php dtrace_execute_ex function-return

        php php php_request_shutdown request-shutdown

        php php php_request_startup request-startup

        php oci8.so php_oci_dtrace_check_connection oci8-check-connection

        php oci8.so php_oci_do_connect oci8-connect-entry

        php oci8.so php_oci_persistent_helper oci8-connect-expiry

        php oci8.so php_oci_do_connect_ex oci8-connect-lookup

        php oci8.so php_oci_pconnection_list_np_dtor oci8-connect-p-dtor-close

        php oci8.so php_oci_pconnection_list_np_dtor oci8-connect-p-dtor-release

        php oci8.so php_oci_do_connect oci8-connect-return

        php oci8.so php_oci_do_connect_ex oci8-connect-type

        php oci8.so php_oci_error oci8-error

        php oci8.so php_oci_statement_execute oci8-execute-mode

        php oci8.so php_oci_create_spool oci8-sesspool-create

        php oci8.so php_oci_create_session oci8-sesspool-stats

        php oci8.so php_oci_create_session oci8-sesspool-type

        php oci8.so php_oci_statement_create oci8-sqltext

       PHP 手册中详细记载了核心 PHP 探测器。PHP OCI8 探测器如下所述。

       åœ¨ç”¨æˆ·ç»ˆç«¯ï¼Œç”¨ Ctrl-C 停止 php 可执行文件。

       $ php

       ^C

       $

       PHP OCI8 2.0 DTrace 探测器概述

       é™æ€ PHP OCI8 2.0 探测器可分为“用户”探测器和“维护者”探测器。后者对于 PHP OCI8 维护者更有用,可在扩展开发期间验证功能。所有探测器均以参数形式返回数据。官方文档中详细介绍了 PHP OCI8 DTrace 探测器。

       åœ¨ OCI8 2.0.2 中,用户探测器包括:

       oci8-connect-entry — 由 oci_connect()、oci_pconnect() 和 oci_new_connect() 启动。在建立数据库连接之前触发。

       char *username — 连接用户名。

       char *dbname — 数据库连接字符串。

       char *charset — 指定的字符集。

       long session_mode — OCI_SYSDBA (0x2)、OCI_SYSOPER (0x4) 和 OCI_CRED_EXT (1<<) 的二进制“或”(或者过去我所使用平台上的 -)。默认情况下,设置为 0。

       int persistent — 如果调用了 oci_pconnect(),则设置为 1;否则设置为 0。

       int exclusive — 如果调用了 oci_new_connect(),则设置为 1;否则设置为 0。

       oci8-connect-return — 在连接的末尾触发。

       void *connection — 连接结构的地址。

       oci8-check-connection — 如果 Oracle 错误可能已经导致连接失效,则启动。

       void *connection — 连接结构的地址。

       int is_open — 如果 errcode 或 server_status 指示连接无效且必须重新创建,则为 0。

       long errcode — Oracle 错误编号。

       unsigned long server_status — 为 Oracle 库的一个指示器,指示连接是否无效。如果因为 errcode 指示连接无效导致 is_open 为 0,则 server_status 为其默认值 1。

       oci8-sqltext — 执行 oci_parse() 时启动。

       void *connection — 连接结构的地址。

       char *sql — 所执行的 SQL 语句的文本。

       oci8-error — 如果发生 Oracle 错误,则启动。

       int status — Oracle 返回失败的 Oracle 库调用的状态,如 -1 代表 Oracle 的 OCI_ERROR,1 代表 Oracle 的 OCI_SUCCESS_WITH_INFO。请参见 Oracle 的 oci.h,了解所有定义。

       long errcode — Oracle 错误编号。

       oci8-execute-mode — 指示 oci_execute() 调用的提交状态。

       void *connection — 连接结构的地址。

       unsigned int mode — 传递给 Oracle 库的模式,如 OCI_NO_AUTO_COMMIT (0x)、OCI_DESCRIBE_ONLY (0x) 或 OCI_COMMIT_ON_SUCCESS (0x)。

       æ³¨ï¼šæœ€æ–°çš„ OCI8 2.0.6 中包含 oci8-connection-close 探测器,有几个探测器现在也具有 client_id 参数和指向语句结构的指针。

       ç»´æŠ¤è€…探测器如下所示。参数描述请参考 PHP OCI8 源代码。

       oci8-connect-p-dtor-close

       void *connection

       oci8-connect-p-dtor-release

       void *connection

       oci8-connect-lookup

       void *connection

       int is_stub

       oci8-connect-expiry

       void *connection

       int is_stub

       long idle_expiry

       long timestamp

       oci8-connect-type

       int persistent

       int exclusive

       void *connection

       long num_persistent

       long num_connections

       oci8-sesspool-create

       void *session_pool

       oci8-sesspool-stats

       unsigned long free

       unsigned long busy

       unsigned long open

       oci8-sesspool-type

       int type

       void *session_pool

       PHP OCI8 2.0 中的探测器代替了 PHP OCI8 1.4 中使用的 oci_internal_debug() 跟踪。该函数已变成一条空指令,不执行任何操作。

       ä½¿ç”¨ PHP OCI8 和 DTrace

       æ‰§è¡Œä»¥ä¸‹æ­¥éª¤ã€‚

       åˆ›å»ºä¸€ä¸ªç®€å•çš„ PHP 文件 oci8.php 来查询数据库:

        <?php

        error_reporting(0);

        ini_set('display_errors', 'Off');

        function do_query($c, $sql)

        {

        $s = oci_parse($c, $sql);

        if (!$s)

        return;

        $r = oci_execute($s);

        if (!$r)

        return;

        while (($row = oci_fetch_row($s)) != false) {

        foreach ($row as $item) {

        echo $item . " ";

        }

        echo "\n";

        }

        }

        $c = oci_new_connect('hr', 'welcome', 'localhost/pdborcl');

        do_query($c, "select city from locations where rownum < 5 order by 1");

        do_query($c, "select something from does_not_exist");

        ?>

       åˆ›å»ºä¸€ä¸ª D 脚本 user_oci8.d 来探测 oci8.php 的执行:

        #!/usr/sbin/dtrace -Zs

        # This script is for OCI8 2.0.2

        php*:::oci8-connect-entry

        {

        printf("PHP connect-entry\n");

        printf("\t username %s\n", arg0 ? copyinstr(arg0) : "");

        printf("\t dbname %s\n", arg1 ? copyinstr(arg1) : "");

        printf("\t charset %s\n", arg2 ? copyinstr(arg2) : "");

        printf("\t session_mode %ld\n", (long)arg3);

        printf("\t persistent %d\n", (int)arg4);

        printf("\t exclusive %d\n", (int)arg5);

        }

        php*:::oci8-connect-return

        {

        printf("PHP oci8-connect-return\n");

        printf("\t connection 0x%p\n", (void *)arg0);

        }

        php*:::oci8-connection-close

        {

        printf("PHP oci8-connect-close\n");

        printf("\t connection 0x%p\n", (void *)arg0);

        }

        php*:::oci8-error

        {

        printf("PHP oci8-error\n");

        printf("\t status %d\n", (int)arg0);

        printf("\t errcode %ld\n", (long)arg1);

        }

        php*:::oci8-check-connection

        {

        printf("PHP oci8-check-connection\n");

        printf("\t connection 0x%p\n", (void *)arg0);

        printf("\t is_open %d\n", arg1);

        printf("\t errcode %ld\n", (long)arg2);

        printf("\t server_status %lu\n", (unsigned long)arg3);

        }

        php*:::oci8-sqltext

        {

        printf("PHP oci8-sqltext\n");

        printf("\t connection 0x%p\n", (void *)arg0);

        printf("\t sql %s\n", arg0 ? copyinstr(arg1) : "");

        }

        php*:::oci8-execute-mode

        {

        printf("PHP oci8-execute-mode\n");

        printf("\t connection 0x%p\n", (void *)arg0);

        printf("\t mode 0x%x\n", arg1);

        }

       ä½¿ç”¨ OCI8 2.0.6,一些参数的数值需要调整,才能满足现在一些新增参数的需要。

       ä»¥ root 用户身份启动 D 脚本。该脚本将暂停,等待探测器触发:

        # chmod +x user_oci8.d

        # ./user_oci8.d

       ï¼ˆç¨åŽï¼Œä½“验完 PHP 之后,可以使用 Ctrl-C 关闭此终端。)

       åœ¨å¦ä¸€ä¸ªçª—口中运行命令行 PHP。显示成功查询的输入:

        $ php oci8.php

        Beijing

        Bern

        Bombay

        Geneva

       åœ¨è¿è¡Œ D 脚本的 root 终端,将显示 PHP 执行期间触发的探测器:

        # ./user_oci8.d

        dtrace: script 'user_oci8.d' matched 0 probes

        CPU ID FUNCTION:NAME

        1 php_oci_do_connect:oci8-connect-entry PHP connect-entry

        username hr

        dbname localhost/pdborcl

        charset

        session_mode 0

        persistent 0

        exclusive 0

        0 php_oci_do_connect:oci8-connect-return PHP oci8-connect-return

        connection 0x7fecff0

        0 php_oci_statement_create:oci8-sqltext PHP oci8-sqltext

        connection 0x7fecff0

        sql select city from locations where rownum < 5 order by 1

        0 php_oci_statement_execute:oci8-execute-mode PHP oci8-execute-mode

        connection 0x7fecff0

        mode 0x

        0 php_oci_statement_create:oci8-sqltext PHP oci8-sqltext

        connection 0x7fecff0

        sql select something from does_not_exist

        0 php_oci_statement_execute:oci8-execute-mode PHP oci8-execute-mode

        connection 0x7fecff0

        mode 0x

        0 php_oci_error:oci8-error PHP oci8-error

        status -1

        errcode

        0 php_oci_dtrace_check_connection:oci8-check-connection PHP oci8-check-connection

        connection 0x7fecff0

        is_open 1

        errcode

        server_status 1

        0 php_oci_connection_close:oci8-connection-close PHP oci8-connect-close

        connection 0x7fecff0

       ï¼ˆå°† -q 添加到 user_oci8.d 的 /usr/sbin/dtrace 参数将隐藏 CPU 和 ID 详细信息。)

       åœ¨å¤š CPU 计算机上,探测器可能不会顺序出现,具体取决于哪个 CPU 正在处理探测器。显示探测器时间戳将有助于消除混淆,例如:

        php*:::oci8-connect-entry

        {

        printf("PHP connect-entry at %lld\n", walltimestamp);

        }

       ä»Ž user_oci8.d DTrace 输出中,您可以看到以下内容:

       å‘起的连接 (oci8-connect-entry)。连接到 localhost/pdborcl 数据库的用户 hr。因为 exclusive 和 persistent 均为 0,所以是一个 oci_connect() 调用。未请求任何显式的字符集。请求的是默认的会话模式(oci_connect 的第五个可选参数)。

       å¯¹ä¸¤æ¡ SQL 语句进行分析 (oci8-sqltext),并以 0x(即 OCI_COMMIT_ON_SUCCESS)模式执行 (oci-execute-mode)。

       ç”Ÿæˆäº† (oci8-error) 一条 Oracle 错误 — ORA-(表或视图不存在)。

       è¯¥é”™è¯¯å¯¼è‡´è¦éªŒè¯è¿žæŽ¥çŠ¶æ€ (oci8-check-connection)。is_open 的值为 1,表示连接正常。

       é€šè¿‡è¿™äº›ä¿¡æ¯ï¼Œæ‚¨å¯ä»¥è·Ÿè¸ªæœ‰é—®é¢˜çš„语句执行和连接问题。

       æ€»ç»“

       DTrace 是一个非常强大的实用程序,本文只是有关其用法的只言片语。通过上述示例,可将 PHP OCI8 跟踪与核心 PHP 跟踪相集成。您可以设置 PHP 函数调用的时间,计算调用的次数。您可以深入了解 PHP 进行的操作系统调用。Bryan Cantrill 在 DTrace 和 PHP(演示)中发布了一些核心 PHP 跟踪的示例。(注意,博客平台升级导致其博文中的一个反斜杠显示为两个反斜杠。而且,您不再需要单独的 PHP DTrace 扩展。)Brendan Gregg 的 DTrace Toolkit 包含许多有用的 DTrace 脚本。还有各种不同的博客。

       è®°ä½ï¼ŒDTrace 的目的是始终启用其功能,适合开发和生产(此过程最需要 DTrace)。DTrace 的设计意味着探测器不受监视时零开销。

更多内容请点击【休闲】专栏

精彩资讯