malloc difference causes refstring test to fail on FreeBSD
$ ~/gnome/source/meson/meson.py test -v refstring
ninja: Entering directory `/tmp/ram/glib-build'
ninja: no work to do.
/refstring/base: OK
/refstring/length: OK
/refstring/length-auto: OK
/refstring/length-nuls: OK
/refstring/intern: **
GLib:ERROR:../../../home/lantw44/gnome/source/glib/glib/tests/refstring.c:104:test_refstring_intern: 's == p' should be FALSE
1/1 glib:glib / refstring FAIL 0.02 s (killed by signal 6 SIGABRT)
OK: 0
FAIL: 1
SKIP: 0
TIMEOUT: 0
The test fails here is in test_refstring_intern
, and it can be understood as the following steps:
- Allocate the first string.
- Allocate the second string.
- Free the second string.
- Free the first string.
- Allocate the third string.
- The third string must not have the same address as the first string.
This assumption isn't always true. Since both spaces used to hold the first and the second string are freed, malloc
can allocate the third string at the location used to hold the first string. If it happens, the test fails.
It can be worked around by allocating an unused string before allocating the third string. FreeBSD malloc
will put the unused string at the location of the first string, so the third string must be allocated at a different address.
diff --git a/glib/tests/refstring.c b/glib/tests/refstring.c
index 41ab0c05c..5dc5085d7 100644
--- a/glib/tests/refstring.c
+++ b/glib/tests/refstring.c
@@ -77,7 +77,7 @@ static void
test_refstring_intern (void)
{
char *s = g_ref_string_new_intern ("hello, world");
- char *p;
+ char *p, *q;
g_test_message ("s = '%s' (%p)", s, s);
g_assert_cmpstr (s, ==, "hello, world");
@@ -99,10 +99,15 @@ test_refstring_intern (void)
g_test_message ("releasing s[%p] ('%s')", s, s);
g_ref_string_release (s);
+ q = g_ref_string_new_intern ("hi, world");
+ g_test_message ("q = '%s' (%p)", q, q);
+
p = g_ref_string_new_intern ("hello, world");
g_test_message ("p[%p] ('%s') != s[%p]", p, p, s);
g_assert_false (s == p);
g_ref_string_release (p);
+
+ g_ref_string_release (q);
}
int
I call it a workaround instead of a fix because it is still not guaranteed to work. If there is a malloc
implementation allocating the unused string at the location of the second string, the location of the first string will still be free and it will be possible for malloc
to reuse it for the third string.
I tagged @ebassi here because this test is written by him.