On Thu, Oct 2, 2008 at 9:08 PM, Manish Katiyar <[EMAIL PROTECTED]> wrote:
> On Thu, Oct 2, 2008 at 3:55 PM, Mitul Modi <[EMAIL PROTECTED]> wrote:
>>
>>
>> On Wed, Oct 1, 2008 at 6:12 PM, srimugunthan dhandapani
>> <[EMAIL PROTECTED]> wrote:
>>>
>>> hi all,
>>> I want to understand how the fork call return 0 in child and 'pid of
>>> child' in the parent.
>>> Presently my (naive)understanding is that the %eax value is stored
>>> differently for the child and the parent.
>>> Both the child and the parent returns from fork to the same instruction
>>> address, but will have different return values according to %eax.
>
> Can someone who reads assembly well decode "ret_from_fork" ??? I tried
> but couldn't understand much........What is that assembly function
> supposed to do ?
>
from kernel/entry_32.S:
ENTRY(ret_from_fork)
CFI_STARTPROC
pushl %eax
CFI_ADJUST_CFA_OFFSET 4
call schedule_tail
GET_THREAD_INFO(%ebp)
popl %eax
CFI_ADJUST_CFA_OFFSET -4
pushl $0x0202 # Reset kernel eflags
CFI_ADJUST_CFA_OFFSET 4
popfl
CFI_ADJUST_CFA_OFFSET -4
jmp syscall_exit
CFI_ENDPROC
END(ret_from_fork)
cannot understand this? neither do i, so this instead (objdump vmlinux):
c1004950 <ret_from_fork>:
c1004950: 50 push %eax
c1004951: e8 69 ff 01 00 call c10248bf <schedule_tail>
c1004956: bd 00 f0 ff ff mov $0xfffff000,%ebp
c100495b: 21 e5 and %esp,%ebp
c100495d: 58 pop %eax
c100495e: 68 02 02 00 00 push $0x202
c1004963: 9d popf
c1004964: e9 45 01 00 00 jmp c1004aae <syscall_exit>
c1004969: 8d 76 00 lea 0x0(%esi),%esi
And schedule_tail():
/**
* schedule_tail - first thing a freshly forked thread must call.
* @prev: the thread we just switched away from.
*/
asmlinkage void schedule_tail(struct task_struct *prev)
__releases(rq->lock)
{
struct rq *rq = this_rq();
finish_task_switch(rq, prev);
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
/* In this case, finish_task_switch does not reenable preemption */
preempt_enable();
#endif
if (current->set_child_tid)
put_user(task_pid_vnr(current),
current->set_child_tid);=========>remembering that the current context
is still the parent context, therefore, put_user() will write task ID
of the parent into the child's process memory space, pointed to by
set_child_tid (which is how the child process can retrieve the parent
process ID inside the child process running in userspace.)
}
Contra with earlier:
put_user(nr, parent_tidptr);====>this is
copying the PID (which is nr) to the userspace memory of parent
process, to keep informed of the PID of child.
So effectively for both parent and child process, they can retrieve
their own PID and PPID in their userspace process memory (surprisingly
for me, not in the kernelspace itself).
--
Regards,
Peter Teoh
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