Я хочу сделать пример приложения с libev
. Я хочу иметь наблюдателя на вводе на клавиатуре, который будет анализировать несколько команд, таких как «start» «stop» «exit». В «start» я хочу создать канал и развернуть приложение, чтобы запустить какого-нибудь рабочего (например, ffmpeg
с exec()
или только некоторый цикл, который печатает некоторые символы) в дочернем элементе и установить наблюдателя на этом канале в родительском для вывода вывода на консоль , В команде «stop» я хочу убить ребенка и удалить наблюдателя.Ошибка сегментации в libev после fork
Я реализовал эту программу, но после развилки я всегда получаю segfault на ввод с клавиатуры, когда ребенок работает.
Сначала я подумал, что, если STDIN
можно разделить между дочерним и родительским. Я пытался отделить ребенка, закрыть STDIN
у ребенка. Затем я попробовал dup
STDIN
и закрыл по умолчанию STDIN
в исходном состоянии в начале и установил наблюдателя на дублированный STDIN
. Я также попытался закрыть дескрипторы STDOUT/ERR
перед разветвлением и восстановить их у родителя после вилки.
Я остановился и запустил user_input
наблюдатель в user_input
обратный вызов в случае, если это может вам помочь.
Затем я попытался выполнить ev_default_fork()
и ev_loop_fork()
у ребенка (это не нужно, потому что я хочу exec()
только после развилки или в любом случае ребенок петля никогда не получить контроль) без успеха.
Я также пытался использовать разные задние части (select
вместо epoll
).
Также я попытался игнорировать некоторые сигналы, такие как SIGHUP
SIGPIPE
SIGCHILD
.
Я заметил также, что мой ввод после fork()
вызывает segfault и bash, чтобы получить его как команду, поэтому, если я сделаю что-то вроде этого (с помощью «>» я обозначаю самописный ввод и с «<» программой и системой выход):
> $ ./libev_example
> start
< Debug: fork data got:
< [Data got from child through pipe]
> asd
< Segmentation fault (core dumped)
< $ asd
< bash: asd: command not found...
Тогда я построил libev
из источников и пытался отладить. Происходит в выдаёт ошибку сегментации ev.c:1698
if (expect_false (w_->pending))
pendings [pri][w_->pending - 1].events |= revents;
else
значение pri
является 4, и как я мог понять, что это приоритет. pendings[4]
- 0x0
, поэтому происходит segfault. Когда программа не сбой кода идет в else
ветви.
Fd, что epoll
возвращает 0, но я не использовал 0 в качестве fd в любом случае. Более того, для 0 есть наблюдатель в loop->anfds
, который имеет обратный вызов моего обратного вызова user_input
. В предыдущей итерации, когда я вводил какую-либо строку, не было никакого события для 0. Я проверил fds трубы, и они также имеют число терки, затем 0.
Я не могу понять, что происходит здесь и что я делаю неправильно. Я могу разместить здесь какой-то код, но там нет ничего особенного. Этот пост достаточно большой, поэтому, если кто-то запросит код, я отправлю его позже.
Спасибо.