Read shared memory from x86 to x64 and vice versa on OSX

If I create SM from a 64-bit application and open it on a 32-bit application, it will fail.

//for 64 bit shared_memory_object( create_only, "test" , read_write) ; // for 32 bit shared_memory_object (open_only, "test", read_write); 

the file created by the 64-bit application is located in the path indicated below:

 /private/tmp/boost_interprocess/AD21A54E000000000000000000000000/test 

where as a file looking for a 32-bit application is the path

 /private/tmp/boost_interprocess/AD21A54E00000000/test 

Therefore, 32-bit applications cannot read the file.

I am using boost 1.47.0 for Mac OS X. Is this a bug? Do I need to make some adjustments using some macros to fix this? Has anyone encountered this problem before?

+4
source share
2 answers

I found a solution to the problem and, as expected, this is a mistake.

This error is present in the tmp_dir_helpers.hpp file.

  inline void get_bootstamp(std::string &s, bool add = false) { ... std::size_t char_counter = 0; long fields[2] = { result.tv_sec, result.tv_usec }; for(std::size_t field = 0; field != 2; ++field){ for(std::size_t i = 0; i != sizeof(long); ++i){ const char *ptr = (const char *)&fields[field]; bootstamp_str[char_counter++] = Characters[(ptr[i]&0xF0)>>4]; bootstamp_str[char_counter++] = Characters[(ptr[i]&0x0F)]; } ... } 

Where, as it should have been, something like this ..

 **long long** fields[2] = { result.tv_sec, result.tv_usec }; for(std::size_t field = 0; field != 2; ++field){ for(std::size_t i = 0; i != sizeof(**long long**); ++i) 

I created a ticket in boost for this error.

Thanks.

+1
source

Is it important that shared memory is supported by the file? Otherwise, you can use the basic Unix shared memory APIs: shmget, shmat, shmdt, and shmctl, all declared in sys / shm.h. I found them very easy to use.

 // create some shared memory int id = shmget(0x12345678, 1024 * 1024, IPC_CREAT | 0666); if (id >= 0) { void* p = shmat(id, 0, 0); if (p != (void*)-1) { initialize_shared_memory(p); // detach from the shared memory when we are done; // it will still exist, waiting for another process to access it shmdt(p); } else { handle_error(); } } else { handle_error(); } 

Another process will use something like this to access shared memory:

 // access the shared memory int id = shmget(0x12345678, 0, 0); if (id >= 0) { // find out how big it is struct shmid_ds info = { { 0 } }; if (shmctl(id, IPC_STAT, &info) == 0) printf("%d bytes of shared memory\n", (int)info.shm_segsz); else handle_error(); // get its address void* p = shmat(id, 0, 0); if (p != (void*)-1) { do_something(p); // detach from the shared memory; it still exists, but we can't get to it shmdt(p); } else { handle_error(); } } else { handle_error(); } 

Then, when all processes are running with shared memory, use shmctl(id, IPC_RMID, 0) to release it back to the system.

You can use the ipcs and ipcrm tools on the command line to manage shared memory. They are useful for troubleshooting the first time you write shared memory code.

All that has been said, I'm not sure about the sharing of memory between 32-bit and 64-bit programs. I recommend trying Unix APIs, and if they fail, this is probably not possible. After all, this is what Boost uses in its implementation.

+1
source

All Articles