Европейский Университет в Санкт-Петербурге
Опубликован: 04.07.2008 | Доступ: свободный | Студентов: 896 / 162 | Оценка: 4.30 / 3.78 | Длительность: 18:28:00
Лекция 16:

Практическое применение DTrace

< Лекция 15 || Лекция 16: 123

Однажды у нас был случай, когда скрипт на php непостижимым образом выдавал лишнюю пустую строку в генерируемой странице. А страница импортировалась в поток RSS у разных хороших людей. То есть должна была, но не импортировалась, потому что лишняя пустая строка все портила. Тогда дело решилось внимательным изучением всех включаемых файлов .php и обнаружением лишней строки. Однако бывают и более сложные случаи, когда при отладке web-приложений хочется понять, как на самом деле это приложение работает. Сейчас очень многие веб-сайты, даже довольно простые, строятся на основе системы управления контентом (CMS, content management system). И еще многие другие – просто на связке php-скриптбаза данных. С другой стороны, а именно со стороны клиента, заполнение разнообразных форм на веб-странице обычно связано с кодом на javascript, так как это – стандартный способ проверять допустимость значений в полях формы.

Можем ли мы в отладке веб-приложений применить DTrace для того, чтобы отследить все передаваемые от веб-обозревателя к базе данных (и обратно) параметры на всем пути их следования через скриптыобработчики? Если мы используем Solaris – то да. И более того, легко.

Вспомним, что технология DTrace в настоящее время воплощена в Solaris (начиная с Solaris 10) и портирована в Mac OS X Leopard, FreeBSD 6.2 (частично) и QNX Neutrino (QNX6). В данной статье мы рассматриваем ее применение в Solaris и помним, что приложения третьих компаний (например, Firefox) в виде готового пакета для других систем с поддержкой DTrace могут быть еще недоступны для скачивания. Однако если вы хотите инструментировать любое приложение с открытым кодом, используя DTrace, никто не вправе помешать вам. Описание того, как это сделать с помощью провайдера sdt (statically defined tracing), можно найти на странице http://www.solarisinternals.com/wiki/index.php/DTrace_Topics_USDT.

Приводимые в статье примеры основаны на наборе DTrace Toolkit, который состоит из 386 скриптов (количество верно для версии DTrace Toolkit 0.99) на языке D и содержит скрипты почти на все случаи жизни, начиная с простых примеров и продолжая трассировкой java-приложений, о которой можно написать отдельную статью. Скачать DTrace Toolkit можно по адресу http://www.opensolaris.org/os/community/dtrace/dtracetoolkit/

Каждый датчик, по срабатыванию которого мы можем выполнять требуемые нам действия в D-скрипте, относится к определенному провайдеру. Системным провайдерам (типа syscall, io и пр.) соответствует одноименный модель ядра, а за провайдеры, созданные сторонними разработчиками, отвечает модуль ядра sdt. Это вам, скорее всего, уже известно из предыдущей статьи про DTrace в декабрьском номере "Системного администратора" (а может быть, вы это узнали еще раньше?) Теперь мы изучим возможности, которые нам предоставляет провайдер javascript, а в следующем разделе разберемся с провайдерами php и postgresql.

Провайдер javascript

В свежих сборках Firefox (забирать по адресу http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/contrib/latest-trunk/) в код вставлены датчики DTrace. Из D-скриптов к ним надо обращаться через провайдер javascript. Для экспериментов мы выбрали firefox-3.0a9pre.en-US.solaris11-i386.tar.bz2. Кстати, имейте в виду, что более старые версии firefox могли включать этот же провайдер под другим именем – mozilla.

Что именно позволяет посмотреть провайдер javascript?

# dtrace -l -n 'javascript*:::'|more
ID PROVIDER MODULE FUNCTION NAME
72803 javascript2258 libmozjs.so jsdtrace_execute_done execute-done
72804 javascript2258 libmozjs.so js_Execute execute-done
72805 javascript2258 libmozjs.so jsdtrace_execute_start execute-start
72806 javascript2258 libmozjs.so js_Execute execute-start
...
(вывод команды сокращен)

Как видно из вывода dtrace, имя провайдера появляется сопряженным с идентификатором процесса firefox-bin, а датчики вводятся для ряда основных функций. Также есть датчики function-entry, funtion-info, function-return, function-rval, object-create, object-create-start, object-createdone и object-create-finalize. Набор датчиков в будущем может быть расширен, но в той версии mozilla, которая оказалась в нашем распоряжении, других датчиков не было.

