2011-12-23 2 views
1

이 코드 세그먼트가 세그먼트 오류를 ​​일으키는 이유는 무엇입니까?mmap : map_anonymous 왜 SIGSEGV를 제공합니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 
#include <string.h> 

int main() 
{ 
    void *ptr; 

    ptr=mmap(NULL, 10, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0); 
    strcpy(ptr, "Hello"); 

} 

또는 더 나은, 내가하고 싶은 : char *ptr=malloc(10); 다음 메모리 매핑이 인수를 전달합니다. 둘 다 SIGSEGV를 제공합니다.

답변

10

시스템 호출의 반환 값을 확인하십시오! 그래서 mmap는 대부분 실패 EINVALerrno 세트 ((void*)-1 반환)이며,

MAP_SHARED 
    Share this mapping. Updates to the mapping are visible to other processes 
    that map this file, and are carried through to the underlying file. The file 
    may not actually be updated until msync(2) or munmap() is called. 

MAP_PRIVATE 
    Create a private copy-on-write mapping. Updates to the mapping are not 
    visible to other processes mapping the same file, and are not carried through 
    to the underlying file. It is unspecified whether changes made to the file 
    after the mmap() call are visible in the mapped region. 

당신은 그것을 제공하지 않는 :

mmapflags 인수는이 두 가지 옵션 중 정확히 하나가 있어야합니다.

+1

+1, 세분화 오류를 진단 수단으로 사용하는 것이 항상 바람직한 결과를 얻을 수있는 것은 아닙니다. –

+0

고마워, 해결 됐어. 이제 malloc의 반환 값을 mmap의 첫 번째 인수로 사용하고 있습니다. malloc 대신 메모리 맵핑이 오버 헤드가 될 수 있다고 생각하십니까? – kingsmasher1

+0

@ kingsmasher1 : 가능합니다. 'mmap'의 최소 매핑은 1 페이지 (많은 시스템에서는 4k이지만 훨씬 더 클 수 있습니다.)이므로 작은 할당에 적합하지 않습니다. (매핑 테이블 내부에서 작은 덩어리를 관리하지 않는 한. (OS 및 CPU의 경우) 오버 헤드가 발생합니다. 자신이 수행 한 작업을 빠르고 저렴하게 구현할 수 있다고 생각하지 마십시오. 수행하기 어렵고 "완벽하게"수행하기가 거의 불가능합니다. 심지어 밸 글 린드도 모든 잘못된 메모리 참조를 캐치하고 실제로는 전체 CPU_와 _emulates – Mat

0

당신은 아마 errnoEINVALmmap의 결과로 (즉, (void*)-1입니다) MAP_FAILED를 얻을. man page of mmap(2)은 10 그것은 페이지 길이 (최소 4K)의 배수 여야합니다 수 없습니다 (man 페이지에서 length라고도 함) mmap

EINVAL We don't like addr, length, or offset (e.g., they are too large, 
      or not aligned on a page boundary). 

두 번째 인수에 실패했다.

+0

'lenght'는 페이지 크기의 배수 여야한다는 요구 사항은 없습니다. (리눅스 시스템 호출을위한 맨 페이지는 die.net보다 kernel.org에서 훨씬 낫다. 그들은 실제로 최신 상태이며 실제로 실제로 포맷되어있다.) – Mat

관련 문제