Click to See Complete Forum and Search --> : someone help explain fork() and exec()


gamblor01
09-09-2004, 02:09 AM
So I'm a little confused about what exactly is going on when processes are created. So I have a parent process and it's going to call fork and spawn a child. Then the child's address space is going to be initialized and the code, data, stack, etc. segments are copied to the child, so that immediately after fork is finished...they'll contain the exact same thing. Now, then the return value comes in, and the parent process gets the PID of the child, the child gets zero. Now the child runs it's stuff, and so the code would look something like this:


// currently in the parent process

main()

// code here

int pid = fork(); // create some child process

if (pid == 0) // we're a child
{
exec (argc, argv0, argv1, etc.)
}
else
{
// parent process continues here, maybe waits
}


I guess what I really don't understand is this. Fork copies the code, data, and stack segments from the parent process. The code segment is read only. If the code segment is copied and is read only, and fork is what spawns new processes, how are new programs initialized?

Let's say we have init running xfs, pdflush, login, etc. Now login has BASH as a child. Now BASH has smbd as a child. Init can't possibly preempt all possible programs that could ever and will ever be written and neither can BASH or any process. This must be where exec comes into play, and calls the newly written program??? ...so a process is not the same as a program? I mean, I know the notion of a process is really just an abstraction, but I don't get what's going on. The code segment in the address space of process smbd for example, is not the same as the actual code for smbd? Let's say the BASH shell (which is a process yeah?) spawns the smbd child process. So then the smbd process contains the code segment for BASH. So how does the smbd process know to execute the code for smbd? I think that's what exec does...correct me if I'm wrong.

Can anyone please shed some light on this for me? :D

jim mcnamara
09-09-2004, 11:26 AM
Right after the fork, both processes are identical - they are almost complete clones.

There is one important exception - fork() returns a zero to the child process. It returns the pid of the child process to the parent. This is how you know 'who' you are after a fork.

exec*() fires up an executable image (or a shell which is also an image),
this initalizes everything.

bwkaz
09-09-2004, 07:28 PM
Originally posted by gamblor01
I guess what I really don't understand is this. Fork copies the code, data, and stack segments from the parent process. The code segment is read only. If the code segment is copied and is read only, and fork is what spawns new processes, how are new programs initialized? 1) Linux does not use segments. It creates one huge code segment, and one huge data segment, to cover all of memory. Inter-process security is done with paging, not segmentation.

2) Now, it is true that on x86, writing into the code segment (using the code segment descriptor) is impossible. But this only applies to userspace on Linux, because the kernel can use the data segment descriptor to write to the same physical addresses that the code segment maps onto for a particular process. It does this by modifying the page tables so that two linear addresses (one for each segment) map to the same physical address, I believe.

When you call exec*, you actually call into the kernel (that's why it's a syscall ;)). The kernel then creates this alternate set of page tables to allow itself to write to the code segment. It then supplies these changed data pages to /lib/ld-linux.so.2 (the dynamic linker), which loads the program and any libraries that it depends on into those data pages. It also modifies some addresses during the link (to resolve symbols).

Then, I believe ld-linux.so.2 calls back into the kernel to start execution of the program. Alternately, it is possible that it calls your program's main() function directly, I'm not sure.

And of course, there are a ton of other minor niggling details involved in the whole process -- most of which I don't understand either... :D

cybertron
09-09-2004, 09:38 PM
So the simplistic version of what bwkaz said (at least from what I understood from my OS class) is that fork makes an exact copy of the process (except the pid), and then exec essentially replaces everything in the child process with whatever program you tell it to. So how about an example to show what I mean?

Suppose we call the parent process P0, which is all we start out with.

P0 calls fork()
Now we have two processes P0 and P0 with a different pid
The child P0 calls exec(P1)
Now we have P0 and P1, the child P0 has been replaced with P1. Edit: But it's still the same process, just now it contains P1 instead of P0.

Of course, this may be completely incorrect. I'm still not 100% sure that everything I learned in my OS class is accurate. It seemed pretty dumbed-down to me, but then having familiarity with Linux when you're in a class with a whole bunch of Windows users will do that to you:D

GnomeProject
09-10-2004, 12:54 AM
My understanding is...

fork() copies the parent process almost exactly with exception to the PID (a new one is assigned by init I believe) and then it's given a 0 priority number at which time exec() morphs the "clone" of the parent process into the program you want to start and the program starts and is then reassigned a new priority number...yet maintains either it's previous PPID (that of the parent) or of the previous parent process...

Sorry if that doesn't totally sound right...but hey...it's what I know and think is correct.

-Adam

gamblor01
09-10-2004, 09:27 PM
There is one important exception - fork() returns a zero to the child process. It returns the pid of the child process to the parent. This is how you know 'who' you are after a fork.
Yeah I mentioned that both in the text I wrote, and in the code sample. I know that already. Ditto for the rest of you guys that wrote something similar.

exec*() fires up an executable image (or a shell which is also an image)
This what I was looking for more information on as to what exactly is going on.

I figured I could count on bwkaz. I guess I have enough information to go bug my professor with and see if he can help explain it further. Thanks guys.