2010-02-02 1 views
3

DTrace - впечатляющая мощная система трассировки, первоначально из Solaris, но переносится на FreeBSD и Mac OSX.Вызов функции C из сценариев DTrace

DTrace использует язык высокого уровня под названием D не в отличие от AWK или C. Вот пример:

io:::start 
/pid == $1/ 
{ 
    printf("file %s offset %d size %d block %llu\n", args[2]->fi_pathname, 
     args[2]->fi_offset, args[0]->b_bcount, args[0]->b_blkno); 
} 

Использование командной строки sudo dtrace -q -s <name>.d <pid> все IOs возникла из этого процесса вошедшего.

Мой вопрос в том, что и как можно вызвать пользовательские функции C из сценария DTrace для выполнения расширенных операций с данными трассировки во время самой трассировки.

ответ

6

DTrace explicity не позволяет вам делать что-либо подобное по той же причине, что вы не можете написать цикл в D: если вы каким-либо образом испортите его, форму или форму, вы разбиваете всю систему. Когда запускается D-датчик, вы находитесь в режиме KERNEL, а не в пользовательской зоне. Позвольте мне привести цитату из «Руководства по программированию модуля ядра Linux»:

Итак, вы хотите написать модуль ядра. Вы знаете C, вы написали ряд обычных программ для запуска в качестве процессов, и теперь вы хотите добраться до того, где находится действительное действие , где один дикий указатель может уничтожить вашу файловую систему и ядро ​​ означает перезагрузку.

Вот почему вы не хотите играть в ковбоя в D-зонде и почему ограничения D подходят для вас. =]

1

вы должны иметь возможность по крайней мере фильтровать выход dtrace после того, как каждый датчик загорается трубами.

 
sudo dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }' | perl myscript.pl

myscript.pl:

#!/usr/bin/perl 
while (<>){ 
print $_; 
print "another application launched, do something!"; 
}

1

Это невозможно назвать произвольные C внутри ваших зондов по причинам, которые упоминают @Sniggerfardimungus, но по-видимому, вы просто хотите сделать некоторые операции с данными, которые бытие (хранить его в базе данных/делать с ним некоторые вычисления или визуализации/etc), и это вполне возможно из C (и через обертки вокруг C на нескольких других языках).

Для этого используйте libdtrace (заголовок находится в /usr/include/dtrace.h на моей коробке Mac OS X) или обертка для него, например node-libdtrace. Основная идея заключается в том, что вы можете создать своего собственного потребителя данных DTrace (фактически, заменив инструмент командной строки dtrace(1m)), который получает вывод от любого сценария. Когда у вас есть данные, вы можете делать все, что хотите.

1

Слишком поздно для редактирования моего исходного ответа, но вы также можете использовать команду system() внутри сценария DTrace, чтобы порождать подпроцесс, который запускает произвольный код, когда событие происходит в DTrace. Это потенциально destructive action, поэтому вам нужно использовать опцию командной строки -w или директиву #pragma D option destructive в сценарии D. Обратите внимание, что деструктивные действия могут зависать, бесконечный цикл, убивать и в противном случае уничтожать процессы, которые вы исследуете, если вы не используете их осторожно. (И я бы не рекомендовал использовать деструктивные действия ядра, если вам действительно неинтересно, если ваша система опустится, когда вы случайно ее испортите.)

Вы можете использовать скрипт, выполняемый system(), для вызова произвольного кода на C (или отправить сигнал другому процессу для его вызова и т. д.).