child process is of 4 kb size more than the parent process? - fork

If I use fork() system call to create a child process then I use #ps aux command to see the size of the processes, I always see that the child process is of 4 KB more than the parent one!!!
I also want to know how can I know the actual address of any process in RAM not the relative shown in /proc/pid/maps
Thanks in advance
pid = fork();
if( pid == 0)
{
getchar();
execlp("/usr/bin/top", NULL);
}
else
{
wait(&childstatus);
printf("Hello From Parent\n");
}
I run #ps aux when the child process is waiting for getchar().

Kernel employs copy-on-write methods while copying memory from parent's process address space to child's one.
Another thing is that kernel will add about 2kB (on 32-bit system) descriptor to process table on fork.
I also want to know how can I know the actual address of any process in RAM not the relative shown in /proc/pid/maps
Well, this will require some kind of kernel debugger. There was some kdb or kgdb as far as I remember.

I have just realized that this 4 KB extra is because of wait(). If I remove it, both parent and child processes will be of the same size.
But can anyone tell me why does wait() consume more 4 KB extra?

Related

Limiting child process's memory usage with rlimit without affecting current process

I want to limit the memory usage of a child process using rlimit. Currently our code is as follows:
old_rlimit := get_rlimit()
set_rlimit(child_process_rlimit)
cmd.Start()
set_rlimit(old_rlimit)
cmd.Wait()
However, sometimes Golang runtime will report out of memory error at cmd.Start(). It seems that in cmd.Start() current process will allocate some memory, and if current memory usage is higher than child_process_rlimit, an error will be raised.
I want to know is there any way to limit the memory usage of child process without affecting current one?
You need to apply rlimit to the child process only rather than relying on rlimit inheritance. Your main blocker here is clearly spelled out in the setrlimit man page:
an unprivileged process may set only its soft limit to a value in the
range from 0 up to the hard limit, and (irreversibly) lower its hard
limit
The standard way to do this is through fork/exec, something along the lines of:
child_pid := fork()
if pid != 0 {
// in child process
setrlimit(...)
execve(...)
}
If you don't want to do that, you still have a few options:
run as privileged user
cmd.Run a small wrapper (eg: bash ulimit -m ...) that calls the child process. note: -m is not honored by many systems.
call prlimit (linux-specific and no syscall wrapper. see this thread for details)

On fork() in Linux

#include<stdio.h>
int giCtr0;
int main(void){
int iPid;
iPid = fork();
if (iPid == 0){
giCtr0++;
printf("In Child\n");
printf("Addr\t%x Value\t%d\n",&giCtr0,giCtr0);
}
else{
giCtr0+=2;
printf("In Parent\n");
printf("Addr\t%x Value\t%d\n",&giCtr0,giCtr0);
}
return 0;
}
The output from Ubuntu is as follows:
In Parent
Addr 601054 Value 2
In Child
Addr 601054 Value 1
The Value is proper and as expected.
How does address of the variable remain same in child and parent process?
Is there anything wrong in this code? Please suggest.
Memory addresses in a Unix-like VM system are per-process. The address you obtain with the C & operator is an OS-level construct, not the addressing scheme that maps directly to bits in RAM chips (or swapped-out VM pages). Thus, it's possible for the same address in two different processes to refer to two different locations in "real" memory.
fork spawns a clone of the parent process. For both processes to continue operating as they had before the fork, the entire memory image of the parent process is copied to create that of the child process... so, from each process' perspective, the memory addresses of all variables still point to the same things they did before. (But since the processes are now separate, changes in one affect a different underlying storage than is used by the other.)
How does address of the variable remain same in child and parent process?
To add to the comment from mkimball
Linux implements virtual memory. That means it sets up the hardware so each process sees a 'virtual' memory map instead of the 'real'/physical memory map.
Because of this the memory address 0x601054 of one process does not necessarily correspond to the same real memory 'cell' as the same address 0x601054 inside another process.

when using shared memory in unix

When you code a data supplier app in C for Unix that uses shared memory when do you detach the shared memory only when the server exits or when you are finished updating the shared memory ?
AFAIK, keeping it attached will not bother.
However since the attachment tracks the number of processes attached, if that count is >0, then you won't be allowed to destroy your shm until that count get back to 0 (in other words when all process are detached).
If you have a main process attached, I'm not sure you will be able to destroy it from an external "administrative" process for you shm.
In my personnal experience, I don't detach the SHM after write operations, only at process exit.

In the linux kernel, where is the first process initialized?

I'm looking for the code in the linux kernel (2.4.x) that initializes the first process, pid=0.
Many searches provided many clues, but I still cannot find it.
Any pointers, anyone?
The initial task struct is set up by the macro INIT_TASK(), defined in include/linux/init_task.h. All other task structs are created by do_fork.
start_kernel()
check out rest_init() at the end
// idle process, pid = 0
cpu_idle(); // never return
The first process that the kernel initializes is the swapper process or the idle thread. This thread runs forever. When no other process is active in the system, then this thread [which is cpu_idle() function found in arch/arm/kernel/process.c for the ARM architecture] calls the architecture dependent pm_idle function, which power collapses the CPU until a timer interrupt or some other interrupt wakes it up.
The swapper process [pid=0] is initialized in arch/arm/kernel/init_task.c by the macro INIT_TASK.

How to know child process status and resource usage on windows?

I want to write a program, which will launch a child process. The child process may be windows mode or console mode program.
I want to monitor the child process status and resource usage. e.g. I want to know the child process is still running or terminated. If it terminated, I want to know the reason (is terminated normally or because of crash?).
And during the child process running and/or it terminated, I want to know its resource usage, especially CPU time (user time, system) and memory usage (virtual size and/or rss). It is OK if the numbers are not very accurate.
In Unix terminology, I want to fork, exec, waitpid and getrusage . And fork+setrusage+exec can limit child's resource usage. But I don't know how to do these on the Windows platform.
Please point me the Windows API name. I could study the rest myself.
Prefer not using library other than the Windows API. Prefer it is not parent working as debugger and attaching to child process. Just not prefer, but still acceptable.
When you call CreateProcess, it returns a handle to the process.
WaitForSingleObject on a process handle will block until the process has exited or time-out has expired. A timeout of zero will return immediately and indicate if the process is still running.
BOOL IsProcessRunning(HANDLE process)
{
return WaitForSingleObject(process, 0) != WAIT_OBJECT_0;
}
void WaitForProcessToExit(HANDLE process)
{
WaitForSingleObject(process, INFINITE);
}
To get the exit code of a running process, you can use GetExitCodeProcess. You'll need to interpret what the error code means, however. 0xC0000005 is typical for an access violation, but not all crashes result in this error code.
For resource usage, you can call GetProcessTimes to get total CPU time, GetGuiResources to get GDI handle info, GetProcessMemoryInfo to get memory stats, and GetProcessIoCounters to get IO info.

Resources