Calling a Function in Shared Memory

From: Michael B Allen (mba2000_at_ioplex.com)
Date: 05/15/05


Date: Sun, 15 May 2005 01:15:11 -0400

I have a hashmap in a file that is mmap'd into shared memory when
needed. I use size_t offsets from the beginning of the mapping to track
everything. This has worked great with Linux 2.4. But I just tried 2.6
and I'm getting a segfault.

Two issues have conspired against me to cause this problem. One is
that multiple processes need to access the map concurrently. Two, the
hashmap API hides the hash and compare functions as pointers within the
hashmap structure.

Because a pointer in one process (a function pointer in this case) is not
valid in another I had to copy the function into shared memory. Let me
reiterate that a little. The function of interest is called 'hash_str'. I
can locate this function within it's library with objdump:

 $ objdump -t libmba.so.0.8.32 | grep hash_str
 0000594c g F .text 0000004d hash_str

Now I can dissassemble this like:

 $ objdump --start-address=0x594c --stop-address=0x5999 \
         -d libmba.so.0.8.32

 libmba.so.0.8.32: file format elf32-i386
 
 Disassembly of section .init:
 Disassembly of section .plt:
 Disassembly of section .text:
 
 0000594c <hash_str>:
     594c: 55 push %ebp
     594d: 89 e5 mov %esp,%ebp
     594f: 83 ec 0c sub $0xc,%esp
     5952: c7 45 fc 05 15 00 00 movl $0x1505,0xfffffffc(%ebp)
     5959: 8b 45 08 mov 0x8(%ebp),%eax
     595c: 89 45 f8 mov %eax,0xfffffff8(%ebp)
     595f: 83 7d 0c 00 cmpl $0x0,0xc(%ebp)
     5963: 74 09 je 596e <hash_str+0x22>
     5965: 8b 45 08 mov 0x8(%ebp),%eax
     5968: 03 45 0c add 0xc(%ebp),%eax
     596b: 89 45 f8 mov %eax,0xfffffff8(%ebp)
     596e: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
     5971: 0f b6 00 movzbl (%eax),%eax
     5974: 89 45 f4 mov %eax,0xfffffff4(%ebp)
     5977: 8b 55 f4 mov 0xfffffff4(%ebp),%edx
     597a: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
     597d: ff 00 incl (%eax)
     597f: 85 d2 test %edx,%edx
     5981: 74 11 je 5994 <hash_str+0x48>
     5983: 8b 45 fc mov 0xfffffffc(%ebp),%eax
     5986: c1 e0 05 shl $0x5,%eax
     5989: 03 45 fc add 0xfffffffc(%ebp),%eax
     598c: 03 45 f4 add 0xfffffff4(%ebp),%eax
     598f: 89 45 fc mov %eax,0xfffffffc(%ebp)
     5992: eb da jmp 596e <hash_str+0x22>
     5994: 8b 45 fc mov 0xfffffffc(%ebp),%eax
     5997: c9 leave
     5998: c3 ret
 Disassembly of section .fini:

When the program starts I actually allocate 15 + 0x004d bytes in the
shared memory and memcpy the above function .text section there aligned
on a 16 byte boundry. Yeah, I know this is highly non-portable but I
don't really have a lot of choices.

So when one of the processes calls the hashmap_get function, which needs
to call the hash function, it gets a pointer to the shared memory and
casts it to hash_fn. This much works. I can print the memory at the
pointer just before the segfault and see the above code:

00000: 55 89 e5 83 ec 0c c7 45 fc 05 15 00 00 8b 45 08 |U......E......E.|
00010: 89 45 f8 83 7d 0c 00 74 09 8b 45 08 03 45 0c 89 |.E..}..t..E..E..|
00020: 45 f8 8b 45 f8 0f b6 00 89 45 f4 8b 55 f4 8d 45 |E..E.....E..U..E|
00030: f8 ff 00 85 d2 74 11 8b 45 fc c1 e0 05 03 45 fc |.....t..E.....E.|
00040: 03 45 f4 89 45 fc eb da 8b 45 fc c9 c3 |.E..E....E... |

But when I call the function it segfaults:

Program received signal SIGSEGV, Segmentation fault.
0x007d9b66 in hashmap_get (h=0xb7508188, key=0x804f8a7) at src/hashmap.c:398
398 hs = hf(key, ALADR(al, h->context));
(gdb) bt
#0 0x007d9b66 in hashmap_get (h=0xb7508188, key=0x804f8a7) at src/hashmap.c:398

So I can only conclude that 2.6 does not like executing arbirary code
in a memory mapping like this.

What can I do? Is there a workaround?

Thanks,
Mike



Relevant Pages

  • Re: shared memory malloc library
    ... you need to do all pointer operations in the heap code relative to the ... base adresse which you get when you map in the shared memory. ... just providing an additional parameter to *malloc() and kin. ...
    (comp.lang.c)
  • Re: copying structures in shared memory
    ...     int x ... wise since the term "shared memory" only makes sense when there ... in the process this pointer is coming from. ...
    (comp.lang.c)
  • Re: Shared Memory...Some Questions.....
    ... I'm by no means a shared memory expert... ... /* int ctheSharedIndex; ... shmat returns a pointer ... you are using it to store an int, you need to store the return ...
    (comp.os.linux.development.system)
  • Re: shared memory and dynamic data structures
    ... in a current project I'm using shared memory along with STL containers. ... I've wrote an allocator to serve memory allocations requested by STL ... pointer that just keep an offset into the shared memory region. ...
    (comp.unix.programmer)
  • Re: shared memory and dynamic data structures
    ... in a current project I'm using shared memory along with STL containers. ... I've wrote an allocator to serve memory allocations requested by STL ... pointer that just keep an offset into the shared memory region. ...
    (comp.os.linux.development.system)