Prevent child process writing shared memory? - linux

My process makes a shared memory section as runtime stack(Co's stack run on the shared memory). Thus my process can restore the runtime in case it core dump.
But I meet a problem. I don't want child-process to write anything to stack memory which is actually the super-process's stack after a fork. I knew I just need to make the memory copy-on-write to the child process. So I must declare this shared memory to private, but this makes changes to it from super-process lost after a core dump restart.
Is there any mechanism in Linux that makes a shared memory does not inherit to the child process, but only to that process explicit attach to it? Maybe a mmap flag? or a system call to override the copy-on-write configuration to a specific memory section?
Thanks.

Related

linux: munmap shared memory in on single call

If a process calls mmap(...,MAP_ANONYMOUS | MAP_SHARED,...) and forks N children, is it possible for any one of these processes (parent or descendants) to munmap() the memory for all processes in one go, thus releasing the physical memory, or does every of these processes have to munmap() individually?
(I know the memory will be unmapped on process exit, but the children won't exit yet).
Alternatively, is there a way to munmap memory from another process? I'm thinking of a call something like munmap(pid,...).
Or is there a way to achieve what I am looking for using non-anonymous mappings and performing an operation on the related file descriptor (e.g closing the file)?
My processes are performance sensitive, and I would like to avoid performing lots of IPC when it becomes known that the shared memory will no longer be used by anyone.
No, there is no way to unmap memory in one go.
If you don't need mapped memory in child processes at all, you may mark mappings with madvise(MADV_DONTFORK) before forking.
In emergency situations, you may invoke syscalls from inside external processes by using gdb:
Figure out PID of target process
List mapped memory with cat /proc/<PID>/maps
Attach to process using gdb: gdb -p <PID> (it will suspend execution of target process)
Run from gdb: call munmap(0x<address>, 0x<size>) for each region you need to unmap
Exit gdb (execution of process is resumed)
It must be obvious that if your process tries to access unmapped memory, it will receive SIGSEGV. So, you must be 100% sure what you are doing.

How to avoid shared memory leaks

I'm using shared memory between 2 processes on Suse Linux and I'm wondering how can I avoid the shared memory leaks in case one process crashes or both. Does a leak occur in this case? If yes, how can I avoid it?
You could allocate space for two counters in the shared memory region: one for each process. Every few seconds, each process increments its counter, and checks that the other counter has been incremented as well. That makes it easy for these two processes, or an external watchdog, to tear down the shared memory if somebody crashes or exits.
If the subprocess is a simple fork() from the parent process, then mmap() with MAP_SHARED should work.
If the subprocess does an exec() to start a different executable, you can often pass file descriptors from shm_open() or a similar non-portable system call (see Is there anything like shm_open() without filename?) On many operating systems, including Linux, you can shm_unlink() the file descriptor from shm_open() so it doesn't leak memory when your processes die, and use fcntl() to clear the close-on-exec flag on the shm file descriptor so that your child process can inherit it across exec. This is not well defined in the POSIX standard but it appears to be very portable in practice.
If you need to use a filename instead of just a file descriptor number to pass the shared memory object to an unrelated process, then you have to figure out some way to shm_unlink() the file yourself when it's no longer needed; see John Zwinck's answer for one method.

where thread is implemented in memory?

We know that thread has its own stack it's implemented within the process. But my question is that when thread is implemented in his own stack that time it is the same stack which used by process or any other function?
One more doubt that thread share it's global variable,file descriptor, signal handler etc. But how it's share all these parameters within same address where all the threads executed?
Brief explanation will be appreciated.
when thread is implemented in his own stack that time it is the same stack which used by process or any other?
Can't quite parse this but I get the gist I think.
In most cases, under Linux in a multithreaded application, all of the threads share the same address space. Each thread if it is running on a separate processor may have local cached memory but the overall address space is shared by all threads. Even per-thread stack space is shared by all threads -- just that each thread gets a different contiguous memory area.
But how it's share all these parameters within same address?
This is also true of the global variables, file descriptors, etc.. They are all shared.
Most thread implementations running under Linux use the clone(2) syscall to create new thread processes. To quote from the clone man page:
clone() creates a new process, in a manner similar to fork(2). It is actually a library function layered on top of the underlying clone() system call, hereinafter referred to as sys_clone. A description of sys_clone is given toward the end of this page.
Unlike fork(2), these calls allow the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and the table of signal handlers.
You can see the cloned processes by using ps -eLf under Linux.

Should we detach shared memory before termination of a forked process

Suppose we have requested shared memory and attached it to the main process of our program.
This program creates several processes.
As the manual of shmat says
After a fork(2) the child inherits the attached shared memory segments.
So we don't have to attach the shared memory to the child processes.
But what about detaching it? Should we do it at the child's code as well?
Or just detaching the shared memory at the main process and destroying it is enough?
It really depends on what you are doing after. But if you are calling execve or one of its cousins, it will detach the shared memory segments.

Is it possible that a child process can modify memory in the parent?

This is twilight zone stuff. We bumped into this on Ubuntu. It looks like errno in a parent process was modified by its child process. We see this in code that is executed before main, in a constructor for a shared library.
Is this even possible? Has anyone seen anything like this?
If errno is in a vdso, could it be that those pages aren't mapped to the child until main is ready to start? That seems crazy.
Is it possible that a child process can modify memory in the parent?
Only if it comes from a vfork() or a clone() call with CLONE_VM (not from a fork() call), or if that memory is shared memory (mmap()ed MAP_SHARED memory counts as shared memory).

Resources