2013-04-19 4 views
0

libev으로 예제 응용 프로그램을 만들고 싶습니다. 나는 "start" "stop" "exit"와 같은 몇 가지 명령을 구문 분석 할 키보드 입력에 대한 감시자를 원합니다. "시작"에서 나는 파이프를 만들고 응용 프로그램을 포크로 작성하여 (예 : ffmpeg, exec() 또는 일부 문자를 인쇄하는 일부 루프) 자식을 시작하고 부모에게이 파이프에 대한 감시자를 설정하여 출력을 콘솔에 인쇄하려고합니다 . "stop"명령에 나는 아이를 죽이고 감시자를 제거하고 싶다.포크 후 libev의 분할 오류

이 프로그램을 구현했지만 포크 후에 아이가 실행 중일 때 항상 키보드 입력에서 segfault를 얻습니다.

처음에는 나는 STDIN을 자식과 부모가 공유 할 수 있기 때문에 생각했습니다. 아이를 분리하려고 시도했습니다. 어린이는 STDIN입니다. 그런 다음 dupSTDIN을 시도하고 처음에는 부모의 기본값 STDIN을 닫고 복제본의 경우 감시자를 STDIN으로 설정했습니다. 또한 포크를 사용하기 전에 STDOUT/ERR 개의 설명자를 닫고 부모에서 복원하는 작업을 시도했습니다.

user_input 청취자가 콜백 user_input에서 중지되어 도움이 될 수 있습니다.

은 그럼 내가 성공하지 못했다 (이 난 그냥 포크 후 또는 어떤 경우 아이 루프 결코 제어에 exec()를 원하기 때문에 필요하지 않습니다) 아이에 ev_default_fork()ev_loop_fork()을 실행하기 위해 노력했다.

또한 다른 백엔드 (epoll 대신 select)를 사용하려고했습니다.

나는 또한 SIGHUPSIGPIPESIGCHILD과 같은 일부 신호를 무시하려고했습니다.

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을 빌드하고 디버깅을 시도했습니다. 는 segfault는 ev.c:1698

if (expect_false (w_->pending)) 
     pendings [pri][w_->pending - 1].events |= revents; 
    else 

pri 값이 4에서 일어나는 내가 이해할 수로는 우선 순위입니다. pendings[4]0x0이므로 segfault가 발생합니다. 프로그램이 코드를 충돌하지 않으면 else 브랜치에 들어갑니다.

epoll이 반환하는 fd는 0이지만 fd는 0으로 사용하지 않았습니다. 또한 0의 경우 내 user_input 콜백에 대한 콜백을 가진 loop->anfds에 감시자가 있습니다. 이전 반복에서는 어떤 문자열을 입력 할 때 0에 대한 이벤트가 없었습니다. 파이프 파이프 라인을 검사 한 결과 0보다 큰 숫자도 나타났습니다.

여기에서 무슨 일이 일어나는지 파악할 수 없습니다. 잘못된. 나는 여기에 몇 가지 코드를 넣을 수 있지만 특별한 것은 없다. 이 게시물은 꽤 크기 때문에 누군가 코드를 요청하면 나중에 게시하게됩니다.

감사합니다.

답변

0

확인. gdb에서 문제가 해결되었습니다.내 코드에서 libev 나 fork와 직접적인 관련이없는 몇 가지 오류가 발견되었습니다.

그런 이상한 행동을 일으킨 문제는 내 부주의로 인해 눈치 채지 못했던 실수였습니다. 나는 표준 ev_io 구조체를 서브 클래스하지만 어떤 이유로 나는이 만든 : 그래서 내 자신의 구조체에 콜백에서 이벤트 포인터를 캐스팅

typedef struct lee_user_input_event_t{ 
    struct ev_io event; 
    struct lee_process_data_t *child_process_data; 
... 
} 

완전하고 거대한 재앙이었다 대신이의

typedef struct lee_user_input_event_t{ 
    struct ev_io *event; 
    struct lee_process_data_t *child_process_data; 
... 
}; 

합니다.