Sponsored LinksКатегорииLinksUnix Tutorial
Personal Development Ruslan Valiev Solaris Performance Team Damien Farnham Fintan Ryan Nicky Veitch Niall Mullen Sean McGrath DTrace Bryan Cantrill Brendan Gregg ZFS Tim Foster General Ben Rockwood Learning Solaris 10 Privacy policy |
Friday, 10 December. 2004Предикаты в DTrace
В DTrace нет условных операторных скобок типа if..then..else, вместо них используются предикаты.
Предикат - это заключённые в слэши (/) условия, приводимые сразу после строки объявления той или иной пробы, и предназначенные для контроля за необходимостью выполнения кода, относящегося к этой пробе. Скажем, следующий скрипт выведет список всех системных вызовов, кроме write, для всех процессов, запущенных на системе. Так как DTrace отслеживает события на уровне thread'ов, в примере запуска этого скрипта видно, что некоторые иднентификаторы процессов повторяются. Это потому что пробы сработали для различных thread'ов одного и того же процесса: CODE: #!/usr/sbin/dtrace -s #pragma D option quiet syscall::: /probefunc != "write"/ { printf("probefunc: %s, pid: %d, execname: %s\n", probefunc, pid, execname); } После запуска скрипта вы увидите примерно следующее: CODE: probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace ... Т.е. скрипт учёл и системные вызовы, выполненные командой dtrace, которая выполняла скрипт. Для того, чтобы исключить эту команду из нашей статистики, следует изменить предикат: CODE: /probefunc != "write" && execname != "dtrace"/ и тогда вывод команды будет включать уже все другие процессы, кроме dtrace, в моём примере это парочка моих терминалов rxvt и java: CODE: probefunc: pollsys, pid: 28411, execname: rxvt probefunc: ioctl, pid: 28411, execname: rxvt probefunc: ioctl, pid: 28411, execname: rxvt probefunc: pollsys, pid: 28411, execname: rxvt probefunc: pollsys, pid: 28406, execname: rxvt probefunc: ioctl, pid: 28406, execname: rxvt probefunc: ioctl, pid: 28406, execname: rxvt probefunc: pollsys, pid: 28406, execname: rxvt probefunc: lwp_cond_wait, pid: 27870, execname: java_vm probefunc: lwp_cond_signal, pid: 27870, execname: java_vm probefunc: lwp_cond_signal, pid: 27870, execname: java_vm probefunc: lwp_cond_wait, pid: 27870, execname: java_vm ... В выражениях предикатов могут использоваться любые константы и переменные, ранее использовавшиеся в коде, или стандартные переменные, как в приведённых примерах. А если учесть, что локальные переменные уникальны для каждого thread'а процесса, то можно строить и конструкции посложнее... Локальные для каждого thread'а переменные объявляются с помощью оператора -> специального идентификатора self, например: self->flag = 1;. Приведённые ниже пример выведет лишь по одному сообщению про системный вызов write каждого из thread'ов всех процессов, выполняющих этот вызов. Как видно из кода, едва мы сообщаем об очередном thread'е, который мы уличили в завершении системного вызова write, мы тут же отмечаем в локальной для этого thread'а переменной, что он уже был обработан: self->processed = 1;. А предикат уже позаботится о том, чтобы в следующий раз для уже отмеченного thread'а мы не выполняли код нашей пробы: CODE: #!/usr/sbin/dtrace -s #pragma D option quiet syscall::write:return / self->processed == 0/ { printf("tid: %d, pid: %d, execname: %s\n", tid, pid, execname); self->processed = 1; } Как видно, каждый thread был зарегистрирован только один раз: CODE: tid: 1, pid: 21583, execname: soffice.bin tid: 4, pid: 21750, execname: thunderbird-bin tid: 4, pid: 27406, execname: mozilla-bin tid: 1, pid: 27406, execname: mozilla-bin tid: 1, pid: 21450, execname: icewm tid: 4, pid: 21583, execname: soffice.bin tid: 1, pid: 21750, execname: thunderbird-bin tid: 1, pid: 28636, execname: dtrace Всех способов использования предикатов не расскажешь в одной записи, так что в следующий раз я постараюсь показать ещё несколько вариантов использования этой замечательной возможности DTrace. Defined tags for this entry: dtrace Обратные ссылки
URI этой записи для создания обратных ссылок (trackback)
Нет обратных ссылок
|




