2012-07-23 2 views
1

짧은 질문 :
이 두 가지 방법을 가지고 malloc이 된 버퍼를 매핑 할 수 있나요 (두 개의 포인터가 같은 물리적 가리키는 메모리) 같은 버퍼에 액세스? 또는 malloc에서받은 가상 메모리 주소를 임시로 이동할 수 있습니까? 또는 가상 공간의 한 위치에서 다른 위치를 가리킬 수 있습니까?리눅스 - 가상 메모리 주소를 malloc에에서 가상 메모리 주소를 중복 또는 이동

배경 : 나는 DirectFB 함께 일하고
, 표면 관리 및 2D 그래픽 라이브러리를 퇴비. 표면을 잠그고, 잠겨있는 동안 (포인터는 malloc을 사용하여 시스템 메모리에 할당 됨) 만 메모리를 수정하고 표면을 잠금 해제하는 잠금 프로토콜을 시행하려고합니다.

현재 표면을 잠그고 픽셀 포인터를 저장하고 나중에 서페이스를 수정하는 응용 프로그램에서 버그를 추적하려고합니다. 즉, 라이브러리가 표면을 읽거나 쓰는 것이 안전한지 알 수 없음을 의미합니다. 잠금 프로토콜이 위반되었음을 감지하는 방법을 찾으려고합니다. 내가 원하는 것은 잠금 해제 호출이 이루어진 후 사용자에게 전달 된 포인터를 무효화하는 방법입니다. 더 나은, 잠금 후 메모리에 액세스하려고하면 응용 프로그램을 seg 오류 싶습니다. 이 디버거에서 중지하고 우리에게 그것이라고 관여 루틴 표면이 참여하고있는 아이디어, 등

가능한 솔루션을 제공합니다 :

  1. 임시 버퍼를 만들기를 버퍼 포인터를 사용자에게 전달하고, 잠금 해제시 실제 버퍼에 픽셀을 복사하고, 임시 버퍼를 삭제합니다. 버퍼.

    • 장점 : 구현 가능한 솔루션입니다.
    • 단점 : 비용이 많이 드는 사본이 필요하기 때문에 성능이 느려지고 메모리가 사용 가능하거나 사용 가능하지 않을 수도 있습니다. 하나의 임시 서페이스가 다른 서페이스와 겹치는 것을 보장하는 방법은 입니다. 갑자기 무효화 된 포인터가 다시 작동하도록 허용합니다.
  2. malloc 된 표면에 추가지도를 만들어 사용자에게 전달합니다. 잠금 해제시 메모리를 매핑 해제하십시오.

    • 장점 : 매우 빠른 속도로 추가 메모리가 필요하지 않습니다.
    • 단점 : 가능하면 알 수 없음.
    • Gotchas : 예약 된 범위의 주소는 다른 어떤 곳 (malloc 또는 커널 포함)에서 사용하지 않도록 설정해야합니다. 또한 은 낡은 포인터 가 갑자기 무언가를 가리키고 seg fault가 아닌 것을 가리킬 수있는 두 개의 서페이스가 겹치지 않도록해야합니다. 사용자가 잠겨 단순히 잠금에 가상 주소를 이동하고 다시 잠금 해제에 이동하는 동안 라이브러리가 메모리에 액세스하지 않는다는 사실을
  3. 테이크 장점.

    • 장점 : 매우 빠른 속도로 추가 메모리가 필요하지 않습니다.
    • 단점 : 가능하면 알 수 없음.
    • Gotchas : 위의 "2"와 동일합니다.

이 가능합니까?

추가 정보 :

  • 다음 stdlib를 사용하여, Linux 2.6을 사용하고 있습니다.
  • 도서관은 C로 작성되었습니다.
  • 라이브러리 및 응용 프로그램이 사용자 공간에서 실행됩니다.
  • 커스텀 메모리 할당 루틴을 작성하기 위해 커널 모듈을 사용할 가능성이 있지만, 에 모듈을 쓰는 것이 어렵다. 실제로 구현할 수있는 수준은 에 가까워 질 가능성이있다. 이 해결책. 그러나이 이 유일한 방법이라면, 알아두면 좋을 것입니다.
  • 기본 프로세서는 x86입니다.
+0

메모리 범위의 복사본을 원 하시겠습니까? 아니면 두 번째 포인터를 원하십니까? – steffen

+0

잠금 해제 호출시 무효화 될 수있는 두 번째 포인터가 필요합니다. – user1539433

+0

이것이 가능해야만합니다 ... 순환 버퍼 (버퍼가 두 번 순차적으로 메모리에 매핑되므로 전체 버퍼 크기가 읽기/쓰기가 단일 'memcpy'). –

답변

5

한 페이지의 여러 매핑을 만들 기능은 shm_open입니다.

한 프로세스 내에서만 메모리를 사용할 수 있지만 여전히 "공유 메모리"입니다. 즉, 동일한 기본 물리적 페이지에 대한 여러 가상 매핑이 존재합니다.

그러나 원하지 않는 것은 입니다.입니다. 실제로 수행해야 할 작업은 잠금 기능에서 mprotect 시스템 호출을 사용하여 잠금 해제시 메모리를 읽을 수 없도록 설정하고 잠금에 대한 사용 권한을 복원하는 것입니다. 잠금을 유지하지 않고 액세스하면 segfault가 발생합니다. 물론 이것은 하나의 동시 액세스 스레드에서만 작동합니다 ...

문제를 추적하는 또 다른 방법은 valgrind 또는 다른 메모리 분석 도구에서 응용 프로그램을 실행하는 것입니다. 이렇게하면 속도는 크게 느려지지만 아주 미세하게 제어 할 수 있습니다. 메모리를 액세스 할 수있는 것으로 표시하거나 해제하는 valgrind 스크립트를 만들 수 있으며 위반이 발생하면 디버거로 바로 이동할 수 있습니다. 그러나 이와 같은 일회성 문제를 해결하려면 #ifdef DEBUG-wrap 된 mprotect 호출을 잠금/잠금 해제 기능에 설치한다고 말하고 싶습니다.

+0

mprotect에 대해 알지 못했습니다. 추천 해 주셔서 감사합니다. mprotect의 유일한 문제점은 라이브러리가 여전히 메모리에 액세스해야한다는 것입니다. 물론 라이브러리에는 mprotect (현재 수행되는 것보다 더 많은 보호 기능이 있음)를 사용할 수있는 내부 잠금 메커니즘이 있지만 라이브러리에 표면이 잠겨있는 동안 응용 프로그램이 잠길 수있는 기회가 여전히 있습니다 .나는 당신의 valgrind 생각을 고려해야 할 것이지만, 나는 그것이 기회의 비슷한 창을 가지고 있을까 우려하고 있습니다. – user1539433

+0

@ user1539433 현재 스택 추적을 검사하는 오류 처리기를 등록 할 수 있으며 라이브러리 자체의 내부 접근 자 메서드로 연결되는 경우 SEGV를 삭제합니다. 이것은'mprotect' 또는 valgrind 스크립트와 함께 작동합니다. – Borealid

관련 문제