Какой толк можно получить из срабатывания этих датчиков? Во-первых, можно традиционно трассировать выполнение функции, написанной на javascript, и мерять время выполнения разных ее компонент. Во-вторых, уже сейчас доступна экспериментальная функциональность провайдера javascript по трассировке функций с выводом их аргументов.

Детальную информацию об аргументах датчиков, предназначенных для этого, можно почерпнуть на странице http://news.speeple.com/blogs.sun. com/2007/10/23/dtrace-mozilla-rfe-javascript-tracing-framework-landed.htm:

javascript*::: function-args
Args: (char *filename, char *classname, char *funcname, int argc,
void *argv, void *argv0,void *argv1, void *argv2, void *argv3,
void *argv4)
javascript* :::function-rval
Args: (char *filename, char *classname, char *funcname, int lineno,
void *rval, void *rval0)

Датчик function-args служит для показа аргументов вызванной javascript-функции в скрипте, а function-rval – для показа возвращаемого функцией значения.

Кстати, если под рукой нет документации, то некоторое представление о том, какие аргументы есть у датчика, и следовательно, какие параметры arg0..argN вам требуется выводить командой printf в скрипте, можно получить, используя ключи -l -v команды dtrace (только давать их надо перед ключом -n, если вы его применяете, это важно!)

dtrace -l -v -n 'javascript*:::function-args'
72808 javascript2258 libmozjs.so js_Interpret function-args
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Types
args[0]: char *
args[1]: char *
args[2]: char *
args[3]: int
args[4]: void *
args[5]: void *
args[6]: void *
args[7]: void *
args[8]: void *
args[9]: void *

Как видно, датчик function-args может иметь до 9 аргументов, смысл которых пояснен выше, а при определенном воображении о значении аргументов можно догадаться по их типу. Так или иначе, команду dtrace -l -v стоит иметь в виду.

Попробуем выяснить с помощью датчика function-args, какое значение из формы в файле .html передается в написанную нами функцию на javascript. Наш экспериментальный файл и код javascript представляют собой проcтую форму для ввода единственного поля – даты и проверку на формат даты соответственно:

<html>
<head>
<title>Input form</title>
<script language="JavaScript" type="text/javascript">
function testDate(date) {
alert(date);
return(true);
}
function testBox1(form) {
/* Parsing of date and time */
IDate = form.date.value;
if (testDate(IDate)) return (true);
return (false);
}
function runSubmit (form, button) {
if (!testBox1(form)) return;
document.inputform.submit(); // un-comment to actually submit form
return;
}
</script>
</head>
<body>
<form name="inputform" action="/cgi-bin/main.pl">
<input name="date" type="text" size="8"></td>
<input type="button" name="act" value="Submit"
onClick="runSubmit(this.form,
this)">
</form>
</body>
</html>

Функция testDate в этом примере фактически не проверяет дату, а лишь выдает ее значение в окне сообщения, однако вместо такой заглушки можно написать честную проверку. Для демонстрации работы с dtrace она нам не понадобится. В скрипт /cgi-bin/main.pl передаются введенные данные из поля. Листинг main.pl мы не приводим, так как сейчас он не имеет для нас значения – мы изучаем работу функции проверки данных на стороне клиента, а скрипт main.pl работает на сервере.

Запускаем firefox-bin с включенными в него датчиками, открываем файл с вышеприведенным кодом и переходим к эксперименту:

# dtrace -n 'javascript*:::function-args /copyinstr(arg2) ==
"testDate"/ {printf("%s %s %d %s",copyinstr(arg0),copyinstr(arg2),arg
3,copyinstr(arg5));}'
dtrace: description 'javascript*:::function-args ' matched 4 probes
CPU ID FUNCTION:NAME
1 18348 jsdtrace_function_args:function-args file:///export/home/
filip/jstest.html testDate 1 00.00.00

Как видно из вывода нашего скрипта, в качестве даты мы вводили значение 00.00.00. Будем надеяться, что настоящая функция проверки даты такого безобразия не пропустит!

< Лекция 15 || Лекция 16: 123
Александр Тагильцев
Александр Тагильцев

Где проводится профессиональная переподготовка "Системное администрирование Windows"? Что-то я не совсем понял как проводится обучение.

Виталий Шацилло
Виталий Шацилло
Россия, Санкт-Петербург
Петр Арсенин
Петр Арсенин
Россия, Москва