0

I have a 32bit application running as a service in windows (OS : Microsoft Windows Server 2012 R2 Standard). Its a client server based application which Maps a view of a file using the MapViewOfFile() API for every new client attached. Its basically creating new view every time whenever new client connects. The view size is sizeof(CLRHostArea_t) which is equal to 8394264 (around 8MB). But after running for around 190 client call the server crashes. It is because of MapViewOfFile returns NULL and giving the error 8 in GetLastError(). This error will be same for all the call after this. Following code snippet is from my server application:

Creating the handle: hAISHostMap = CreateFileMappingA(INVALID_HANDLE_VALUE,
&Sa,
PAGE_READWRITE ,
0,
sizeof(CLRHostArea_t),
FileMapName);

Mapping a view: this->CLRHostArea = (CLRHostArea_t*)MapViewOfFile(hAISHostMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

In order to reproduce the issue with MapViewOfFile(), I have tried the below program in the same environment and have observed the same error:

 const int sizeOfTheFileMappingObject = 8394264;
 const int numberOfBytesToMap = sizeOfTheFileMappingObject;
 const char* fileMappingObjectName = "Global\\QWERTY";

 void AllocateMemoryWithMalloc(std::vector<void*>* addresses)
 {
 const size_t sizeOfMemAllocatedAtOnce = 32* 
 1024;
for (;;) {
    void* address = malloc(sizeOfMemAllocatedAtOnce);
    if (address != NULL) {
        addresses->push_back(address);
    }
    else {
        printf("The %dth malloc() returned NULL. Allocated 
memory: %d MB\n",
            addresses->size() + 1,
            (addresses->size() * sizeOfMemAllocatedAtOnce) / 
(1024 * 1024));
        break;
    }
  }
 }

void DeallocateMemoryWithFree(std::vector<void*>* addresses)
{
std::vector<void*>::iterator current = addresses->begin();
std::vector<void*>::iterator end = addresses->end();
for (; current != end; ++current) {
    free(*current);
}
addresses->clear();
printf("Memory is deallocated.\n");
}

void TryToMapViewOfFile()
{
HANDLE fileMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE,
    fileMappingObjectName);
if (fileMapping == NULL) {
    printf("OpenFileMapping() failed. LastError: %d\n", 
GetLastError());
    return;
}

LPVOID mappedView = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 
0, numberOfBytesToMap);
if (mappedView == NULL) {
    printf("MapViewOfFile() failed. LastError: %d\n", 
GetLastError());
    if (!CloseHandle(fileMapping)) {
        printf("CloseHandle() failed. LastError: %d\n", 
GetLastError());
    }
    return;
}

if (!UnmapViewOfFile(mappedView)) {
    printf("UnmapViewOfFile() failed. LastError: %d\n", 
GetLastError());
    if (!CloseHandle(fileMapping)) {
        printf("CloseHandle() failed. LastError: %d\n", 
GetLastError());
    }
    return;
}

if (!CloseHandle(fileMapping)) {
    printf("CloseHandle() failed. LastError: %d\n", 
GetLastError());
    return;
}

printf("MapViewOfFile() succeeded.\n");
}

int main(int argc, char* argv[])
{
HANDLE fileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, 
NULL,
    PAGE_READWRITE, 0, sizeOfTheFileMappingObject, 
fileMappingObjectName);
if (fileMapping == NULL) {
    printf("CreateFileMapping() failed. LastError: %d\n", 
GetLastError());
    return -1;
}

TryToMapViewOfFile();

std::vector<void*> addresses;

AllocateMemoryWithMalloc(&addresses);

TryToMapViewOfFile();

DeallocateMemoryWithFree(&addresses);

TryToMapViewOfFile();

if (!CloseHandle(fileMapping)) {
    printf("CloseHandle() failed. LastError: %d\n", 
GetLastError());
}

return 0;
}

In 64 bit platform, the function TryToMapViewOfFile() is successful for all the calls even if we are not deallocating the allocated memory. But it fails for 32bit platform after AllocateMemoryWithMalloc() and same after deallocating the memory also. And giving the error code of 8 in GetLastError().

Is this because of deallocation is not happening in 32bit even if we properly deallocating using the UnMapViewOfFile() and CloseHandle() function calls?

I have searched for many articles on this but nothing has solved my problem. It is a critical issue as the server is crashing, and I am bound with 32 bit architecture. Any help how we can resolve this issue in 32bit?

3
  • 190 calls with 8 MiB each is 1.5 GiB which is the virtual memory limit in Win32. This would indicate to me that you leak the memory and the unmap calls don't actually happen. Try seeing if they are actually called with some log statements or so Commented Aug 26, 2022 at 12:35
  • I have checked it using the log messages, unmapping and closing of handle is called for every client. Commented Aug 26, 2022 at 13:01
  • Hi, you are correct, the issue was happening because of the memory leak and the unmap calls was not actually happen. The address which I was passing to unmap the view was not correct. It was passed like UnmapViewOfFile(&CLRHostArea), instead I have to pass the pointer to the base address of the mapped view that is to be unmapped. UnmapViewOfFile(&CLRHostArea); should be UnmapViewOfFile((LPCVOID)(this->CLRHostArea)); and then CloseHandle(hAISHostMap); Commented Aug 30, 2022 at 19:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.