[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
explicit_bzero test: Fix test failure due to GCC optimizations
From: |
Bruno Haible |
Subject: |
explicit_bzero test: Fix test failure due to GCC optimizations |
Date: |
Sun, 29 Aug 2021 19:03:55 +0200 |
The explicit_bzero test (which needs to do things that are outside of the C
standard) fails in different circumstances, due to GCC optimizations:
1) On x86_64, with GCC 11 and option -O3,
as well as on m68k with GCC 10 and option -O3, the compiler creates
two simplified copies of the function do_secret_stuff, one for pass==1,
and one for pass!=1. The stack allocation of both simplified copies is
different.
The fix is to have a static variable communicate the address of stackbuf
from the first invocation (pass==1) to the second invocation (pass==2).
2) On m68k with GCC 10 and option -O2, the compiler generates code for
do_secret_stuff (1);
count += do_secret_stuff (2);
that cleans up the stack only after the second statement. This is
possible because m68k has a small stack alignment. But the consequence
is that the stack pointer in the two calls is different; this makes the
test fail.
The fix is to convince the compiler to use the stack pointer in both cases.
2021-08-29 Bruno Haible <bruno@clisp.org>
explicit_bzero test: Fix test failure due to GCC optimizations.
* tests/test-explicit_bzero.c (do_secret_stuff): Use static variable
'last_stackbuf'.
(main): Use an 'if' to combine the two do_secret_stuff invocations.
diff --git a/tests/test-explicit_bzero.c b/tests/test-explicit_bzero.c
index 14f0ead2b..15a252698 100644
--- a/tests/test-explicit_bzero.c
+++ b/tests/test-explicit_bzero.c
@@ -139,16 +139,22 @@ test_heap (void)
static int _GL_ATTRIBUTE_NOINLINE
do_secret_stuff (volatile int pass)
{
+ static char *last_stackbuf;
char stackbuf[SECRET_SIZE];
if (pass == 1)
{
memcpy (stackbuf, SECRET, SECRET_SIZE);
explicit_bzero (stackbuf, SECRET_SIZE);
+ last_stackbuf = stackbuf;
return 0;
}
else /* pass == 2 */
{
- return memcmp (zero, stackbuf, SECRET_SIZE) != 0;
+ /* Use last_stackbuf here, because stackbuf may be allocated at a
+ different address than last_stackbuf. This can happen
+ when the compiler splits this function into different functions,
+ one for pass == 1 and one for pass != 1. */
+ return memcmp (zero, last_stackbuf, SECRET_SIZE) != 0;
}
}
@@ -158,10 +164,17 @@ test_stack (void)
int count = 0;
int repeat;
- for (repeat = 1000; repeat > 0; repeat--)
+ for (repeat = 2 * 1000; repeat > 0; repeat--)
{
- do_secret_stuff (1);
- count += do_secret_stuff (2);
+ /* This odd way of writing two consecutive statements
+ do_secret_stuff (1);
+ count += do_secret_stuff (2);
+ ensures that the two do_secret_stuff calls are performed with the same
+ stack pointer value, on m68k. */
+ if ((repeat % 2) == 0)
+ do_secret_stuff (1);
+ else
+ count += do_secret_stuff (2);
}
/* If explicit_bzero works, count is near 0. (It may be > 0 if there were
some asynchronous signal invocations between the two calls of
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- explicit_bzero test: Fix test failure due to GCC optimizations,
Bruno Haible <=