Я пытаюсь отладить последовательное соединение на 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, так что это объясняет проблему.