2012-07-02 3 views
-1

두 프로세스간에 메모리를 공유하고 싶습니다.
mmap() 뒤에 주소가 mapStart 인 경우 mapStart에 오프셋을 추가하고 mapAddr을 얻고 mapAddr이 매핑 된 PAGE_SIZE를 초과하지 않도록하십시오.
내가mmap() 후 반환 된 주소에 쓰기는 정상이지만 시스템 충돌을 일으킬 수 있습니다. 이유는 무엇입니까?

memcpy((void *)mapAddr, data, size); 

모두에 의해 mapAddr에 쓸 때 확인합니다.

하지만

memcpy(&data, (void *)mapAddr, size);` 

것이다 경우 시스템 충돌

에 의해 mapAddr에서 읽을 때.
누가 알 수 있습니까? The similar problem is here

일부 정보 추가 @Tony Delroy을, @ J-16 SDiZ
의 mmap 기능은 다음과 같습니다

mapStart = (void volatile *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, memfd, pa_base); 

시스템 충돌 : 더 어떤 OS 오류 메시지가없는, 콘솔은 일부 MCA 정보를 인쇄

세부 사항은에서 설명합니다 here

+2

여기 미친 아이디어가 있습니다. 왜 'mmap()'에 대한 인수를 준비하는 코드를 보여주지 않습니까? 모든 경우에 보호 플래그에'PROT_READ'가 없지만 어떻게 알 수 있습니까? –

+2

어떤 종류의 "시스템 충돌"입니까? sigfault? 커널 패닉? 오류 메시지를 제공하십시오. –

+0

다른 게시물에서 IA64에 대해 언급했는데, 같은 아치입니까? –

답변

1

그냥 몇 가지 아이디어.

mmap()은 특성이 다른 메모리 영역에 걸쳐 있습니까? 이것은 불법입니다. 오래된 커널 (2.6.18)이 이것을 허용했지만, 그 중 일부에 쓸 때 충돌이 발생합니다.

일부 출발점은 this post을 참조하십시오. 가능하다면 새로운 커널을 사용해보십시오.

1

적어도 두 가지 문제가 있습니다 :의 mmap() 후

, 그때 내가 mapStart 오프셋 추가합니다 주소 mapStart를 얻고 mapAddr을 얻고, mapAddr이 MAPED PAGE_SIZE을 초과하지 않습니다 있는지 확인하십시오.

아니요 mapAddr은 매핑 된 크기를 초과하지 말고 mapAddr+size이어야합니다. 하나뿐 아니라 size 바이트를 터치하려고합니다.

memcpy((void *)mapAddr, data, size); 
memcpy(&data, (void *)mapAddr, size); 

data데이터로 가리키는 위치에서 없다 (처음 라인 어드레스 연산자없이 사용 이후 그럴듯한 가정 임) 어레이, 제 2 라인 사본을되지 가정 데이터로 시작하는입니다. 이것은 아마도 할당되지 않은 메모리이거나, 스택상의 어떤 위치, 또는 무엇이든간에 가능할 것입니다. 스택에 많은 정보가 없으면 스택 끝 부분을 텍스트 세그먼트로 읽거나 다른 정보를 읽을 수 있습니다.

(실제로 data이 배열 인 경우 물론 동일하지만 코드 스타일이 일치하지 않습니다.)

+0

첫 번째 : 'mapAddr + size' (테스트 된 프로그램)가 매핑 된 크기를 초과하지 않도록 할 수 있습니다. 둘째 : 데이터가 긴 유형이고 크기가 8이므로 문제가되지 않을 것이라고 생각합니다. –

+0

"두 번째 : 데이터가 긴 유형입니다."-이 경우 '& data'는 데이터의 주소이며 충돌의 원인은 내가 말했던 것입니다. 데이터의 주소에서 시작하여 "정의되지 않은 메모리 범위"를 읽습니다. 주소 연산자 ('&')를 제거하고, 포인터가 필요한 곳에 포인터를 사용하고 싶다. C에서 타입의 종류가 너무 엄격하지 않기 때문에 'long'을 포인터로 사용합니다. 그러나 기술적으로 잘못되었습니다. 포인터와 정수 (또는 'long')는 같은 것이 아닙니다. – Damon

+0

대단히 고맙습니다. 미안하지만 '&'가 없어야합니다. 내 실수입니다. 그러나 '&'를 제거해도 여전히 문제를 해결할 수 없습니다. 그리고 printf ("% ld", long() (mapAddr)));도 시스템 충돌을 야기했기 때문에 memcpy()를 사용했다. –