Почему в моей трассировке dtruss нет никаких execve вызовов?

У меня есть такой скрипт:

script.sh

#!/bin/bash

clang -v

Если я сделаю dtruss на этом тогда я ожидал бы увидеть execve позвонить clang,

$ sudo dtruss -f -a -e ./script.sh 

Тем не менее, след не содержит execve, Вместо этого есть ошибка:

...
 1703/0x16931:       856       4      0 sigaction(0x15, 0x7FFEE882A3B8, 0x7FFEE882A3F8)      = 0 0
 1703/0x16931:       858       4      0 sigaction(0x16, 0x7FFEE882A3C8, 0x7FFEE882A408)      = 0 0
 1703/0x16931:       874       4      0 sigaction(0x2, 0x7FFEE882A3C8, 0x7FFEE882A408)       = 0 0
 1703/0x16931:       881       4      0 sigaction(0x3, 0x7FFEE882A3C8, 0x7FFEE882A408)       = 0 0
 1703/0x16931:       883       4      0 sigaction(0x14, 0x7FFEE882A3C8, 0x7FFEE882A408)      = 0 0
dtrace: error on enabled probe ID 2149 (ID 280: syscall::execve:return): invalid address (0x7fc2b5502c30) in action #12 at DIF offset 12
 1703/0x16932:      2873:        0:       0 fork()       = 0 0
 1703/0x16932:      2879     138      5 thread_selfid(0x0, 0x0, 0x0)         = 92466 0
 1703/0x16932:      2958       8      0 issetugid(0x0, 0x0, 0x0)         = 0 0
 1703/0x16932:      2975       8      1 csrctl(0x0, 0x7FFEEE21DC3C, 0x4)         = 0 0
 1703/0x16932:      2985      12      6 csops(0x0, 0x0, 0x7FFEEE21E550)      = 0 0
 1703/0x16932:      3100      13      3 shared_region_check_np(0x7FFEEE21DA98, 0x0, 0x0)    
...
  • Что вызывает эту ошибку?
  • Как я могу получить execve команду, чтобы показать, чтобы я мог видеть вызванную программу и ее аргументы?

1 ответ

Решение

Это означает, что сценарий DTrace, который dtruss использует внутренне доступ к недопустимому адресу памяти, который происходит, пока он пытается отследить execve Звоните, вам интересно. В общем, dtruss (или, возможно, сам DTrace), похоже, содержит ошибку, которая мешает вам получить нужную информацию. К сожалению, Apple не была лучшей в поддержании DTrace и зависящих от него инструментов, хорошо работающих на macOS:-/.

В частности, для сценариев Bash / shell вы можете заставить его печатать каждую выполняемую команду, добавив set -x в верхней части вашего сценария (больше информации в этом другом ответе).

Если вы хотите, вы также можете попробовать использовать DTrace напрямую - это довольно простая однострочная (не пробовал запускать это сам, поэтому извиняюсь, если есть опечатки):

sudo dtrace -n 'proc:::exec-success /ppid == $target/ { trace(curpsinfo->pr_psargs); }' -c './script.sh'

Как это работает:

  • proc:::exec-success: Трассировать все exec-success события в системе, которые запускаются в подпроцессе, когда exec* Семейный системный вызов успешно возвращается.
  • /ppid == $target/: Фильтр, который означает, что это срабатывает только когда PID родительского процесса (ppid) соответствует PID, возвращенному для процесса, запущенного -c вариант мы перешли к dtrace команда ($target).
  • { trace(curpsinfo->pr_psargs); }: Это действие, которое нужно предпринять, когда событие срабатывает и соответствует нашему фильтру. Мы просто печатаем (trace) аргументы, передаваемые процессу, который хранится в curpsinfo переменная.

(Если это не удается с похожей ошибкой, скорее всего, ошибка в реализации macOS curpsinfo где-то.)

Другие вопросы по тегам