Почему strace не регистрирует все мои системные вызовы?

Я пытаюсь отладить последовательное соединение на BeagleBone под управлением Debian 8.7. Для этого я написал тестовую программу на ходу. Я не получил ожидаемых результатов, поэтому запустил strace в тестовой программе.

Разумеется, системных вызовов записи, которые я ожидал увидеть, там не было. Я проверил свой исходный код, и они определенно должны быть там. Программа тестирования по сути такова:

loop:
   write a log message to stderr
   write a buffer of binary 0x00 to the serial port 
   write a different log message to stderr
   write a buffer of binary 0xff to the serial port 

Программа выводит на stderr следующий вывод:

2015/11/12 21:28:45 111...
2015/11/12 21:28:46 000...
2015/11/12 21:28:48 111...
2015/11/12 21:28:49 000...
2015/11/12 21:28:51 111...
2015/11/12 21:28:52 000...
2015/11/12 21:28:54 111...
2015/11/12 21:28:55 000...
2015/11/12 21:28:57 111...
2015/11/12 21:28:58 000...
2015/11/12 21:29:00 111...
2015/11/12 21:29:01 000...
2015/11/12 21:29:03 111...
2015/11/12 21:29:04 000...
2015/11/12 21:29:06 111...
2015/11/12 21:29:07 000...
2015/11/12 21:29:09 111...
2015/11/12 21:29:10 000...
2015/11/12 21:29:12 111...
2015/11/12 21:29:13 000...
2015/11/12 21:29:15 111...
2015/11/12 21:29:16 000...
2015/11/12 21:29:18 111...
2015/11/12 21:29:19 000...
2015/11/12 21:29:21 111...

Затем я заметил, что не все записи в stderr появлялись в выводе strace. Будет выполнено первое сообщение журнала без второго, чего не может произойти с описанным выше алгоритмом. Вот выдержка из вывода, отфильтрованная путем поиска записи в файле trace.log. Как видите, записей в strace гораздо меньше, чем строк в stderr, что указывает на то, что strace не регистрирует все фактически выполняемые системные вызовы.

write(2, "2015/11/12 21:28:46 000...\n", 27) = 27
write(2, "2015/11/12 21:28:49 000...\n", 27) = 27
write(2, "2015/11/12 21:28:52 000...\n", 27) = 27
write(2, "2015/11/12 21:28:55 000...\n", 27) = 27
write(2, "2015/11/12 21:28:58 000...\n", 27) = 27
write(2, "2015/11/12 21:29:01 000...\n", 27) = 27
write(2, "2015/11/12 21:29:04 000...\n", 27) = 27
write(2, "2015/11/12 21:29:07 000...\n", 27) = 27
write(2, "2015/11/12 21:29:12 111...\n", 27) = 27
write(2, "2015/11/12 21:29:15 111...\n", 27) = 27
write(2, "2015/11/12 21:29:18 111...\n", 27) = 27
write(2, "2015/11/12 21:29:21 111...\n", 27) = 27

В моем исходном коде или в какой-либо из библиотек go, которые я использую, нет параллелизма, нет разветвления каких-либо дочерних процессов.

Я проверил справочную страницу strace, и, похоже, нет никакого способа указать статистическую выборку системных вызовов и никаких указаний на то, что он не регистрирует их все, если вы не укажете фильтрующее выражение (которого у меня нет).

Я понятия не имею, действительно ли происходят системные вызовы записи, направленные на последовательные порты, но прямо сейчас я не могу доверять выходным данным strace, потому что они не показывают мне все известные мне системные вызовы.

Кто-нибудь может объяснить, что происходит?

Моя командная строка:

strace -o trace.log -v ./serial-test --device /dev/ttyO2 --oscillator --delay 500

обновление: друг предложил добавить флаг -f, который, похоже, помог. что неясно, так это почему, поскольку в документации указано, что -f полезен только при наличии вызовов fork(), а в моей программе их нет (или, действительно, в выводе strace).

Итак, страница руководства также ссылается на clone(), а потоки Linux создаются с помощью clone(). go использует потоки Linux, так что это объясняет проблему.


person jonseymour    schedule 09.02.2017    source источник


Ответы (1)


Это сводится к тому, что golang свободно использует потоки, поэтому вам нужно использовать флаг strace -f, чтобы отслеживать вторичные потоки, которые go создал от вашего имени.

Таким образом, флаг strace -f требуется для дочерних процессов, созданных системным вызовом fork(), а также для потоков, созданных clone() [, а также vfork()]. Моя ошибка заключалась в том, что я полагал, что это требуется только для дочерних процессов.

person jonseymour    schedule 09.02.2017