Skip to content

SharedObject can sometimes not access shared memory on macOS #12

@mtmorgan

Description

@mtmorgan

When trying to load SharedObject I get

> library(SharedObject)
Error: package or namespace load failed for 'SharedObject':
 .onLoad failed in loadNamespace() for 'SharedObject', details:
  call: C_initialPkgData()
  error: An error has occured in initializing shared memory object: An error has occured in allocating shared memory:
 Operation not permitted
You must manually initial the package via <initialSharedObjectPackageData()>

This is on

> sessionInfo()$running
[1] "macOS Monterey 12.4"

I debugged this by running under lldb and setting a break point on any C++ exception

$ R -d lldb
(lldb) break set -E c++
(lldb) run

Loading the package causes the exception

> library(SharedObject)
Process 23898 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001a736cb3c libc++abi.dylib`__cxa_throw
libc++abi.dylib`__cxa_throw:
->  0x1a736cb3c <+0>:  pacibsp
    0x1a736cb40 <+4>:  stp    x24, x23, [sp, #-0x40]!
    0x1a736cb44 <+8>:  stp    x22, x21, [sp, #0x10]
    0x1a736cb48 <+12>: stp    x20, x19, [sp, #0x20]
Target 0: (R) stopped.
(lldb) up
frame #1: 0x000000013d03d258 SharedObject.so`void boost::interprocess::ipcdetail::create_shared_dir_and_clean_old<char>(shared_dir="") at shared_dir_helpers.hpp:214:10
   211 	      //If fails, check that it's because already exists
   212 	      if(!open_or_create_shared_directory(root_shared_dir.c_str())){
   213 	         error_info info(system_error_code());
-> 214 	         throw interprocess_exception(info);
   215 	      }
   216
   217 	      #if defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME)
(lldb) p root_shared_dir
(std::basic_string<char, std::char_traits<char>, std::allocator<char> >) $0 = "/tmp/boost_interprocess"

and the problem is that /tmp/boost_interprocess is owned by root

$ ls -al /tmp/boost_interprocess
total 0
drwxrwxrwx   2 root  wheel   64 Jun 21 02:12 .
drwxrwxrwt  21 root  wheel  672 Jun 21 14:27 ..

A work-around is to delete this directory; this requires admim / root access, which for me involved

$ su <admin account>
Password:
% sudo rm -rf /tmp/boost_interprocess
  1. Maybe there is a way to customize the directory uses to create the shared memory file?
  2. The current error message could be improved to report a more informative error
  3. The advice You must manually initial the package via <initialSharedObjectPackageData()> is not feasible because the package cannot be loaded; one could wrap the initial command with tryCatch():
    SharedObject master$ git diff
    diff --git a/R/zzz.R b/R/zzz.R
    index 6480750..aee17cf 100644
    --- a/R/zzz.R
    +++ b/R/zzz.R
    @@ -15,5 +15,7 @@ NULL
             C_setAltrepPrint(FALSE)
             C_setPackagePrint(TRUE)
         }
    -    initialSharedObjectPackageData()
    +    tryCatch({
    +        initialSharedObjectPackageData()
    +    }, error = warning)
     }
    
  4. There is a typo occured instead of occurred in the error message, and the same phrase is repeated twice. error: An error has occured in initializing shared memory object: An error has occured in allocating shared memory: Operation not permitted

For what it's worth the same problem occurs in BiocParallel and motivated the change to cpp11 -- Bioconductor/BiocParallel#202

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions