Системные вызовы в strace

Я вызвал strace некоторую программу A, которая разветвляет две дочерние программы: B и C.

В strace у меня есть следующие syscalls:

 pipe[([3,4]) = 0
 pipe([5,6]) = 0
 fork(wc) = 7135
 fork (gnetcat) = 7136
 close(3) = 0
 close(5) = 0
 close(4) = 0
 close(6) = 0
 wait4(-1, NULL, 0, NULL) = 7136
 wait4(-1, NUKLL, 0, NULL) = 7135

Я пытаюсь переписать программу A на C. В этом случае мне действительно никогда не нужно знать, что означают эти файловые дескрипторы _9 _, _ 10 _, _ 11_ и 6, не так ли? Есть ли способ узнать, что это такое? Я знаю, что 3 для stderr.


person darksky    schedule 22.02.2012    source источник


Ответы (2)


0 - это STDIN, 1 - это STDOUT, а 2 - это STDERR. Все более высокие числа зависят от приложения. В этом случае я подозреваю, что они используются для захвата stdout / stderr недавно созданных программ. Это означало бы, что "wc", вероятно, работает со своим stdout, связанным с fd 3, а stderr с fd 4, поэтому основное приложение может выводить wc.

person Sec    schedule 22.02.2012
comment
Почему тогда файловые дескрипторы - это пустые файлы? Как они будут работать с передачей данных? Чтобы иметь возможность реализовать это на C, действительно не имеет значения, что означают 4 и все более высокие файловые дескрипторы, не так ли? Я могу просто передать их в трубы, да? - person darksky; 23.02.2012
comment
файловые дескрипторы представляют собой (открытый) канал. Вам нужен fd, чтобы можно было определить, куда вы пишете. - Поскольку ваш strace не содержит read () или write (), похоже, что по этим каналам ничего не отправляется, что немного странно. - А вот форк (программа) предлагает вам отредактировать :-) - person Sec; 23.02.2012

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

Процесс верхнего уровня создает две трубы. Каналы используются программами для связи друг с другом. Первый канал имеет конец чтения на fd 3 и конец записи на fd 4. Второй канал имеет конец чтения на fd 5 и конец записи на fd 6.

Поскольку программа верхнего уровня закрывает все четыре fds после вызова двух дочерних программ, похоже, что они просто используются внутри дочерними программами (которые обе получают копии fds). Это необычно, потому что обычно я ожидал, что родительский процесс оставит один en открытым в другом месте для связи с дочерним процессом. Похоже, в вашей трассировке отсутствует какая-то важная информация о том, что происходило с fds после каждой вилки.

Это то, что я ожидал бы увидеть, если бы процесс открывал каналы для захвата stdout от дочернего элемента, например:

parent_pid: pipe[3,4]
parent_pid: clone() = child_pid
parent_pid: close(4)
child_pid:  dup(4,1)
child_pid:  close(4)
child_pid:  close(3)
child_pid:  execve(some program)
child_pid:  write(1)
parent_pid: read(3)
parent_pid: wait(child_pid)
child_pid:  exit()
person EllexusTechSupport    schedule 13.06.2013