pstree: workaround stupidity of modern compilers

Submitted by Andrei Vagin on May 10, 2016, 12:32 a.m.

Details

Message ID 1462840378-16502-1-git-send-email-avagin@openvz.org
State Accepted
Series "pstree: workaround stupidity of modern compilers"
Commit 086347d89d77c01364b69c41d64c45eb4c8024f0
Headers show

Commit Message

Andrei Vagin May 10, 2016, 12:32 a.m.
From: Andrew Vagin <avagin@virtuozzo.com>

gcc v6.0  and clang think that &next->pid.node can't be null.

Here is an explanation from a kernel log (v3.12-5097-g1310a5a):
"""
the result of this expression is not defined by a C standard
and some gcc versions (e.g.  4.3.4) assume the above expression can never
be equal to NULL.  The net result is an oops because the iteration is not
properly terminated.
"""

$ gcc -v
gcc version 6.0.0 20160406 (Red Hat 6.0.0-0.20) (GCC)
$ python test/zdtm.py run  -t zdtm/static/session00
...
$ gdb -c /tmp/core.61 criu/criu
Program terminated with signal SIGSEGV, Segmentation fault.
598			if (&next->pid.node == NULL || next->pid.virt > pid)

$ make CC=clang
pstree.c:598:18: error: comparison of address of 'next->pid.node' equal to a null pointer is always false [-Werror,-Wtautological-pointer-compare]
                if (&next->pid.node == NULL || next->pid.virt > pid)

Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
---
 criu/pstree.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/pstree.c b/criu/pstree.c
index 408ce2b..a03321e 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -590,12 +590,17 @@  static int get_free_pid()
 		prev = rb_entry(rb_first(&pid_root_rb), struct pstree_item, pid.node);
 
 	while (1) {
+		struct rb_node *node;
 		pid_t pid;
+
 		pid = prev->pid.virt + 1;
 		pid = pid < RESERVED_PIDS ? RESERVED_PIDS + 1 : pid;
 
-		next = rb_entry(rb_next(&prev->pid.node), struct pstree_item, pid.node);
-		if (&next->pid.node == NULL || next->pid.virt > pid)
+		node = rb_next(&prev->pid.node);
+		if (node == NULL)
+			return pid;
+		next = rb_entry(node, struct pstree_item, pid.node);
+		if (next->pid.virt > pid)
 			return pid;
 		prev = next;
 	}

Comments

Cyrill Gorcunov May 10, 2016, 6:07 a.m.
On Tue, May 10, 2016 at 03:32:58AM +0300, Andrey Vagin wrote:
> From: Andrew Vagin <avagin@virtuozzo.com>
> 
> gcc v6.0  and clang think that &next->pid.node can't be null.
> 
> Here is an explanation from a kernel log (v3.12-5097-g1310a5a):
> """
> the result of this expression is not defined by a C standard
> and some gcc versions (e.g.  4.3.4) assume the above expression can never
> be equal to NULL.  The net result is an oops because the iteration is not
> properly terminated.
> """
> 
> $ gcc -v
> gcc version 6.0.0 20160406 (Red Hat 6.0.0-0.20) (GCC)
> $ python test/zdtm.py run  -t zdtm/static/session00
> ...
> $ gdb -c /tmp/core.61 criu/criu
> Program terminated with signal SIGSEGV, Segmentation fault.
> 598			if (&next->pid.node == NULL || next->pid.virt > pid)
> 
> $ make CC=clang
> pstree.c:598:18: error: comparison of address of 'next->pid.node' equal to a null pointer is always false [-Werror,-Wtautological-pointer-compare]
>                 if (&next->pid.node == NULL || next->pid.virt > pid)
> 
> Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
Pavel Emelianov May 11, 2016, 12:40 p.m.
Applied