Linux shared memory question

If a program creates a shared memory segment (using shmget(), shmat(), etc) is there an easy way from a command prompt to list shared memory segments by name, and also is there any easy way to view the contents of these segments?

The ipcs command is what you want. I believe the -m flag will report on all existing shared memory segments.

ipcs -m only seems to list the segments out by their ID. Am I missing something?

Here’s what I’m getting at. I have a host computer sending commands to a linux box over ethernet. One of those commands is to create a region, and another command sends data to be put into that region.

So I create a region doing something like this:

config_key=ftok("/usr/test.region", CONFIG_KEY_ID);
config_id=shmget(config_key, size, IPC_CREAT);

(the size is passed in from the command)

Right now I’m only creating one region just to test all of this out, and since the region is passed data in chunks, I want to look at the region on the linux box to find out if it all of the chunks ended up in the right place. I’m going to end up with a lot of different regions, so it would be nice if I could list out the regions with something showing the name that I passed (test.region). Unless I’m missing something (which is entirely possible), ipcs -m only shows the id that I get back from the shmget call.

If I could somehow examine and possibly edit the region with a hex editor that would be really beneficial. Do regions show up as a file kinda thing anywhere in the file system?

As far as I know, the ftok() call just provides a numeric ID based on the path, and that’s what gets passed to shmget() to generate your segment ID. The numeric key is available in the ipcs -m output, but I don’t think there’s any way to preserve the original pathname of your ftok() without inspecting that memory segment (assuming you put it in there.)

But it’s been about a billion years since I made a SysV IPC call, so my knowledge is pretty rusty.

The memory contents can be viewed and modified externally using gdb to attach to a process using the shared memory or via /dev/mem for the truly brave.

I take it you’re coding this? That is, perhaps you’re not stuck with the use of the shm* functions? Consider using mmap to create a memory mapped file. This will allow you to do the sorts of things you want to do much more easily.

IPC objects get their IDs via two transforms:
filename → key → id
It sounds like you want to reverse these transformations, i.e. determine filename from id. IIRC, whether idkey is even possible with shmctl() depends on what Unix version you use. But keyfilename will certainly be “impossible,” using system calls, for much the same reason that the filename of an open file cannot be determined.

If you know all the filenames that will be used to create these objects, you can maintain your own registry of filename <–> id pairs.

This may be good advice, but might be a detour depending on what stage your project is in.

(Disclaimer: I’ve not used IPC for decades; in fact the only time I attached shmem “in anger” was contracting to a huge Peter-principle team, which had imposed() an anal-retentive layer between application and kernel: One had to call gack_shmget() to use shmget() where gack_ was an interface to ensure only a subset of IPC functionality was retained. :smack: My involvement with that team ended when they bid $1,000,000 to port their application from one Unix system to another! :smack:

    • the interface layer created the maximum number of shmems upon boot to ensure it could not be bypassed. :smack:)

Looks like I will have to keep a master list of memory segments, which is ok I guess. I was hoping for some easier debugging but I can deal with it. No biggie.

I’m concerned about performance. With shared memory, accessing data is just a pointer, which is about as fast as you get. If you want to read and modify data, how much slower is it to do file accesses?

You don’t normally modify a memory mapped file with file system operations, but you can. When you map your file, you get a memory region that corresponds to the contents of the file. Then your app accesses it just like any other memory region, e.g. with pointers. The contents of the file are updated as needed; it’s not the case that every memory update results in an immediate file update. The easiest way to envision it is as if you’ve set up a special paging device, the shared file, for a region of memory.

If a second process maps the same file, you’ve got shared memory. The other nifty thing is that memory can then also be accessed by programs that work with files via the mapped file, which seemed to give you both things you wanted: the ability to use a hex editor or the like and the ability to locate a shared memory region via a file name.

I’ll have to look into that. Thanks!

I’m going to have to correct myself. I just realized that while I was certain that the use of mmap meant that memory modifications end up in the mapped file, I was not certain of the reverse, and the man page is silent about it.

So I wrote a test program, and it turns out that modifications to the file don’t affect memory. So you can use file I/O on the mapped file to view the shared memory contents, but not to modify them. My mistake.