Bug 203105 - Wrong description of CLONE_CHILD_SETTID
Summary: Wrong description of CLONE_CHILD_SETTID
Status: RESOLVED CODE_FIX
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P1 low
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-03-29 19:40 UTC by Jakub Nowak
Modified: 2019-04-15 12:17 UTC (History)
3 users (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Jakub Nowak 2019-03-29 19:40:59 UTC
The description of flag CLONE_CHILD_SETTID in clone(2) says "The store operation completes before clone() returns control to user space". This statement is wrong.

Currently, the store operation is performed when the child thread starts, i.e. the store operation completes before clone() returns control in the cloned process context.

The current behaviour of CLONE_CHILD_SETTID flag can be seen with this C code:


#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

volatile pid_t ctid = 0;

int child_fn(void * arg)
{
	sleep(1);
	printf("child, ctid: %d\n", ctid);
	sleep(2);
	return 0;
}

int main(void)
{
	void * stack = NULL;
	stack = malloc(0x1000);
	clone(child_fn, stack + 0x1000 - 0x8, CLONE_VM | CLONE_CHILD_SETTID,
			NULL, NULL, NULL, &ctid);
	printf("parent, ctid: %d\n", ctid);
	sleep(2);
	printf("parent, ctid: %d\n", ctid);
	return 0;
}


It should print:
0: 0
1: 24379
2: 24379

Of course, the number 24379 will be different in each case.


It might be worth mentioning that the description of CLONE_PARENT_SETTID is in fact correct.
Comment 1 Michael Kerrisk 2019-04-12 16:17:28 UTC
Jakub,

I'm not quite sure if I understand your report. The manual page text says:

       CLONE_CHILD_SETTID (since Linux 2.5.49)
              Store the child thread ID  at  the  location  ctid  in  the
              child's  memory.   The  store  operation  completes  before
              clone() returns control to user space.

I don't see what part of your report or your sample program contradicts that. Could you say a bit more please?

Thanks,

Michael
Comment 2 Jakub Nowak 2019-04-12 23:37:14 UTC
Michael,

Sorry, English is not my native language. I'll try to describe it better.


I've made a mistake when I've said what the program prints, it should be:

parent, ctid: 0
child, ctid: 24379
parent, ctid: 24379

where 24379 is a tid of the child.


The sentence "The store operation completes before clone() returns control to user space" from manual page isn't correct.

As can be seen in this example program, the ctid value printed _right after_ returning from clone() is 0.
The manual page says that it should be set before clone() returns, but it's not.

It then prints non-zero value after the sleep. This shows that the value isn't set before clone() returns but rather later on, after some time.


Thank you for your patience,

Jakub
Comment 3 Michael Kerrisk 2019-04-14 17:36:57 UTC
Hello Jakub,

Okay, now I understand what you meant to say. (Perhaps I should have worked it out to begin with!)

The text of the page says:

       CLONE_CHILD_SETTID (since Linux 2.5.49)
              Store the child thread ID  at  the  location  ctid  in  the
              child's  memory.   The  store  operation  completes  before
              clone() returns control to user space.

When I read that text, then because the first sentence meantipns the child's memory, I naturally read the second sentence as implying *before clone() returns in the child*. But I also that other's might not take that implication, so I changed the text to read:

       CLONE_CHILD_SETTID (since Linux 2.5.49)
              Store the child thread ID  at  the  location  ctid  in  the
              child's  memory.   The  store  operation  completes  before
              clone() returns control to user space in the child process.


Thanks,

Michael
Comment 4 Michael Kerrisk 2019-04-15 12:17:32 UTC
So, I revisited this, and realized that I wrote the sentence against which you reported the bug. I hope that I was at that time thinking what I said in comment 3!

However, I think it does not hurt to say even more in the manual page, so I amended it further to say:

              Store the child thread ID  at  the  location  ctid  in  the
              child's  memory.   The  store  operation  completes  before
              clone() returns control to user space in the child process.
              (Note  that  the  store  operation  may  not have completed
              before clone() returns in the parent process, which will be
              relevant if the CLONE_VM flag is also employed.)

Note You need to log in before you can comment on or make changes to this bug.