process_shared
process_shared copied to clipboard
arm - error in mmap (Errno::EINVAL)
Hi,
I'm trying to use process_shared but fails crashing everything.
I thinks it's because /dev/mem doesn't work same way.
Output when trying to use just ProcessShared::SharedMemory.new(1024):
~/.gem/ruby/2.1.0/gems/process_shared-0.2.0/lib/process_shared/posix/errno.rb:28:in block (2 levels) in error_check': Invalid argument - error in mmap (Errno::EINVAL) from ~/.gem/ruby/2.1.0/gems/process_shared-0.2.0/lib/process_shared/posix/shared_memory.rb:62:ininitialize'
@JustDevZero Hm, I don't have an arm system on which to test...
The manpage for mmap(2) says EINVAL can be due to any of the following:
EINVAL We don't like addr, length, or offset (e.g., they are too large,
or not aligned on a page boundary).
EINVAL (since Linux 2.6.12) length was 0.
EINVAL flags contained neither MAP_PRIVATE or MAP_SHARED, or contained
both of these values.
Length isn't 0, and the flags should be MAP_SHARED (barring strange errors in the helper.so library). That leaves the first option. addr is nil (means, let the kernel pick something), and offset is zero. The only remaining variable is size. Have you tried various sizes? Something like this brute force method may or may not provide a clue:
#!/bin/bash
for size in {1..4096}; do
ruby -e "require 'process_shared'; begin; ProcessShared::SharedMemory.new($size); warn 'success: $size'; rescue; warn 'err: $size'; end;"
done
If it isn't that, I don't have any ideas at the moment.
Sorry for replying so late, every single step in the brute force answered "err", followed by the number, no success at all :(
I tried to figure out what is failing but I'm not able.
@JustDevZero are you able to test a small C program? I believe it does the exact same steps as the ruby code in proces_shared.
Compile and run with:
gcc shm.c -lrt -o shm && ./shm
shm.c:
#include <fcntl.h> /* O_* constants */
#include <stdio.h> /* printf, perror */
#include <stdlib.h> /* exit */
#include <sys/mman.h> /* shm_open, shm_unlink, mmap */
#include <sys/stat.h> /* mode constants */
#include <unistd.h> /* ftruncate */
#include <sys/types.h>
void
fatal(const char * msg)
{
perror(msg);
exit(1);
}
int
main()
{
const char * name = "/shm-test-for_process_shared";
const int size = 256;
int fd;
void * mem;
fd = shm_open(name, O_CREAT | O_RDWR | O_EXCL, 0777);
if (fd < 0) fatal("shm_open");
if (shm_unlink(name) < 0) fatal("shm_unlink");
if (ftruncate(fd, size) < 0) fatal("ftruncate");
mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mem == MAP_FAILED) fatal("mmap");
printf("successfully mmap'ed a shared memory segment.\n");
return 0;
}
@JustDevZero Forgot to mention, if the above fails, I maybe have an easier time finding out what I'm doing wrong, or what's different about arm.
Surething...
Now I'm pretty lost.
As for this test It seems everything is ok...
[zero@localhost Projects]$ gcc shm.c -lrt -o shm && ./shm successfully mmap'ed a shared memory segment.
:/ I'm kinda lost now
@JustDevZero Interesting. I guess that means the ruby code doesn't do quite what I think it does. The output of strace from both C and ruby versions could be enlightening. What sort of arm machine are you running on? Any ideas on how I can get my hands on something similar? QEMU? I'm trying out this cloud provider with arm servers, but I cannot reproduce the problem: I just get segfaults making any ffi call...