PHP ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΡΠ΅ΡΡΡ ΡΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ Π·ΠΎΠ½Π΄Π°ΠΌΠΈ DTrace Π½Π° ΠΏΠ»Π°ΡΡΠΎΡΠΌΠ°Ρ , ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΡΡ ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΡ DTrace.
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ΡΡ ΠΊ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ, ΡΡΠΎΠ±Ρ Π²ΠΊΠ»ΡΡΠΈΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ DTrace Π² ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Oracle Linux ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΡΠ΄ΡΠΎ UEK3 ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
ΠΠΌΠ΅ΡΡΠΎ chmod Π΄ΠΎΡΡΡΠΏΠ΅Π½
ΠΏΠ°ΠΊΠ΅Ρ ΠΏΡΠ°Π²ΠΈΠ» ACL Π΄Π»Ρ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Π΄ΠΎΡΡΡΠΏΠ° Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ
ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ.
Π‘Π±ΠΎΡΠΊΠ° PHP Ρ ΠΊΠ»ΡΡΠΎΠΌ --enable-dtrace:
# ./configure --enable-dtrace ...
# make
# make install
Π‘Π±ΠΎΡΠΊΠ° PHP Ρ ΠΊΠ»ΡΡΠΎΠΌ --enable-dtrace ΡΠ΄Π΅Π»Π°Π΅Ρ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π·ΠΎΠ½Π΄Ρ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ Π² ΡΠ΄ΡΠ΅ PHP.
ΠΠ°ΠΆΠ΄ΡΠΉ PHP-ΠΌΠΎΠ΄ΡΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ²ΠΎΠΈ Π·ΠΎΠ½Π΄Ρ,
ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΎΠ±ΡΠ°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ ΠΊΠ°ΠΊ ΡΠ°Π·Π΄Π΅Π»ΡΠ΅ΠΌΡΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ.
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΡΠ΅Π΄Ρ USE_ZEND_DTRACE=1 Π΄Π»Ρ ΡΠ΅Π»Π΅Π²ΡΡ PHP-ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ², ΡΡΠΎΠ±Ρ Π²ΠΊΠ»ΡΡΠΈΡΡ Π·ΠΎΠ½Π΄Ρ.
| ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ Π·ΠΎΠ½Π΄Π° | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π·ΠΎΠ½Π΄Π° | ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ Π·ΠΎΠ½Π΄Π° |
|---|---|---|
request-startup |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΡΠΈ Π½Π°ΡΠ°Π»Π΅ Π·Π°ΠΏΡΠΎΡΠ°. | char *file, char *request_uri, char *request_method |
request-shutdown |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΡΠΈ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΠΈ Π·Π°ΠΏΡΠΎΡΠ°. | char *file, char *request_uri, char *request_method |
compile-file-entry |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ ΡΠΊΡΠΈΠΏΡΠ°. | char *compile_file, char *compile_file_translated |
compile-file-return |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Π΅ΡΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ ΡΠΊΡΠΈΠΏΡΠ°. | char *compile_file, char *compile_file_translated |
execute-entry |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ ΠΌΠ°ΡΡΠΈΠ² Π±Π°ΠΉΡ-ΠΊΠΎΠ΄Π°. Π ΠΏΡΠΈΠΌΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Π²ΡΠ·ΡΠ²Π°ΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ, Π²ΠΎΠ·ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°Π±ΠΎΡΠ° Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡΠ° ΠΈΠ»ΠΈ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ include. | char *request_file, int lineno |
execute-return |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΏΠΎΡΠ»Π΅ ΠΎΡΡΠ°Π±ΠΎΡΠΊΠΈ ΠΌΠ°ΡΡΠΈΠ²Π° Π±Π°ΠΉΡ-ΠΊΠΎΠ΄Π°. | char *request_file, int lineno |
function-entry |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π΄Π²ΠΈΠΆΠΎΠΊ PHP Π½Π°ΡΠΈΠ½Π°Π΅Ρ Π·Π°ΠΏΡΡΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
function-return |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π΄Π²ΠΈΠΆΠΎΠΊ PHP Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
exception-thrown |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° Π²ΡΠ±ΡΠΎΡΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅. | char *classname |
exception-caught |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠΉΠΌΠ°Π½ΠΎ. | char *classname |
error |
Π‘ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ, Π΅ΡΠ»ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ°, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΡΡΠΎΠ²Π½Ρ error_reporting. | char *errormsg, char *request_file, int lineno |
ΠΠΎΠ΄ΡΠ»ΠΈ PHP ΠΌΠΎΠ³ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π·ΠΎΠ½Π΄Ρ.
ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ PHP-ΠΏΡΠΎΡΠ΅ΡΡ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΠ΅ ΡΠ»Π΅Π΄ΡΡΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ Π·ΠΎΠ½Π΄ΠΎΠ²:
# dtrace -l
ΠΠΎΠΌΠ°Π½Π΄Π° Π²ΡΠ²Π΅Π΄Π΅Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
ID PROVIDER MODULE FUNCTION NAME
[ . . . ]
4 php15271 php dtrace_compile_file compile-file-entry
5 php15271 php dtrace_compile_file compile-file-return
6 php15271 php zend_error error
7 php15271 php ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
8 php15271 php zend_throw_exception_internal exception-thrown
9 php15271 php dtrace_execute_ex execute-entry
10 php15271 php dtrace_execute_internal execute-entry
11 php15271 php dtrace_execute_ex execute-return
12 php15271 php dtrace_execute_internal execute-return
13 php15271 php dtrace_execute_ex function-entry
14 php15271 php dtrace_execute_ex function-return
15 php15271 php php_request_shutdown request-shutdown
16 php15271 php php_request_startup request-startup
ΠΠΎΠ»ΠΎΠ½ΠΊΠ° Provider ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°Π΄ΠΏΠΈΡΡ php
ΠΈ PID-ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ Π·Π°ΠΏΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ PHP-ΠΏΡΠΎΡΠ΅ΡΡΠ°.
ΠΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅ΡΠ° Apache Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠΎΠ΄ΡΠ»Ρ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡΡ ΠΊΠ°ΠΊ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, libphp5.so, ΠΈ Π²ΡΠ²ΠΎΠ΄ΡΡΡΡ ΡΠ΅ΡΠΈΡ Π±Π»ΠΎΠΊΠΎΠ² ΡΠΏΠΈΡΠΊΠ°, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Apache.
ΠΠΎΠ»ΠΎΠ½ΠΊΠ° Function ΡΡΡΠ»Π°Π΅ΡΡΡ Π½Π° Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΉ Π‘-ΡΡΠ½ΠΊΡΠΈΠΈ PHP, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π·ΠΎΠ½Π΄.
Π‘ΠΏΠΈΡΠΎΠΊ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ Π·ΠΎΠ½Π΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ²ΡΠ·Π°Π½Ρ Ρ PHP, Π΅ΡΠ»ΠΈ PHP Π½Π΅ Π·Π°ΠΏΡΡΡΠΈΠ»ΠΈ.
ΠΡΠΈΠΌΠ΅Ρ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π±Π°Π·ΠΎΠ²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠΊΡΠΈΠΏΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠ·ΡΠΊΠ° DTrace D.
ΠΡΠΈΠΌΠ΅Ρ #1 Π‘ΠΊΡΠΈΠΏΡ all_probes.d β ΡΡΠ°ΡΡΠΈΡΠΎΠ²ΠΊΠ° ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ PHP-Π·ΠΎΠ½Π΄ΠΎΠ² ΡΠ΅ΡΠ΅Π· DTrace
#!/usr/sbin/dtrace -Zs
#pragma D option quiet
php*:::compile-file-entry
{
printf("PHP compile-file-entry\n");
printf(" compile_file %s\n", copyinstr(arg0));
printf(" compile_file_translated %s\n", copyinstr(arg1));
}
php*:::compile-file-return
{
printf("PHP compile-file-return\n");
printf(" compile_file %s\n", copyinstr(arg0));
printf(" compile_file_translated %s\n", copyinstr(arg1));
}
php*:::error
{
printf("PHP error\n");
printf(" errormsg %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
}
php*:::exception-caught
{
printf("PHP exception-caught\n");
printf(" classname %s\n", copyinstr(arg0));
}
php*:::exception-thrown
{
printf("PHP exception-thrown\n");
printf(" classname %s\n", copyinstr(arg0));
}
php*:::execute-entry
{
printf("PHP execute-entry\n");
printf(" request_file %s\n", copyinstr(arg0));
printf(" lineno %d\n", (int)arg1);
}
php*:::execute-return
{
printf("PHP execute-return\n");
printf(" request_file %s\n", copyinstr(arg0));
printf(" lineno %d\n", (int)arg1);
}
php*:::function-entry
{
printf("PHP function-entry\n");
printf(" function_name %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
printf(" classname %s\n", copyinstr(arg3));
printf(" scope %s\n", copyinstr(arg4));
}
php*:::function-return
{
printf("PHP function-return\n");
printf(" function_name %s\n", copyinstr(arg0));
printf(" request_file %s\n", copyinstr(arg1));
printf(" lineno %d\n", (int)arg2);
printf(" classname %s\n", copyinstr(arg3));
printf(" scope %s\n", copyinstr(arg4));
}
php*:::request-shutdown
{
printf("PHP request-shutdown\n");
printf(" file %s\n", copyinstr(arg0));
printf(" request_uri %s\n", copyinstr(arg1));
printf(" request_method %s\n", copyinstr(arg2));
}
php*:::request-startup
{
printf("PHP request-startup\n");
printf(" file %s\n", copyinstr(arg0));
printf(" request_uri %s\n", copyinstr(arg1));
printf(" request_method %s\n", copyinstr(arg2));
}
ΠΠ»Ρ ΠΊΠΎΠΌΠ°Π½Π΄Ρ dtrace
ΡΠΊΡΠΈΠΏΡ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΎΠΏΡΠΈΡ -Z
ΠΈ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΡΠ°Π±ΠΎΡΡ, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ PHP-ΠΏΡΠΎΡΠ΅ΡΡ Π½Π΅ Π·Π°ΠΏΡΡΠ΅Π½.
ΠΠ΅Π· ΠΎΠΏΡΠΈΠΈ ΡΠΊΡΠΈΠΏΡ ΡΡΠ°Π·Ρ ΠΆΠ΅ Π·Π°Π²Π΅ΡΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅,
ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π½Π΅ ΡΠ²ΠΈΠ΄ΠΈΡ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π·ΠΎΠ½Π΄Π° Π΄Π»Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ.
Π‘ΠΊΡΠΈΠΏΡ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅Ρ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ PHP-Π·ΠΎΠ½Π΄ Π½Π° Π²ΡΡΠΌ ΠΏΡΠΎΡΡΠΆΠ΅Π½ΠΈΠΈ ΡΠ°Π±ΠΎΡΡ PHP-ΡΠΊΡΠΈΠΏΡΠ°. ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ D-ΡΠΊΡΠΈΠΏΡ:
# ./all_probes.d
ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ ΡΠΊΡΠΈΠΏΡ ΠΈΠ»ΠΈ PHP-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. ΠΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡΠΈΠΉ D-ΡΠΊΡΠΈΠΏΡ Π±ΡΠ΄Π΅Ρ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΡΠ°Π±ΠΎΡΠ°Π²ΡΠ΅Π³ΠΎ Π·ΠΎΠ½Π΄Π°.
ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ ΡΠ°Π±ΠΎΡΡ ΡΠΊΡΠΈΠΏΡΠ° ΠΏΡΠ΅ΡΡΠ²Π°ΡΡ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΠ΅ΠΉ CTRL+C.
ΠΠ° ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΡΡ ΠΌΠ°ΡΠΈΠ½Π°Ρ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π·ΠΎΠ½Π΄ΠΎΠ² Π½Π΅ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π΅Π½ ΠΈ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠΎΠ², Π½Π° ΠΊΠΎΡΠΎΡΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π·ΠΎΠ½Π΄Ρ ΠΈ ΠΊΠ°ΠΊ ΠΌΠΈΠ³ΡΠΈΡΡΡΡ ΠΏΠΎΡΠΎΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°ΠΌΠΈ. ΠΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΌΠ΅ΡΠΎΠΊ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΠΈΠ·Π±Π΅Π³Π°ΡΡ ΠΊΠΎΠ½ΡΡΠ·ΠΎΠ². Π ΠΏΡΠΈΠΌΠ΅ΡΡ:
php*:::function-entry
{
printf("%lld: PHP function-entry ", walltimestamp);
[ . . .]
}