Если вы читаете исходный код для dtruss:
cat `which dtruss`
Вы обнаружите, что количество аргументов жестко закодировано.
Вступление:
syscall:::entry /(OPT_command && pid == $target) || (OPT_pid && pid == PID) || (OPT_name && NAME == strstr(NAME, execname)) || (OPT_name && execname == strstr(execname, NAME)) || (self->child)/ { /* set start details */ self->start = timestamp; self->vstart = vtimestamp; self->arg0 = arg0; self->arg1 = arg1; self->arg2 = arg2; /* count occurances */ OPT_counts == 1 ? @Counts[probefunc] = count() : 1; }
Вернуть:
/* print 3 arg output - default */ syscall:::return /self->start/ { /* calculate elapsed time */ this->elapsed = timestamp - self->start; self->start = 0; this->cpu = vtimestamp - self->vstart; self->vstart = 0; self->code = errno == 0 ? "" : "Err#"; /* print optional fields */ /* OPT_printid ? printf("%5d/%d: ",pid,tid) : 1; */ OPT_printid ? printf("%5d/0x%x: ",pid,tid) : 1; OPT_relative ? printf("%8d ",vtimestamp/1000) : 1; OPT_elapsed ? printf("%7d ",this->elapsed/1000) : 1; OPT_cpu ? printf("%6d ",this->cpu/1000) : 1; /* print main data */ printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n",probefunc,self->arg0, self->arg1,self->arg2,(int)arg0,self->code,(int)errno); OPT_stack ? ustack() : 1; OPT_stack ? trace("\n") : 1; self->arg0 = 0; self->arg1 = 0; self->arg2 = 0; }
Некоторые системные вызовы имеют индивидуальную обработку ( /* mmap has 6 arguments */
).
Я сделал копию сценария и копировать-вставить в несколько больше self->arg*
и , 0x%X
.
Я был в состоянии изменить значение по умолчанию на 6 аргументов, достигнув результата, как это:
posix_spawn(0x700003AA66B4, 0x7FF7B215BF10, 0x700003AA6570, 0x700003AA6610, 0x700003AA6720, 0x0) = 0 0
Что касается того, почему мы должны копировать-вставлять аргументы, а не просто увеличивать счетчик: DTrace не поддерживает циклы. Я думаю, потому что для трассировки недопустимо вводить возможность бесконечного цикла внутри ядра.