[CRIU] [PATCH 22/23] zdtm/grow_map: fix test failure for clang

Kir Kolyshkin kir at openvz.org
Tue Oct 11 18:47:00 PDT 2016


When this code is compiled by clang, it optimizes two byte writes into
one word write, like this:

>        fake_grow_down[0] = 'c';
>        *(fake_grow_down - 1) = 'b';
> 401b60:       66 41 c7 46 ff 62 63    movw   $0x6362,-0x1(%r14)

This is incorrect, as the stack is supposed to grow page by page,
so we need to touch one page then another, i.e. the order is important.

To fix, let's use volatile pointer. After this change, the following
(correct) code is generated:

>        *p-- = 'c';
>   401b60:       41 c6 06 63             movb   $0x63,(%r14)
>        *p = 'b';
>   401b64:       41 c6 46 ff 62          movb   $0x62,-0x1(%r14)

[v2: same fix for another similar place]

Cc: Andrei Vagin <avagin at virtuozzo.com>
Signed-off-by: Kir Kolyshkin <kir at openvz.org>
---
 test/zdtm/static/grow_map.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/test/zdtm/static/grow_map.c b/test/zdtm/static/grow_map.c
index c26cfc8..dd1dffd 100644
--- a/test/zdtm/static/grow_map.c
+++ b/test/zdtm/static/grow_map.c
@@ -11,6 +11,7 @@ const char *test_author	= "Andrew Vagin <avagin at openvz.org>";
 int main(int argc, char **argv)
 {
 	char *start_addr, *fake_grow_down, *test_addr, *grow_down;
+	volatile char *p;
 	test_init(argc, argv);
 
 	start_addr = mmap(NULL, PAGE_SIZE * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
@@ -28,8 +29,9 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	fake_grow_down[0] = 'c';
-	*(fake_grow_down - 1) = 'b';
+	p = fake_grow_down;
+	*p-- = 'c';
+	*p = 'b';
 
 	/* overlap the guard page of fake_grow_down */
 	test_addr = mmap(start_addr + PAGE_SIZE * 3, PAGE_SIZE,
@@ -57,8 +59,9 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	grow_down[0] = 'z';
-	*(grow_down - 1) = 'x';
+	p = grow_down;
+	*p-- = 'z';
+	*p = 'x';
 
 	pass();
 
-- 
2.7.4



More information about the CRIU mailing list