2013-06-17 4 views
2

inet_ntoa에서 OSX에서 세그먼트 화 오류가 발생하는 문제가 발생했습니다.이 문제는 Linux에서 발생하지 않으며, 이는 입니다.inet_ntoa() 세그먼트 화 오류가 OSX에서 발생했습니다

내 테스트 코드는 다음과 같습니다.

// sample.c 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
//#include <arpa/inet.h> // adding this line prevents the segfault 

int main() { 
    struct sockaddr_in addr; 
    struct sockaddr_in client; 

    int sock0 = socket(AF_INET, SOCK_STREAM, 0); 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(12345); 
    addr.sin_addr.s_addr = INADDR_ANY; 

    bind(sock0, (struct sockaddr *)&addr, sizeof(addr)); 
    listen(sock0, 5); 

    while (1) { 
     int len = sizeof(client); 
     int sock = accept(sock0, (struct sockaddr *)&client, (socklen_t *)&len); 
     printf("accepted connection from %s, port=%d\n", 
       inet_ntoa(client.sin_addr), ntohs(client.sin_port)); 
     send(sock, "HELLO", 5, 0); 
     close(sock); 
    } 

    close(sock0); 

    return 0; 
} 

난 잠시 동안 검색하고,이 「ARPA/inet.h "가 포함되어 추가 a solution 알았다. inet_ntoa가 inet.h에서 확실하게 선언되었고 올바른 방법이라고 확신합니다.

하지만이 코드가없는 이유는 무엇인지 이해할 수 없습니다. Include 라인없이이 코드를 만들고 링크하면 어떻게됩니까?

이 코드를 작성하는 것은 "암시 적 함수 선언"경고를 나타내지 만 링크 오류는 발생하지 않습니다. 이것은 링커가 어떻게 든 inet_ntoa의 구현을 찾았다 고 생각합니다. 잘못 되었나요?

감사합니다. 어떤 조언도 높게 평가됩니다.

답변

6

Linux 시스템이 32 비트 인 동안 OSX 시스템이 64 비트라고 추측합니다. 선언되지 않은 함수는 정수를 반환한다고 가정합니다. 64 비트 포인터가 포인터로 참조 해제 된 32 비트 정수로 쇠퇴 할 경우 세그멘테이션 오류가 발생할 수 있습니다.

4

C는 함수의 암시 적 선언을 허용합니다 (Implicit function declarations in C). 이 때문에 컴파일러 오류가 발생하지 않습니다. 또한 inet_ntoa는 기본적으로 gcc에 의해 링크 된 glibc에 있으므로 링커가 함수의 정의를 찾으면 링커 오류가 발생하지 않습니다. 세그 폴트는 1) C가 암시 적으로 선언했기 때문에 함수가 int를 반환하고 glibc의 inet_ntoa 맥에서 2) 32 비트 값으로 변환되어 정보를 잃는 64 비트 포인터를 반환한다고 가정하기 때문에 segfault가 발생합니다.

관련 문제