2014-10-31 4 views
1

내 모델링 코드에서 부스트 memory mapped files을 사용하여 디스크에 대용량 배열을 할당합니다.부스트 메모리 매핑 파일이 HDD보다 여유 공간보다 많은 디스크 공간을 할당했을 때 어떻게 오류를 감지 할 수 있습니까?

잘 작동하지만 디스크 드라이브의 여유 공간보다 큰 배열을 할당하는 상황을 감지 할 수있는 방법을 찾을 수 없습니다. 내가 allocted되지 않는 메모리의 일부에 기록 될 때까지

boost::iostreams::mapped_file_params file_params; 

    file_params.path = path; 
    file_params.mode = std::ios::in | std::ios::out; 
    file_params.new_file_size = static_cast<size_t>(8E9); # About 10GB 
    file_params.length = static_cast<size_t>(8E9); 

    boost::iostreams::mapped_file result; 

    result.open(file_params); 

나는 심지어의 becaue (resuld.data()에서 작업 할 수 있습니다 : 행복하게 실행하는 코드를 다음과 같은 예를 들어 (내가 HDD 여유 공간 8E9 바이트 이하가 있다고 가정) HDD 공간)를 누락 한 후 나는 다음과 같은 오류 얻을 :

memory access violation at address: 0x7e9e2cd1e000: non-existent physical address 

나는 비밀 memory access violation를 얻기 전에이 오류를 감지 할 수있는 방법이 있나요를?

필자는 실제로이 테스트를 수행했습니다. 파일이 파티션의 사용 가능한 공간보다 크면 코드에 메모리 액세스 위반이 있으며 코드가 작 으면 코드를 편집하지 않고 파티션의 여유 공간을 변경하여 테스트했습니다. .

가능한 솔루션 디버깅

제로와 I std:fill 파일의 내용이 아직도 memory access violation을받을 경우하지만이 오류가 할당 근처에 위치하고 있으며 쉽게. 차라리 예외를 발생시키는 방법을 원합니다.

+0

디스크 공간이 부족한 것처럼 보이지만 매핑 한 범위의 메모리 크기를 액세스하고 있습니다. ir가 실제로 0x1E11이 아닌 1E11입니까? – Oncaphillis

+0

이것은 디스크 공간과 완전히 관련되어 있으며 실제로이 오류가 발생합니다. 내 '/ tmp' (10GB 크기) 코드에 8GB를 할당하면 2.5GB 파일을이 파티션에 쓰면이 오류가 발생합니다. 이것은 부스트에서 다소 불명확 한 버그 일 수 있습니다. --- 자동으로 공간을 잘라낼 수 있습니다 (이 경우 실제로 범위 밖의 메모리에 액세스합니다). –

+0

@user 나는 질문을 편집했다 --- 나는 그 숫자가 무의미하다고 생각했다. 실제로는 약 8GB이며, 숫자는 이제이를 반영해야합니다. 오해를해서 죄송합니다. –

답변

1

fallocate 또는 posix_fallocate을 사용하여 실제로 파일 앞에 공간을 예약 할 수 있습니다. 이렇게하면 절대 "지나치게 커밋하지"않을 것입니다. 물론 초기 생성시에는 성능상의 단점이 있습니다.

보안상의 이유로 OS는 fallocate의 블록을 제로로 만들 수 있습니다.

fallocate을 사용하면 쓰기되지 않은 익스텐트를 만들 수 있지만 처음 액세스 할 때는 여전히 0이됩니다. 창문에서 이것을 쓸어 낼 수도 있습니다. SetFileValidData도 우회 할 수 있습니다. 당신이 훨씬 CPU의 일을하는 경우 리눅스 O_DIRECT + fallocate()으로, (윈도우 SetFileValidData 반대) 여전히 상당한 CPU를 사용하고, IO 대역폭은 일반적으로 병목하지만

참고이 여전히 성능이 현저하게 영향을 미칠 수 같은 시간.

+0

플랫폼 독립성을 유지하면서이 작업을 수행 할 수있는 방법이 있습니까? 이것이 엄격한 요구 사항은 아니지만, 이제는 플랫폼에 독립적 인 도구를 사용하여 전체 응용 프로그램을 작성하고이를 잃으면 사소한 문제가 발생합니다. –

+0

'posix_fallocate'가 전폭적으로 지원 될지도 모릅니다. – sehe

+0

적어도 모든 posix 시스템에. 어쩌면 나는 분명하지 않다.이 솔루션이 Windows에서도 작동한다면 정말 좋을 것이다. –

1

Is there any way to detect this error before I get cryptic memory access violation?

는 단지 파일의 크기를 변경하는 경우가 sparse 될 것입니다, 그 데이터가없는 지역은 디스크 공간을 사용하지 않는 것을 의미한다. 쓰기 중 공간이 할당되며 디스크 공간 오류가 발생할 수 있습니다.

문제를 해결하는 방법은 크기를 변경하는 대신 (더미) 데이터를 파일에 쓰는 것입니다. 그 시간은 더 오래 걸리지 만 나중에 파일이 최종 크기를 가지기 때문에이 첫 번째 쓰기 사이클 동안에 만 디스크 공간이 부족해질 수 있습니다.

+0

이것은 다소 이상한 일이지만, 다음과 같이하면 문제가 해결되지 않습니다.''std :: fill (result.data(), result.data() + this-> array_size_bytes, 0);' '. 나는 아직도''메모리 접근 위반 ''을 당한다. 이 위반은 디버그하는 것이 훨씬 쉬우나 여전히 그렇습니다. 차라리 어떤 메시지를 가로 채고 콘솔에 유용한 정보를 인쇄 할 수 있기를 원합니다. –