Вызов функции C из сценариев DTrace - PullRequest
3 голосов
/ 02 февраля 2010

DTrace - впечатляющая, мощная система трассировки, изначально созданная в Solaris, но она портирована на FreeBSD и Mac OSX.

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> все операции ввода-вывода, созданные в этом процессе, регистрируются.

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

Ответы [ 4 ]

6 голосов
/ 28 апреля 2010

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

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

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

1 голос
/ 17 декабря 2013

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

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

1 голос
/ 30 мая 2013

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

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

1 голос
/ 28 апреля 2010

вы должны быть в состоянии хотя бы отфильтровать вывод 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!";
}
...