Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test failure on macOS Sonoma #2540

Open
fxcoudert opened this issue Sep 15, 2023 · 8 comments
Open

Test failure on macOS Sonoma #2540

fxcoudert opened this issue Sep 15, 2023 · 8 comments

Comments

@fxcoudert
Copy link

Hi,

jemalloc 5.3.0 builds on macOS Sonoma (release candidate), but it has a test failure on both Intel and ARM on this macOS version (which we did not see in earlier versions).

  test_alignment_errors:test/integration/aligned_alloc.c:24: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 0
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 9
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 17
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 33
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 129
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 257
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 513
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1025
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2049
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4097
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 8193
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 16385
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 32769
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65537
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 131073
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 262145
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 524289
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1048577
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2097153
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4194305
  test_alignment_errors (non-reentrant): fail
  test_alignment_errors:test/integration/aligned_alloc.c:24: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 0
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 9
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 17
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 33
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 129
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 257
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 513
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1025
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2049
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4097
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 8193
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 16385
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 32769
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65537
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 131073
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 262145
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 524289
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1048577
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2097153
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4194305
  test_alignment_errors (libc-reentrant): fail
  test_alignment_errors:test/integration/aligned_alloc.c:24: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 0
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 9
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 17
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 33
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 129
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 257
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 513
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1025
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2049
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4097
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 8193
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 16385
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 32769
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 65537
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 131073
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 262145
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 524289
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 1048577
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 2097153
  test_alignment_errors:test/integration/aligned_alloc.c:32: Failed assertion: (p != ((void*)0) || get_errno() != 22) == (0) --> true != false: Expected error for invalid alignment 4194305
  test_alignment_errors (arena_new-reentrant): fail
  test_oom_errors:test/integration/aligned_alloc.c:63: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(9223372036854775808, 9223372036854775808)
  test_oom_errors:test/integration/aligned_alloc.c:76: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(4611686018427387904, 13835058055282163713)
  test_oom_errors:test/integration/aligned_alloc.c:88: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(&p, 16, 18446744073709551600)
  test_oom_errors (non-reentrant): fail
  test_oom_errors:test/integration/aligned_alloc.c:63: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(9223372036854775808, 9223372036854775808)
  test_oom_errors:test/integration/aligned_alloc.c:76: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(4611686018427387904, 13835058055282163713)
  test_oom_errors:test/integration/aligned_alloc.c:88: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(&p, 16, 18446744073709551600)
  test_oom_errors (libc-reentrant): fail
  test_oom_errors:test/integration/aligned_alloc.c:63: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(9223372036854775808, 9223372036854775808)
  test_oom_errors:test/integration/aligned_alloc.c:76: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(4611686018427387904, 13835058055282163713)
  test_oom_errors:test/integration/aligned_alloc.c:88: Failed assertion: (p != ((void*)0) || get_errno() != 12) == (0) --> true != false: Expected error for aligned_alloc(&p, 16, 18446744073709551600)
  test_oom_errors (arena_new-reentrant): fail

I would be happy to provide help and debug, given some indications of what to do.

@interwq
Copy link
Member

interwq commented Sep 18, 2023

Thanks for reporting this @fxcoudert . The assert msg is saying that, we expect an invalid alignment to result in failed allocation, which didn't seem to happen. Could you help to check the things below:

  1. is the aligned_alloc in the test actually linked to the jemalloc impl: https://github.com/jemalloc/jemalloc/blob/dev/src/jemalloc.c#L2822, or any chance it got optimized away by the compiler?
  2. (if above didn't catch anything) when the expect_false fails, check the value of returned p and get_errno()

@fxcoudert
Copy link
Author

For the failure at test_alignment_errors:test/integration/aligned_alloc.c:24
p is NULL and get_errno() returns zero.

The test is correctly linked against jemalloc:

$ otool -L ./test/integration/aligned_alloc
./test/integration/aligned_alloc:
	/opt/homebrew/Cellar/jemalloc/5.3.0/lib/libjemalloc.2.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1600.151.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.0.0)

But I am not sure if jemalloc's version is indeed called. How would I check that? Is there a way to get log output?

@interwq
Copy link
Member

interwq commented Sep 27, 2023

To enable logging, you will need to configure with --enable-log, I'd suggesting adding --enable-debug as well. Then invoke that unit test with the MALLOC_CONF env var:

MALLOC_CONF="log:." test/integration/aligned_alloc

the beginning of the output should look like this (note that the alignments are the invalid ones used in the test):

