Я думаю, что хорошо включить опции ls
таким образом, поскольку cd
не принимает никаких опций.
cdls() {
cd ${$#} && ls ${@:0:$#-1}
}
Я отвечу только за Linux.
Удивительно, но в новых ядрах системный вызов ptrace
, который используется strace
для фактического выполнения трассировки, позволяет отслеживать процесс инициализации. На странице руководства сказано:
EPERM The specified process cannot be traced. This could be because
the tracer has insufficient privileges (the required capability
is CAP_SYS_PTRACE); unprivileged processes cannot trace pro‐
cesses that they cannot send signals to or those running set-
user-ID/set-group-ID programs, for obvious reasons. Alterna‐
tively, the process may already be being traced, or (on kernels
before 2.6.26) be init(8) (PID 1).
, что подразумевает, что начиная с версии 2.6.26, вы можете отслеживать init
, хотя, конечно, вы все еще должны быть root, чтобы сделать это. Бинарный файл strace
в моей системе позволяет мне отслеживать init
, и на самом деле я даже могу использовать gdb
для подключения к init
и уничтожения Это. (Когда я это сделал, система немедленно остановилась.)
ptrace
не может использоваться процессом для трассировки себя, поэтому, если strace
не проверит, он, тем не менее, завершится ошибкой на отслеживая себя. Следующая программа:
#include <sys/ptrace.h>
#include <stdio.h>
#include <unistd.h>
int main() {
if (ptrace(PTRACE_ATTACH, getpid(), 0, 0) == -1) {
perror(NULL);
}
}
печатает Операция запрещена
( т.е. результат EPERM
). Ядро выполняет эту проверку в ptrace.c
:
retval = -EPERM;
if (unlikely(task->flags & PF_KTHREAD))
goto out;
if (same_thread_group(task, current)) // <-- this is the one
goto out;
Теперь два процесса strace
могут отслеживать друг друга; ядро этому не помешает, и вы сами можете наблюдать за результатом. Для меня последнее, что выводит первый процесс strace
(PID = 5882), это:
ptrace(PTRACE_SEIZE, 5882, 0, 0x11
, тогда как второй процесс strace
(PID = 5890) вообще ничего не печатает. ps
показывает оба процесса в состоянии t
, что, согласно странице руководства proc (5)
, означает, что трассировка остановлена.
Это происходит из-за того, что трассируемый объект останавливается всякий раз, когда он входит в системный вызов или выходит из него, а также всякий раз, когда ему собирается доставить сигнал (кроме SIGKILL
).
Предположим, что процесс 5882 уже отслеживает процесс 5890. Затем мы можем вывести следующую последовательность событий:
ptrace
, пытаясь отследить процесс 5882. Процесс 5890 входит в трассировку. -останавливаться. SIGCHLD
, чтобы сообщить ему, что его трассируемый процесс 5890 остановлен. (Процесс с остановленной трассировкой выглядит так, как если бы он получил сигнал `SIGTRAP.) ptrace (PTRACE_SYSCALL, 5890, ...)
, чтобы продолжить процесс 5890. ptrace (PTRACE_SEIZE, 5882, ...)
. Когда последний возвращается, процесс 5890 переходит в режим остановки трассировки. SIGCHLD
, поскольку его трассируемый объект только что снова остановился. Поскольку он отслеживается, получение сигнала приводит к переходу к остановке трассировки. Теперь оба процесса остановлены. Конец.
Как вы можете видеть из этого примера, ситуация, когда два процесса отслеживают друг друга, не создает никаких внутренних логических трудностей для ядра, вероятно, поэтому код ядра не содержит проверки, предотвращающей возникновение такой ситуации.Просто бывает не очень полезно, чтобы два процесса отслеживали друг друга.