구문 적으로 정확하고 컴파일러 확장을 사용하기 때문에 코드가 컴파일됩니다. 그러나 코드에 근본적인 문제가있어서 segfault
으로 연결될 수 있습니다.
먼저, 신호 처리기 코드 :
typedef void (*sighandler_t)(int);
sighandler_t f(int pid) {
void sigintHandler(int sig) {
printf("Process %d", pid);
}
return sigintHandler;
}
이 not standard C하고 심지어 -ftrampolines
플래그가 실제로 컴파일 gcc
의 일부 버전에 지정해야합니다. 당신의 신호 핸들러 함수가 return sigintHandler;
에 의해 f
반환, 당신은 함수 포인터를 반환 할 때
sigintHandler
는 따라서, nested function입니다 :
귀하의 신호 처리기 함수 자체가 해결해야 할 몇 가지 문제가 있습니다. 당신이 void
반환 유형이 함수를 가리 키와 sigintHandler
는 다음과 같이 정의 된 매개 변수로서 int
을 할 수있는 함수 포인터 유형을 정의 typedef void (*sighandler_t)(int);
을 가지고 있기 때문에 코드에서
이 올바르게 컴파일합니다.
대신, 신호 처리기 기능은 단순히 기록 될 수있다 : 당신의 주요 기능에
void sigintHandler(int sig) {
printf("Signal %d\n", sig);
}
다음과 같습니다
여기
if (signal(SIGTSTP, *f(1)) == SIG_ERR) {
// ....
}
는 주목해야한다이뿐만 아니라이 일부 문제. 먼저 signal
함수는 첫 번째 매개 변수로 신호 번호 (일반적으로 signal.h
헤더에 정의 된 매크로)를 취하고 두 번째 인수는 void func_name(int sig)
으로 정의 된 함수에 대한 포인터를 사용합니다.
여기에 을 지정하면 포인터로 전달하는 대신 함수이됩니다.
*f(1)
은 실제로 f
을 호출하며 매개 변수로 1
을 전달합니다.
if (signal(SIGTSTP, f) == SIG_ERR) {
// ....
}
을하지만 f
이 함수 포인터를 반환하는 대신 void
로 정의되어 있기 때문에이 경고/오류를 방출한다 : 대신, 다음으로 변경합니다.
#include <stdio.h>
#include <signal.h>
void sigintHandler(int sig) {
printf("Signal %d", sig);
}
int main(void) {
// ...
if (signal(SIGTSTP, sigintHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
당신은 그러나 진술 : ...
변수 동작을 위해
그래서 준수하기 위해 코드를 변경, 당신은 다음을 수행 할 수 이것은 당신이 의도하고있는 변수의 종류에 달려 있지만, 신호에 기반한 가변 함수라면 다음과 같이 할 수 있습니다 :
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sig_stop(int sig) {
printf("Process %d stop\n", getpid());
}
void sig_int(int sig) {
printf("Process %d interrupt\n", getpid());
}
int main(void) {
// ...
if (signal(SIGTSTP, sig_stop) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sig_int) == SIG_ERR) {
// ...
}
// ...
return 0;
}
또는 당신은 switch
문 사용할 수 있습니다 일반적으로 SEG 오류를 디버깅하는 방법에 대한 팁 정말 감사하겠습니다
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void sigHandler(int sig) {
printf("Process %d received %d\n", getpid(), sig);
switch (sig) {
case SIGTSTP:
// do stop code
break;
case SIGINT:
// do interupt code
break;
}
}
int main(void) {
// ...
if (signal(SIGTSTP, sigHandler) == SIG_ERR) {
// ...
}
if (signal(SIGINT, sigHandler) == SIG_ERR) {
// ...
}
// ...
return 0;
}
을!
먼저 segmentation fault이 무엇인지 이해하십시오. gdb
과 같은 디버거를 사용하여 코드를 단계별 실행하거나 크래시 덤프를 검사하여 segfault
이 어디에서 발생하는지 확인할 수 있습니다.
희망이 도움이 될 수 있습니다.
표준 C는 다른 함수의 내부에서 함수를 정의하는 것을 지원하지 않으므로 이것은 전적으로 컴파일러에 따라 다릅니다. 왜 다른 함수 내부에서 함수를 정의해야합니까? 또한, [GCC 문서] (http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html)에 따르면, * "포함 함수가 끝난 후에 주소를 통해 중첩 된 함수를 호출하려고하면, 모든 지옥이 느슨해집니다. "* – clcto
'pid '를 전역 변수에 넣을 수는 없습니다 ('volatile sig_atomic_t '이어야합니다). – HolyBlackCat
그래, 글로벌 변수를 사용할 수있을 것 같아. 나는 아주 초보자 C 프로그래머이고 다른 곳에서는 일반적으로 가르쳐왔다 [global = bad] (http://wiki.c2.com/?GlobalVariablesAreBad) –