core.malloc.exit: result: 0x7fe31d408140
core.nallocx.exit: result: 8
core.aligned_alloc.entry: alignment: 0, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 9, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 17, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 33, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 65, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 129, size: 1

core.aligned_alloc.exit: result: 0x0
core.aligned_alloc.entry: alignment: 257, size: 1

core.aligned_alloc.exit: result: 0x0

p is NULL and get_errno() returns zero.

So p is NULL as expected, but somehow the errno wasn't set. It's supposed to go down this path:

set_errno(EINVAL);

with a stack trace like this:

(gdb) bt
#0  imalloc_body (sopts=0x7fffffffcf40, dopts=0x7fffffffcf00, tsd=0x7ffff7fe9768)
    at src/jemalloc.c:2671
#1  0x00007ffff761f2e9 in imalloc (sopts=0x7fffffffcf40, dopts=0x7fffffffcf00)
    at src/jemalloc.c:2725
#2  0x00007ffff761f82c in aligned_alloc (alignment=0, size=1) at src/jemalloc.c:2848
#3  0x00000000004011a3 in test_alignment_errors () at test/integration/aligned_alloc.c:22
#4  0x00000000004036fb in p_test_impl (do_malloc_init=true, do_reentrant=true,
    t=0x40116b <test_alignment_errors>, ap=0x7fffffffd260) at test/src/test.c:149
#5  0x00000000004039ae in p_test (t=0x40116b <test_alignment_errors>) at test/src/test.c:200
#6  0x0000000000401957 in main () at test/integration/aligned_alloc.c:152

@fxcoudert
Copy link
Author

I see some calls to jemalloc's aligned_alloc() but not all I think: https://gist.github.com/fxcoudert/148e24b15ad0578e1a11ea235c1b6235

In particular, the ones that fail do not appear to go through jemalloc (unless the logging is badly out-of-sync w.r.t. normal stdout/stderr), if I read the output right.

@interwq
Copy link
Member

interwq commented Sep 27, 2023

@fxcoudert it looks all the invalid ones are not going through jemalloc; I wonder if the new compiler is more aware of the syntax and optimized things away? Can you try adding volatile to both size and p, and see if anything changes?
https://github.com/jemalloc/jemalloc/blob/dev/test/integration/aligned_alloc.c#L17-L18

@fxcoudert
Copy link
Author

  • volatile does not help
  • the test passes if compiled with -O0

I have reduced the test to:

$ cat test/integration/aligned_alloc.c 
#include "test/jemalloc_test.h"

TEST_BEGIN(test_alignment_errors) {
	volatile size_t alignment;
	volatile void *p;

	alignment = 0;
	set_errno(0);
	p = aligned_alloc(alignment, 1);
	expect_false(p != NULL || get_errno() != EINVAL,
	    "Expected error for invalid alignment %zu", alignment);
}
TEST_END

int
main(void) {
	return test(test_alignment_errors);
}

Compiled at -O0 we can see it calls the function:

$ nm ./test/integration/aligned_alloc | grep aligned
                 U _aligned_alloc

but at -O1 or higher, it is not there anymore.

@fxcoudert
Copy link
Author

Reduced:

$ cat test/integration/aligned_alloc.c
#include <stdlib.h>
#include <sys/errno.h>

void test_alignment_errors(void) {
	size_t alignment;
	void *p;

	alignment = 0;
	p = aligned_alloc (alignment, 1);
	if (p != NULL || errno != EINVAL) abort();
}
$ clang -O2 -c -o test/integration/aligned_alloc.o test/integration/aligned_alloc.c && nm test/integration/aligned_alloc.o | grep aligned
$ clang -O0 -c -o test/integration/aligned_alloc.o test/integration/aligned_alloc.c && nm test/integration/aligned_alloc.o | grep aligned
                 U _aligned_alloc

And another variant:

$ cat toto.c 
#include <stdlib.h>
#include <sys/errno.h>

int main(void) {
	size_t alignment;
	void *p;

	alignment = 0;
	p = aligned_alloc (alignment, 1);
	if (p != NULL || errno != EINVAL) abort();
}
$ clang -O0 toto.c && ./a.out
$ clang -O2 toto.c && ./a.out
zsh: abort      ./a.out

I think that is invalid behaviour from the compiler. aligned_alloc called this way should return NULL and set errno.

@fxcoudert
Copy link
Author

Reported to Apple as FB13209585.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@interwq @fxcoudert and others