Процессы сопоставления провайдера pid, которые приходят и уходят в dtrace
Я хотел бы отследить все вызовы функций для определенной библиотеки в процессе, но процесс будет регулярно выходить и повторно открываться, и я хочу продолжать трассировку.
Я делаю это сейчас:
oneshot$target:LIBRARY::entry
{
printf("%s\n", probefunc);
}
Тем не менее, это позволяет мне предоставлять только один пид за раз. Могу ли я продолжать это?
Я хочу что-то вроде:
*:LIBRARY::entry
/execname == "foo"/
но это * не работает там.
Спасибо!
1 ответ
Я не думаю, что вы можете сделать это с помощью одного сценария dtrace. Вам нужно два (по крайней мере...). И вам нужно иметь способность запускать разрушительные system()
действие, которое скорее всего означает root
доступ.
Предположим, вы хотите запустить этот скрипт на любом новом ls
процесс:
#!/usr/sbin/dtrace -s
pid$1:libc::entry
{
printf( "func: %s\n", probefunc );
}
Предполагая, что путь к этому сценарию /root/dtrace/tracelibc.d
, следующий скрипт запустится dtrace
на любой новый ls
процесс, который начинается. Обратите внимание, что вам нужно #pragma D option destructive
быть в состоянии начать dtrace
на новый процесс:
#!/usr/sbin/dtrace -s
#pragma D option destructive
#pragma D option quiet
proc:::exec-success
/ "ls" == basename( execname ) /
{
printf( "tracing process %d\n", pid );
system( "/root/dtrace/tracelibc.d %d", pid );
}
Это должно работать, но в этом случае ls
такой недолговечный процесс, что нечто подобное происходит довольно часто:
dtrace: failed to compile script /root/dtrace/tracelibc.d: line 10:
failed to grab process 12289
Процесс ушел к тому времени dtrace
начинается Если вы отслеживаете долгоживущие процессы и не заботитесь о том, что вы можете пропустить первые несколько проб, потому что dtrace
требуется время, чтобы присоединиться, все готово.
Но если вы хотите отследить недолговечные процессы, вам нужно остановить процесс сразу после его запуска, а затем перезапустить после dtrace
присоединяет:
#!/usr/sbin/dtrace -s
#pragma D option destructive
#pragma D option quiet
proc:::exec-success
/ "ls" == basename( execname ) /
{
printf( "stopping process %d\n", pid );
system( "/root/dtrace/tracelibc.d %d", pid );
stop();
}
и начать его обратно в tracelibc.d
:
#!/usr/sbin/dtrace -s
#pragma D option destructive
BEGIN
{
system( "prun %d", $1 );
}
pid$1:libc::entry
{
printf( "func: %s\n", probefunc );
}
Обратите внимание, что я использую Solaris prun
перезапустить остановленный процесс. Вы бы посмотрели на Mac dtrace
документация для stop()
позвоните, чтобы получить Mac эквивалент Solaris prun
,
Но... упс. Два приведенных выше сценария объединяются для создания:
stopping process 12274
dtrace: failed to compile script /root/dtrace/tracelibc.d: line 10:
probe description pid12274:libc::entry does not match any probes
Почему это говорит pid12274:libc::entry
не соответствует ни одного зонда? О да - когда exec
возвращается, libc.so
общий объект еще не загружен в память. Нам нужен зонд, который гарантированно существует в целевом процессе и который вызывается после libc.so
загружен, но перед обработкой. main
должно хватить. Так что основным скриптом для запуска всего этого становится:
#!/usr/sbin/dtrace -s
#pragma D option destructive
#pragma D option quiet
proc:::exec-success
/ "ls" == basename( execname ) /
{
printf( "stopping process %d\n", pid );
system( "/root/dtrace/tracemain.d %d", pid );
stop();
}
Это начинает tracemain.d
скрипт, который перезапускает процесс, загружает tracelibc.d
сценарий и снова останавливает процесс:
#!/usr/sbin/dtrace -s
#pragma D option destructive
#pragma D option quiet
BEGIN
{
system( "prun %d", $1 );
}
pid$1::main:entry
{
system( "/root/dtrace/tracelibc.d %d", $1 );
stop();
/* this instance of dtrace is now done */
exit( 0 );
}
А также tracelibc.d
добавляет свой собственный system( "prun %d", $1 );
в BEGIN
зонд, и это выглядит так:
#!/usr/sbin/dtrace -s
#pragma D option destructive
BEGIN
{
system( "prun %d", $1 );
}
pid$1:libc::entry
{
printf( "func: %s\n", probefunc );
}
Эти три действительно замедляют ls
процесс, но они производят ожидаемый результат - и есть много, как и ожидалось.