From dd5437fdffdb2a34ef19879dabfd30ff980771c3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 6 May 2024 11:15:07 +0200 Subject: organize libc tests into a proper folder, and run some of them on Windows --- src/tools/miri/ci/ci.sh | 8 +- .../libc_pthread_cond_double_destroy.rs | 20 + .../libc_pthread_cond_double_destroy.stderr | 15 + .../libc_pthread_condattr_double_destroy.rs | 18 + .../libc_pthread_condattr_double_destroy.stderr | 15 + .../libc_pthread_create_main_terminate.rs | 2 +- .../libc_pthread_create_too_few_args.rs | 2 +- .../libc_pthread_create_too_many_args.rs | 2 +- .../concurrency/libc_pthread_join_detached.rs | 2 +- .../concurrency/libc_pthread_join_joined.rs | 2 +- .../fail-dep/concurrency/libc_pthread_join_main.rs | 2 +- .../concurrency/libc_pthread_join_multiple.rs | 2 +- .../fail-dep/concurrency/libc_pthread_join_self.rs | 2 +- .../libc_pthread_mutex_NULL_deadlock.rs | 12 + .../libc_pthread_mutex_NULL_deadlock.stderr | 15 + .../concurrency/libc_pthread_mutex_deadlock.rs | 29 ++ .../concurrency/libc_pthread_mutex_deadlock.stderr | 32 ++ .../libc_pthread_mutex_default_deadlock.rs | 13 + .../libc_pthread_mutex_default_deadlock.stderr | 15 + .../libc_pthread_mutex_destroy_locked.rs | 15 + .../libc_pthread_mutex_destroy_locked.stderr | 15 + .../libc_pthread_mutex_double_destroy.rs | 21 + .../libc_pthread_mutex_double_destroy.stderr | 15 + .../libc_pthread_mutex_normal_deadlock.rs | 15 + .../libc_pthread_mutex_normal_deadlock.stderr | 13 + .../libc_pthread_mutex_normal_unlock_unlocked.rs | 16 + ...ibc_pthread_mutex_normal_unlock_unlocked.stderr | 15 + .../concurrency/libc_pthread_mutex_wrong_owner.rs | 28 ++ .../libc_pthread_mutex_wrong_owner.stderr | 15 + .../libc_pthread_mutexattr_double_destroy.rs | 17 + .../libc_pthread_mutexattr_double_destroy.stderr | 15 + .../libc_pthread_rwlock_destroy_read_locked.rs | 9 + .../libc_pthread_rwlock_destroy_read_locked.stderr | 15 + .../libc_pthread_rwlock_destroy_write_locked.rs | 9 + ...libc_pthread_rwlock_destroy_write_locked.stderr | 15 + .../libc_pthread_rwlock_double_destroy.rs | 14 + .../libc_pthread_rwlock_double_destroy.stderr | 15 + ...ead_rwlock_read_write_deadlock_single_thread.rs | 9 + ...rwlock_read_write_deadlock_single_thread.stderr | 13 + .../libc_pthread_rwlock_read_wrong_owner.rs | 28 ++ .../libc_pthread_rwlock_read_wrong_owner.stderr | 15 + .../libc_pthread_rwlock_unlock_unlocked.rs | 8 + .../libc_pthread_rwlock_unlock_unlocked.stderr | 15 + .../libc_pthread_rwlock_write_read_deadlock.rs | 29 ++ .../libc_pthread_rwlock_write_read_deadlock.stderr | 32 ++ ...ead_rwlock_write_read_deadlock_single_thread.rs | 9 + ...rwlock_write_read_deadlock_single_thread.stderr | 13 + .../libc_pthread_rwlock_write_write_deadlock.rs | 29 ++ ...libc_pthread_rwlock_write_write_deadlock.stderr | 32 ++ ...ad_rwlock_write_write_deadlock_single_thread.rs | 9 + ...wlock_write_write_deadlock_single_thread.stderr | 13 + .../libc_pthread_rwlock_write_wrong_owner.rs | 28 ++ .../libc_pthread_rwlock_write_wrong_owner.stderr | 15 + .../tests/fail-dep/libc/env-set_var-data-race.rs | 17 + .../fail-dep/libc/env-set_var-data-race.stderr | 20 + .../miri/tests/fail-dep/libc/fs/close_stdout.rs | 10 + .../tests/fail-dep/libc/fs/close_stdout.stderr | 14 + .../miri/tests/fail-dep/libc/fs/isolated_stdin.rs | 9 + .../tests/fail-dep/libc/fs/isolated_stdin.stderr | 15 + .../fail-dep/libc/fs/mkstemp_immutable_arg.rs | 11 + .../fail-dep/libc/fs/mkstemp_immutable_arg.stderr | 20 + .../tests/fail-dep/libc/fs/read_from_stdout.rs | 10 + .../tests/fail-dep/libc/fs/read_from_stdout.stderr | 14 + .../libc/fs/unix_open_missing_required_mode.rs | 12 + .../libc/fs/unix_open_missing_required_mode.stderr | 20 + .../miri/tests/fail-dep/libc/fs/write_to_stdin.rs | 9 + .../tests/fail-dep/libc/fs/write_to_stdin.stderr | 14 + src/tools/miri/tests/fail-dep/libc/memchr_null.rs | 8 + .../miri/tests/fail-dep/libc/memchr_null.stderr | 15 + src/tools/miri/tests/fail-dep/libc/memcmp_null.rs | 8 + .../miri/tests/fail-dep/libc/memcmp_null.stderr | 15 + src/tools/miri/tests/fail-dep/libc/memcmp_zero.rs | 12 + .../miri/tests/fail-dep/libc/memcmp_zero.stderr | 15 + src/tools/miri/tests/fail-dep/libc/memcpy_zero.rs | 11 + .../miri/tests/fail-dep/libc/memcpy_zero.stderr | 15 + src/tools/miri/tests/fail-dep/libc/memrchr_null.rs | 11 + .../miri/tests/fail-dep/libc/memrchr_null.stderr | 15 + .../tests/fail-dep/libc/mmap_invalid_dealloc.rs | 18 + .../fail-dep/libc/mmap_invalid_dealloc.stderr | 15 + .../tests/fail-dep/libc/mmap_use_after_munmap.rs | 19 + .../fail-dep/libc/mmap_use_after_munmap.stderr | 32 ++ .../miri/tests/fail-dep/libc/munmap_partial.rs | 20 + .../miri/tests/fail-dep/libc/munmap_partial.stderr | 15 + src/tools/miri/tests/fail-dep/libc/realloc-zero.rs | 8 + .../miri/tests/fail-dep/libc/realloc-zero.stderr | 15 + .../libc/unsupported_incomplete_function.rs | 11 + .../libc/unsupported_incomplete_function.stderr | 15 + src/tools/miri/tests/fail-dep/realloc-zero.rs | 10 - src/tools/miri/tests/fail-dep/realloc-zero.stderr | 15 - .../tests/fail-dep/shims/env-set_var-data-race.rs | 17 - .../fail-dep/shims/env-set_var-data-race.stderr | 20 - .../miri/tests/fail-dep/shims/fs/close_stdout.rs | 10 - .../tests/fail-dep/shims/fs/close_stdout.stderr | 14 - .../miri/tests/fail-dep/shims/fs/isolated_stdin.rs | 9 - .../tests/fail-dep/shims/fs/isolated_stdin.stderr | 15 - .../fail-dep/shims/fs/mkstemp_immutable_arg.rs | 11 - .../fail-dep/shims/fs/mkstemp_immutable_arg.stderr | 20 - .../tests/fail-dep/shims/fs/read_from_stdout.rs | 10 - .../fail-dep/shims/fs/read_from_stdout.stderr | 14 - .../shims/fs/unix_open_missing_required_mode.rs | 12 - .../fs/unix_open_missing_required_mode.stderr | 20 - .../miri/tests/fail-dep/shims/fs/write_to_stdin.rs | 9 - .../tests/fail-dep/shims/fs/write_to_stdin.stderr | 14 - src/tools/miri/tests/fail-dep/shims/memchr_null.rs | 10 - .../miri/tests/fail-dep/shims/memchr_null.stderr | 15 - src/tools/miri/tests/fail-dep/shims/memcmp_null.rs | 10 - .../miri/tests/fail-dep/shims/memcmp_null.stderr | 15 - src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs | 13 - .../miri/tests/fail-dep/shims/memcmp_zero.stderr | 15 - src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs | 12 - .../miri/tests/fail-dep/shims/memcpy_zero.stderr | 15 - .../miri/tests/fail-dep/shims/memrchr_null.rs | 11 - .../miri/tests/fail-dep/shims/memrchr_null.stderr | 15 - .../tests/fail-dep/shims/mmap_invalid_dealloc.rs | 18 - .../fail-dep/shims/mmap_invalid_dealloc.stderr | 15 - .../tests/fail-dep/shims/mmap_use_after_munmap.rs | 19 - .../fail-dep/shims/mmap_use_after_munmap.stderr | 32 -- .../miri/tests/fail-dep/shims/munmap_partial.rs | 20 - .../tests/fail-dep/shims/munmap_partial.stderr | 15 - .../shims/sync/libc_pthread_cond_double_destroy.rs | 20 - .../sync/libc_pthread_cond_double_destroy.stderr | 15 - .../sync/libc_pthread_condattr_double_destroy.rs | 18 - .../libc_pthread_condattr_double_destroy.stderr | 15 - .../shims/sync/libc_pthread_mutex_NULL_deadlock.rs | 12 - .../sync/libc_pthread_mutex_NULL_deadlock.stderr | 15 - .../shims/sync/libc_pthread_mutex_deadlock.rs | 29 -- .../shims/sync/libc_pthread_mutex_deadlock.stderr | 32 -- .../sync/libc_pthread_mutex_default_deadlock.rs | 13 - .../libc_pthread_mutex_default_deadlock.stderr | 15 - .../sync/libc_pthread_mutex_destroy_locked.rs | 15 - .../sync/libc_pthread_mutex_destroy_locked.stderr | 15 - .../sync/libc_pthread_mutex_double_destroy.rs | 21 - .../sync/libc_pthread_mutex_double_destroy.stderr | 15 - .../sync/libc_pthread_mutex_normal_deadlock.rs | 15 - .../sync/libc_pthread_mutex_normal_deadlock.stderr | 13 - .../libc_pthread_mutex_normal_unlock_unlocked.rs | 16 - ...ibc_pthread_mutex_normal_unlock_unlocked.stderr | 15 - .../shims/sync/libc_pthread_mutex_wrong_owner.rs | 28 -- .../sync/libc_pthread_mutex_wrong_owner.stderr | 15 - .../sync/libc_pthread_mutexattr_double_destroy.rs | 17 - .../libc_pthread_mutexattr_double_destroy.stderr | 15 - .../libc_pthread_rwlock_destroy_read_locked.rs | 9 - .../libc_pthread_rwlock_destroy_read_locked.stderr | 15 - .../libc_pthread_rwlock_destroy_write_locked.rs | 9 - ...libc_pthread_rwlock_destroy_write_locked.stderr | 15 - .../sync/libc_pthread_rwlock_double_destroy.rs | 14 - .../sync/libc_pthread_rwlock_double_destroy.stderr | 15 - ...ead_rwlock_read_write_deadlock_single_thread.rs | 9 - ...rwlock_read_write_deadlock_single_thread.stderr | 13 - .../sync/libc_pthread_rwlock_read_wrong_owner.rs | 28 -- .../libc_pthread_rwlock_read_wrong_owner.stderr | 15 - .../sync/libc_pthread_rwlock_unlock_unlocked.rs | 8 - .../libc_pthread_rwlock_unlock_unlocked.stderr | 15 - .../libc_pthread_rwlock_write_read_deadlock.rs | 29 -- .../libc_pthread_rwlock_write_read_deadlock.stderr | 32 -- ...ead_rwlock_write_read_deadlock_single_thread.rs | 9 - ...rwlock_write_read_deadlock_single_thread.stderr | 13 - .../libc_pthread_rwlock_write_write_deadlock.rs | 29 -- ...libc_pthread_rwlock_write_write_deadlock.stderr | 32 -- ...ad_rwlock_write_write_deadlock_single_thread.rs | 9 - ...wlock_write_write_deadlock_single_thread.stderr | 13 - .../sync/libc_pthread_rwlock_write_wrong_owner.rs | 28 -- .../libc_pthread_rwlock_write_wrong_owner.stderr | 15 - .../fail-dep/unsupported_incomplete_function.rs | 11 - .../unsupported_incomplete_function.stderr | 15 - src/tools/miri/tests/panic/unsupported_syscall.rs | 2 +- src/tools/miri/tests/pass-dep/calloc.rs | 22 -- .../pass-dep/concurrency/env-cleanup-data-race.rs | 22 ++ .../concurrency/libc_pthread_cond_timedwait.rs | 2 +- .../libc_pthread_cond_timedwait_isolated.rs | 2 +- .../pass-dep/concurrency/tls_pthread_drop_order.rs | 2 +- src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs | 2 +- .../tests/pass-dep/libc/fcntl_f-fullfsync_apple.rs | 12 + .../pass-dep/libc/fcntl_f-fullfsync_apple.stderr | 2 + .../tests/pass-dep/libc/libc-fs-with-isolation.rs | 28 ++ .../pass-dep/libc/libc-fs-with-isolation.stderr | 4 + src/tools/miri/tests/pass-dep/libc/libc-fs.rs | 430 +++++++++++++++++++++ src/tools/miri/tests/pass-dep/libc/libc-fs.stderr | 1 + src/tools/miri/tests/pass-dep/libc/libc-fs.stdout | 1 + src/tools/miri/tests/pass-dep/libc/libc-mem.rs | 255 ++++++++++++ src/tools/miri/tests/pass-dep/libc/libc-misc.rs | 68 ++++ src/tools/miri/tests/pass-dep/libc/libc-random.rs | 63 +++ src/tools/miri/tests/pass-dep/libc/libc-time.rs | 93 +++++ src/tools/miri/tests/pass-dep/libc/mmap.rs | 181 +++++++++ src/tools/miri/tests/pass-dep/libc/pthread-sync.rs | 315 +++++++++++++++ .../miri/tests/pass-dep/libc/pthread-threadname.rs | 51 +++ src/tools/miri/tests/pass-dep/malloc.rs | 48 --- .../tests/pass-dep/shims/env-cleanup-data-race.rs | 22 -- .../pass-dep/shims/fcntl_f-fullfsync_apple.rs | 12 - .../pass-dep/shims/fcntl_f-fullfsync_apple.stderr | 2 - .../tests/pass-dep/shims/libc-fs-with-isolation.rs | 28 -- .../pass-dep/shims/libc-fs-with-isolation.stderr | 4 - src/tools/miri/tests/pass-dep/shims/libc-fs.rs | 430 --------------------- src/tools/miri/tests/pass-dep/shims/libc-fs.stderr | 1 - src/tools/miri/tests/pass-dep/shims/libc-fs.stdout | 1 - src/tools/miri/tests/pass-dep/shims/libc-misc.rs | 242 ------------ src/tools/miri/tests/pass-dep/shims/libc-random.rs | 63 --- src/tools/miri/tests/pass-dep/shims/libc-time.rs | 93 ----- src/tools/miri/tests/pass-dep/shims/mmap.rs | 181 --------- .../miri/tests/pass-dep/shims/pthread-sync.rs | 315 --------------- .../tests/pass-dep/shims/pthread-threadname.rs | 51 --- 201 files changed, 2789 insertions(+), 2786 deletions(-) create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs create mode 100644 src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/memchr_null.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/memchr_null.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/memcmp_null.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/memcmp_zero.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/memcpy_zero.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/memrchr_null.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/munmap_partial.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/realloc-zero.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr create mode 100644 src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.rs create mode 100644 src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr delete mode 100644 src/tools/miri/tests/fail-dep/realloc-zero.rs delete mode 100644 src/tools/miri/tests/fail-dep/realloc-zero.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/memchr_null.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/memchr_null.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcmp_null.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/memrchr_null.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/munmap_partial.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs delete mode 100644 src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr delete mode 100644 src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs delete mode 100644 src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr delete mode 100644 src/tools/miri/tests/pass-dep/calloc.rs create mode 100644 src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.stderr create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.stderr create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-fs.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-fs.stderr create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-fs.stdout create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-mem.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-misc.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-random.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/libc-time.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/mmap.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/pthread-sync.rs create mode 100644 src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs delete mode 100644 src/tools/miri/tests/pass-dep/malloc.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.stderr delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-fs.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-fs.stderr delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-fs.stdout delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-misc.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-random.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/libc-time.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/mmap.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/pthread-sync.rs delete mode 100644 src/tools/miri/tests/pass-dep/shims/pthread-threadname.rs (limited to 'src') diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh index d1dcacdfdf5..c28a6f183b3 100755 --- a/src/tools/miri/ci/ci.sh +++ b/src/tools/miri/ci/ci.sh @@ -143,10 +143,10 @@ case $HOST_TARGET in # Partially supported targets (tier 2) VERY_BASIC="integer vec string btreemap" # common things we test on all of them (if they have std), requires no target-specific shims BASIC="$VERY_BASIC hello hashmap alloc align" # ensures we have the shims for stdout and basic data structures - MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-misc libc-random libc-time fs env num_cpus - MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-misc libc-random libc-time fs env num_cpus - MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-misc libc-random - MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-misc libc-random + MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus + MIRI_TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus + MIRI_TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random + MIRI_TEST_TARGET=x86_64-pc-solaris run_tests_minimal $VERY_BASIC hello panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal $VERY_BASIC hello panic/panic MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal $VERY_BASIC wasm MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal $VERY_BASIC wasm diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs new file mode 100644 index 00000000000..f22f17be0df --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.rs @@ -0,0 +1,20 @@ +//@ignore-target-windows: No pthreads on Windows + +/// Test that destroying a pthread_cond twice fails, even without a check for number validity + +fn main() { + unsafe { + use core::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + libc::pthread_condattr_init(attr.as_mut_ptr()); + + let mut cond = MaybeUninit::::uninit(); + + libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()); + + libc::pthread_cond_destroy(cond.as_mut_ptr()); + + libc::pthread_cond_destroy(cond.as_mut_ptr()); + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr new file mode 100644 index 00000000000..899c217efbf --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_cond_double_destroy.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/libc_pthread_cond_double_destroy.rs:LL:CC + | +LL | libc::pthread_cond_destroy(cond.as_mut_ptr()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_cond_double_destroy.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.rs new file mode 100644 index 00000000000..d0ccab4de5b --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.rs @@ -0,0 +1,18 @@ +//@ignore-target-windows: No pthreads on Windows +//@ignore-target-apple: Our macOS condattr don't have any fields so we do not notice this. + +/// Test that destroying a pthread_condattr twice fails, even without a check for number validity + +fn main() { + unsafe { + use core::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + + libc::pthread_condattr_init(attr.as_mut_ptr()); + + libc::pthread_condattr_destroy(attr.as_mut_ptr()); + + libc::pthread_condattr_destroy(attr.as_mut_ptr()); + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr new file mode 100644 index 00000000000..ef75b03162d --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_condattr_double_destroy.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/libc_pthread_condattr_double_destroy.rs:LL:CC + | +LL | libc::pthread_condattr_destroy(attr.as_mut_ptr()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_condattr_double_destroy.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs index 7e6f490bb3d..9cd0a35d36e 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //@error-in-other-file: the main thread terminated without waiting for all remaining threads // Check that we terminate the program when the main thread terminates. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs index e1d3704af7c..96dd99e8844 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //! The thread function must have exactly one argument. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs index 7408634db52..d8fbc68d344 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //! The thread function must have exactly one argument. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs index 0b810dc8c72..e89d7a9f02b 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows // Joining a detached thread is undefined behavior. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs index 04ca4bbb3f6..cbad743ca56 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows // Joining an already joined thread is undefined behavior. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs index 75765182163..002498e6c82 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows // Joining the main thread is undefined behavior. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs index 966f416eeac..f5b687a623f 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows // Joining the same thread from multiple threads is undefined behavior. diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs index 0c25c690f37..4bc1c82a254 100644 --- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows // We are making scheduler assumptions here. //@compile-flags: -Zmiri-preemption-rate=0 diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.rs new file mode 100644 index 00000000000..0a494c53b4b --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.rs @@ -0,0 +1,12 @@ +//@ignore-target-windows: No pthreads on Windows +// +// Check that if we pass NULL attribute, then we get the default mutex type. + +fn main() { + unsafe { + let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, std::ptr::null() as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: Undefined Behavior: trying to acquire already locked default mutex + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.stderr new file mode 100644 index 00000000000..3675ce49f30 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_NULL_deadlock.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: trying to acquire already locked default mutex + --> $DIR/libc_pthread_mutex_NULL_deadlock.rs:LL:CC + | +LL | libc::pthread_mutex_lock(&mut mutex as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to acquire already locked default mutex + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_NULL_deadlock.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs new file mode 100644 index 00000000000..0328115c637 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs @@ -0,0 +1,29 @@ +//@ignore-target-windows: No pthreads on Windows +//@error-in-other-file: deadlock + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct Mutex(UnsafeCell); + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +fn new_lock() -> Arc { + Arc::new(Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_mutex_lock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr new file mode 100644 index 00000000000..987d0fc4c2d --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr @@ -0,0 +1,32 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_mutex_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_mutex_deadlock.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> $DIR/libc_pthread_mutex_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); +LL | | }) +LL | | .join() + | |_______________^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 2 previous errors + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.rs new file mode 100644 index 00000000000..1038b8988f9 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.rs @@ -0,0 +1,13 @@ +//@ignore-target-windows: No pthreads on Windows +// +// Check that if we do not set the mutex type, it is the default. + +fn main() { + unsafe { + let mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); + let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: Undefined Behavior: trying to acquire already locked default mutex + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.stderr new file mode 100644 index 00000000000..4d41141b545 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_default_deadlock.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: trying to acquire already locked default mutex + --> $DIR/libc_pthread_mutex_default_deadlock.rs:LL:CC + | +LL | libc::pthread_mutex_lock(&mut mutex as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to acquire already locked default mutex + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_default_deadlock.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.rs new file mode 100644 index 00000000000..e474712cfd9 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.rs @@ -0,0 +1,15 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + unsafe { + let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); + assert_eq!( + libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), + 0, + ); + let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + libc::pthread_mutex_destroy(&mut mutex as *mut _); //~ ERROR: destroyed a locked mutex + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr new file mode 100644 index 00000000000..ed5e27b607a --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_destroy_locked.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: destroyed a locked mutex + --> $DIR/libc_pthread_mutex_destroy_locked.rs:LL:CC + | +LL | libc::pthread_mutex_destroy(&mut mutex as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked mutex + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_destroy_locked.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs new file mode 100644 index 00000000000..46f0c5f8d72 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.rs @@ -0,0 +1,21 @@ +//@ignore-target-windows: No pthreads on Windows + +/// Test that destroying a pthread_mutex twice fails, even without a check for number validity + +fn main() { + unsafe { + use core::mem::MaybeUninit; + + let mut attr = MaybeUninit::::uninit(); + libc::pthread_mutexattr_init(attr.as_mut_ptr()); + + let mut mutex = MaybeUninit::::uninit(); + + libc::pthread_mutex_init(mutex.as_mut_ptr(), attr.as_ptr()); + + libc::pthread_mutex_destroy(mutex.as_mut_ptr()); + + libc::pthread_mutex_destroy(mutex.as_mut_ptr()); + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr new file mode 100644 index 00000000000..05b35ee3b30 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_double_destroy.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/libc_pthread_mutex_double_destroy.rs:LL:CC + | +LL | libc::pthread_mutex_destroy(mutex.as_mut_ptr()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_double_destroy.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.rs new file mode 100644 index 00000000000..f311934e28b --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.rs @@ -0,0 +1,15 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + unsafe { + let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); + assert_eq!( + libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), + 0, + ); + let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: deadlock: the evaluated program deadlocked + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.stderr new file mode 100644 index 00000000000..334c14ebf04 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_deadlock.stderr @@ -0,0 +1,13 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_mutex_normal_deadlock.rs:LL:CC + | +LL | libc::pthread_mutex_lock(&mut mutex as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_normal_deadlock.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.rs new file mode 100644 index 00000000000..2b5886dc163 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.rs @@ -0,0 +1,16 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + unsafe { + let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); + assert_eq!( + libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), + 0, + ); + let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + libc::pthread_mutex_unlock(&mut mutex as *mut _); //~ ERROR: was not locked + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr new file mode 100644 index 00000000000..d717b4ec56b --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_normal_unlock_unlocked.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: unlocked a PTHREAD_MUTEX_NORMAL mutex that was not locked by the current thread + --> $DIR/libc_pthread_mutex_normal_unlock_unlocked.rs:LL:CC + | +LL | libc::pthread_mutex_unlock(&mut mutex as *mut _); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked a PTHREAD_MUTEX_NORMAL mutex that was not locked by the current thread + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutex_normal_unlock_unlocked.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs new file mode 100644 index 00000000000..686a394f7cb --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs @@ -0,0 +1,28 @@ +//@ignore-target-windows: No pthreads on Windows + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct Mutex(UnsafeCell); + +unsafe impl Send for Mutex {} +unsafe impl Sync for Mutex {} + +fn new_lock() -> Arc { + Arc::new(Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_mutex_lock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked a default mutex that was not locked by the current thread + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr new file mode 100644 index 00000000000..b8ec2d6d018 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: unlocked a default mutex that was not locked by the current thread + --> $DIR/libc_pthread_mutex_wrong_owner.rs:LL:CC + | +LL | ...t_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked a default mutex that was not locked by the current thread + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_mutex_wrong_owner.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.rs new file mode 100644 index 00000000000..51f00d62b75 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.rs @@ -0,0 +1,17 @@ +//@ignore-target-windows: No pthreads on Windows + +/// Test that destroying a pthread_mutexattr twice fails, even without a check for number validity + +fn main() { + unsafe { + use core::mem::MaybeUninit; + let mut attr = MaybeUninit::::uninit(); + + libc::pthread_mutexattr_init(attr.as_mut_ptr()); + + libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); + + libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr new file mode 100644 index 00000000000..a8425e6f81d --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutexattr_double_destroy.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/libc_pthread_mutexattr_double_destroy.rs:LL:CC + | +LL | libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_mutexattr_double_destroy.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.rs new file mode 100644 index 00000000000..fa4575bc1d4 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); + libc::pthread_rwlock_destroy(rw.get()); //~ ERROR: destroyed a locked rwlock + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr new file mode 100644 index 00000000000..bb90545c503 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_read_locked.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: destroyed a locked rwlock + --> $DIR/libc_pthread_rwlock_destroy_read_locked.rs:LL:CC + | +LL | libc::pthread_rwlock_destroy(rw.get()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked rwlock + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_destroy_read_locked.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.rs new file mode 100644 index 00000000000..e734a62bca8 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); + libc::pthread_rwlock_destroy(rw.get()); //~ ERROR: destroyed a locked rwlock + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr new file mode 100644 index 00000000000..7210c6a742a --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_destroy_write_locked.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: destroyed a locked rwlock + --> $DIR/libc_pthread_rwlock_destroy_write_locked.rs:LL:CC + | +LL | libc::pthread_rwlock_destroy(rw.get()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked rwlock + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_destroy_write_locked.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs new file mode 100644 index 00000000000..e96f7fc6803 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.rs @@ -0,0 +1,14 @@ +//@ignore-target-windows: No pthreads on Windows + +/// Test that destroying a pthread_rwlock twice fails, even without a check for number validity + +fn main() { + unsafe { + let mut lock = libc::PTHREAD_RWLOCK_INITIALIZER; + + libc::pthread_rwlock_destroy(&mut lock); + + libc::pthread_rwlock_destroy(&mut lock); + //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr new file mode 100644 index 00000000000..5032e98f116 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_double_destroy.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory + --> $DIR/libc_pthread_rwlock_double_destroy.rs:LL:CC + | +LL | libc::pthread_rwlock_destroy(&mut lock); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_double_destroy.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs new file mode 100644 index 00000000000..dffeee2b794 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); + libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr new file mode 100644 index 00000000000..957458a7ba0 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr @@ -0,0 +1,13 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC + | +LL | libc::pthread_rwlock_wrlock(rw.get()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs new file mode 100644 index 00000000000..328372b22ef --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs @@ -0,0 +1,28 @@ +//@ignore-target-windows: No pthreads on Windows + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct RwLock(UnsafeCell); + +unsafe impl Send for RwLock {} +unsafe impl Sync for RwLock {} + +fn new_lock() -> Arc { + Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_rwlock_rdlock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked an rwlock that was not locked by the active thread + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr new file mode 100644 index 00000000000..a964a64284a --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread + --> $DIR/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC + | +LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.rs new file mode 100644 index 00000000000..ced6b7a4f61 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.rs @@ -0,0 +1,8 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + libc::pthread_rwlock_unlock(rw.get()); //~ ERROR: was not locked + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr new file mode 100644 index 00000000000..98b09472904 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_unlock_unlocked.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread + --> $DIR/libc_pthread_rwlock_unlock_unlocked.rs:LL:CC + | +LL | libc::pthread_rwlock_unlock(rw.get()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_unlock_unlocked.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs new file mode 100644 index 00000000000..4174751926d --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs @@ -0,0 +1,29 @@ +//@ignore-target-windows: No pthreads on Windows +//@error-in-other-file: deadlock + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct RwLock(UnsafeCell); + +unsafe impl Send for RwLock {} +unsafe impl Sync for RwLock {} + +fn new_lock() -> Arc { + Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_rwlock_rdlock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr new file mode 100644 index 00000000000..bc9b15f293e --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr @@ -0,0 +1,32 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); +LL | | }) +LL | | .join() + | |_______________^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 2 previous errors + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs new file mode 100644 index 00000000000..099b8dcd106 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); + libc::pthread_rwlock_rdlock(rw.get()); //~ ERROR: deadlock + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr new file mode 100644 index 00000000000..d6cceaff166 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr @@ -0,0 +1,13 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC + | +LL | libc::pthread_rwlock_rdlock(rw.get()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs new file mode 100644 index 00000000000..43b3ab09bb2 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs @@ -0,0 +1,29 @@ +//@ignore-target-windows: No pthreads on Windows +//@error-in-other-file: deadlock + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct RwLock(UnsafeCell); + +unsafe impl Send for RwLock {} +unsafe impl Sync for RwLock {} + +fn new_lock() -> Arc { + Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_rwlock_wrlock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr new file mode 100644 index 00000000000..66c142bbc5c --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr @@ -0,0 +1,32 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC + | +LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC + +error: deadlock: the evaluated program deadlocked + --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + | +LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC + = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC + = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC +note: inside `main` + --> $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC + | +LL | / thread::spawn(move || { +LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); +LL | | }) +LL | | .join() + | |_______________^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 2 previous errors + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs new file mode 100644 index 00000000000..2704ff15441 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No pthreads on Windows + +fn main() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); + libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr new file mode 100644 index 00000000000..3ba99e3db4a --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr @@ -0,0 +1,13 @@ +error: deadlock: the evaluated program deadlocked + --> $DIR/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC + | +LL | libc::pthread_rwlock_wrlock(rw.get()); + | ^ the evaluated program deadlocked + | + = note: BACKTRACE: + = note: inside `main` at $DIR/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs new file mode 100644 index 00000000000..9a2cd09f083 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.rs @@ -0,0 +1,28 @@ +//@ignore-target-windows: No pthreads on Windows + +use std::cell::UnsafeCell; +use std::sync::Arc; +use std::thread; + +struct RwLock(UnsafeCell); + +unsafe impl Send for RwLock {} +unsafe impl Sync for RwLock {} + +fn new_lock() -> Arc { + Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) +} + +fn main() { + unsafe { + let lock = new_lock(); + assert_eq!(libc::pthread_rwlock_wrlock(lock.0.get() as *mut _), 0); + + let lock_copy = lock.clone(); + thread::spawn(move || { + assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked an rwlock that was not locked by the active thread + }) + .join() + .unwrap(); + } +} diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr new file mode 100644 index 00000000000..c9c22dea655 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_wrong_owner.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread + --> $DIR/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC + | +LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE on thread `unnamed-ID`: + = note: inside closure at $DIR/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs new file mode 100644 index 00000000000..a1895feb957 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.rs @@ -0,0 +1,17 @@ +//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0 +//@ignore-target-windows: No libc env support on Windows + +use std::env; +use std::thread; + +fn main() { + let t = thread::spawn(|| unsafe { + // Access the environment in another thread without taking the env lock. + // This represents some C code that queries the environment. + libc::getenv(b"TZ\0".as_ptr().cast()); //~ERROR: Data race detected + }); + // Meanwhile, the main thread uses the "safe" Rust env accessor. + env::set_var("MY_RUST_VAR", "Ferris"); + + t.join().unwrap(); +} diff --git a/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr new file mode 100644 index 00000000000..f85234f5627 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/env-set_var-data-race.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here + --> $DIR/env-set_var-data-race.rs:LL:CC + | +LL | libc::getenv(b"TZ/0".as_ptr().cast()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here + | +help: and (1) occurred earlier here + --> $DIR/env-set_var-data-race.rs:LL:CC + | +LL | env::set_var("MY_RUST_VAR", "Ferris"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE (of the first span) on thread `unnamed-ID`: + = note: inside closure at $DIR/env-set_var-data-race.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs new file mode 100644 index 00000000000..42b7e2b7838 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.rs @@ -0,0 +1,10 @@ +//@ignore-target-windows: No libc IO on Windows +//@compile-flags: -Zmiri-disable-isolation + +// FIXME: standard handles cannot be closed (https://github.com/rust-lang/rust/issues/40032) + +fn main() { + unsafe { + libc::close(1); //~ ERROR: cannot close stdout + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr new file mode 100644 index 00000000000..e1b1b053bbc --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/close_stdout.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: cannot close stdout + --> $DIR/close_stdout.rs:LL:CC + | +LL | libc::close(1); + | ^^^^^^^^^^^^^^ cannot close stdout + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = note: BACKTRACE: + = note: inside `main` at $DIR/close_stdout.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.rs b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.rs new file mode 100644 index 00000000000..3c62015a051 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No libc IO on Windows + +fn main() -> std::io::Result<()> { + let mut bytes = [0u8; 512]; + unsafe { + libc::read(0, bytes.as_mut_ptr() as *mut libc::c_void, 512); //~ ERROR: `read` from stdin not available when isolation is enabled + } + Ok(()) +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr new file mode 100644 index 00000000000..1d6626dda70 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/isolated_stdin.stderr @@ -0,0 +1,15 @@ +error: unsupported operation: `read` from stdin not available when isolation is enabled + --> $DIR/isolated_stdin.rs:LL:CC + | +LL | libc::read(0, bytes.as_mut_ptr() as *mut libc::c_void, 512); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `read` from stdin not available when isolation is enabled + | + = help: pass the flag `-Zmiri-disable-isolation` to disable isolation; + = help: or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning + = note: BACKTRACE: + = note: inside `main` at $DIR/isolated_stdin.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs new file mode 100644 index 00000000000..6d951a3a7b3 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.rs @@ -0,0 +1,11 @@ +//@ignore-target-windows: No mkstemp on Windows +//@compile-flags: -Zmiri-disable-isolation + +fn main() { + test_mkstemp_immutable_arg(); +} + +fn test_mkstemp_immutable_arg() { + let s: *mut libc::c_char = b"fooXXXXXX\0" as *const _ as *mut _; + let _fd = unsafe { libc::mkstemp(s) }; //~ ERROR: Undefined Behavior: writing to alloc1 which is read-only +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr new file mode 100644 index 00000000000..7a2757557ef --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/mkstemp_immutable_arg.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: writing to ALLOC which is read-only + --> $DIR/mkstemp_immutable_arg.rs:LL:CC + | +LL | let _fd = unsafe { libc::mkstemp(s) }; + | ^^^^^^^^^^^^^^^^ writing to ALLOC which is read-only + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `test_mkstemp_immutable_arg` at $DIR/mkstemp_immutable_arg.rs:LL:CC +note: inside `main` + --> $DIR/mkstemp_immutable_arg.rs:LL:CC + | +LL | test_mkstemp_immutable_arg(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.rs b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.rs new file mode 100644 index 00000000000..624f584a0c8 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.rs @@ -0,0 +1,10 @@ +//@compile-flags: -Zmiri-disable-isolation +//@ignore-target-windows: No libc IO on Windows + +fn main() -> std::io::Result<()> { + let mut bytes = [0u8; 512]; + unsafe { + libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); //~ ERROR: cannot read from stdout + } + Ok(()) +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr new file mode 100644 index 00000000000..baa6eb5ad6a --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/read_from_stdout.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: cannot read from stdout + --> $DIR/read_from_stdout.rs:LL:CC + | +LL | libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot read from stdout + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = note: BACKTRACE: + = note: inside `main` at $DIR/read_from_stdout.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs new file mode 100644 index 00000000000..d783967f959 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.rs @@ -0,0 +1,12 @@ +//@ignore-target-windows: No libc IO on Windows +//@compile-flags: -Zmiri-disable-isolation + +fn main() { + test_file_open_missing_needed_mode(); +} + +fn test_file_open_missing_needed_mode() { + let name = b"missing_arg.txt\0"; + let name_ptr = name.as_ptr().cast::(); + let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr new file mode 100644 index 00000000000..0988eefe222 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/unix_open_missing_required_mode.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 + --> $DIR/unix_open_missing_required_mode.rs:LL:CC + | +LL | ...safe { libc::open(name_ptr, libc::O_CREAT) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `test_file_open_missing_needed_mode` at $DIR/unix_open_missing_required_mode.rs:LL:CC +note: inside `main` + --> $DIR/unix_open_missing_required_mode.rs:LL:CC + | +LL | test_file_open_missing_needed_mode(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.rs b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.rs new file mode 100644 index 00000000000..683c55e90e1 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.rs @@ -0,0 +1,9 @@ +//@ignore-target-windows: No libc IO on Windows + +fn main() -> std::io::Result<()> { + let bytes = b"hello"; + unsafe { + libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); //~ ERROR: cannot write to stdin + } + Ok(()) +} diff --git a/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr new file mode 100644 index 00000000000..37323faf560 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/fs/write_to_stdin.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: cannot write to stdin + --> $DIR/write_to_stdin.rs:LL:CC + | +LL | libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot write to stdin + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = note: BACKTRACE: + = note: inside `main` at $DIR/write_to_stdin.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/memchr_null.rs b/src/tools/miri/tests/fail-dep/libc/memchr_null.rs new file mode 100644 index 00000000000..672cc10cd63 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memchr_null.rs @@ -0,0 +1,8 @@ +use std::ptr; + +// null is explicitly called out as UB in the C docs. +fn main() { + unsafe { + libc::memchr(ptr::null(), 0, 0); //~ERROR: dangling + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr b/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr new file mode 100644 index 00000000000..b76722f5f8f --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memchr_null.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + --> $DIR/memchr_null.rs:LL:CC + | +LL | libc::memchr(ptr::null(), 0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/memchr_null.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_null.rs b/src/tools/miri/tests/fail-dep/libc/memcmp_null.rs new file mode 100644 index 00000000000..066af4a8ae3 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_null.rs @@ -0,0 +1,8 @@ +use std::ptr; + +// null is explicitly called out as UB in the C docs. +fn main() { + unsafe { + libc::memcmp(ptr::null(), ptr::null(), 0); //~ERROR: dangling + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr b/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr new file mode 100644 index 00000000000..5c6ba4fd979 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_null.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + --> $DIR/memcmp_null.rs:LL:CC + | +LL | libc::memcmp(ptr::null(), ptr::null(), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/memcmp_null.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_zero.rs b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.rs new file mode 100644 index 00000000000..e28aa26270e --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.rs @@ -0,0 +1,12 @@ +//@compile-flags: -Zmiri-permissive-provenance + +// C says that passing "invalid" pointers is UB for all string functions. +// It is unclear whether `(int*)42` is "invalid", but there is no actually +// a `char` living at that address, so arguably it cannot be a valid pointer. +// Hence this is UB. +fn main() { + let ptr = 42 as *const u8; + unsafe { + libc::memcmp(ptr.cast(), ptr.cast(), 0); //~ERROR: dangling + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr new file mode 100644 index 00000000000..4ab37ab569f --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcmp_zero.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance) + --> $DIR/memcmp_zero.rs:LL:CC + | +LL | libc::memcmp(ptr.cast(), ptr.cast(), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/memcmp_zero.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/memcpy_zero.rs b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.rs new file mode 100644 index 00000000000..b37ed7df74f --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.rs @@ -0,0 +1,11 @@ +//@compile-flags: -Zmiri-permissive-provenance +// C's memcpy is 0 bytes is UB for some pointers that are allowed in Rust's `copy_nonoverlapping`. + +fn main() { + let from = 42 as *const u8; + let to = 23 as *mut u8; + unsafe { + to.copy_from(from, 0); // this is fine + libc::memcpy(to.cast(), from.cast(), 0); //~ERROR: dangling + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr new file mode 100644 index 00000000000..3e1ee7b86e3 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memcpy_zero.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance) + --> $DIR/memcpy_zero.rs:LL:CC + | +LL | libc::memcpy(to.cast(), from.cast(), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/memcpy_zero.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/memrchr_null.rs b/src/tools/miri/tests/fail-dep/libc/memrchr_null.rs new file mode 100644 index 00000000000..f06336b1299 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memrchr_null.rs @@ -0,0 +1,11 @@ +//@ignore-target-windows: No `memrchr` on Windows +//@ignore-target-apple: No `memrchr` on some apple targets + +use std::ptr; + +// null is explicitly called out as UB in the C docs. +fn main() { + unsafe { + libc::memrchr(ptr::null(), 0, 0); //~ERROR: dangling + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr b/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr new file mode 100644 index 00000000000..0cc7ac19feb --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/memrchr_null.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + --> $DIR/memrchr_null.rs:LL:CC + | +LL | libc::memrchr(ptr::null(), 0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/memrchr_null.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.rs b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.rs new file mode 100644 index 00000000000..9d55a493554 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.rs @@ -0,0 +1,18 @@ +//@compile-flags: -Zmiri-disable-isolation +//@ignore-target-windows: No mmap on Windows + +#![feature(rustc_private)] + +fn main() { + unsafe { + let ptr = libc::mmap( + std::ptr::null_mut(), + 4096, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ); + libc::free(ptr); //~ ERROR: which is mmap memory, using C heap deallocation operation + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr new file mode 100644 index 00000000000..cec67b6ef84 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/mmap_invalid_dealloc.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: deallocating ALLOC, which is mmap memory, using C heap deallocation operation + --> $DIR/mmap_invalid_dealloc.rs:LL:CC + | +LL | libc::free(ptr); + | ^^^^^^^^^^^^^^^ deallocating ALLOC, which is mmap memory, using C heap deallocation operation + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/mmap_invalid_dealloc.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.rs b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.rs new file mode 100644 index 00000000000..05ac232f5d7 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.rs @@ -0,0 +1,19 @@ +//@compile-flags: -Zmiri-disable-isolation +//@ignore-target-windows: No mmap on Windows + +#![feature(rustc_private)] + +fn main() { + unsafe { + let ptr = libc::mmap( + std::ptr::null_mut(), + 4096, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ); + libc::munmap(ptr, 4096); + let _x = *(ptr as *mut u8); //~ ERROR: has been freed + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr new file mode 100644 index 00000000000..49f2b84baa8 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/mmap_use_after_munmap.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling + --> $DIR/mmap_use_after_munmap.rs:LL:CC + | +LL | let _x = *(ptr as *mut u8); + | ^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information +help: ALLOC was allocated here: + --> $DIR/mmap_use_after_munmap.rs:LL:CC + | +LL | let ptr = libc::mmap( + | ___________________^ +LL | | std::ptr::null_mut(), +LL | | 4096, +LL | | libc::PROT_READ | libc::PROT_WRITE, +... | +LL | | 0, +LL | | ); + | |_________^ +help: ALLOC was deallocated here: + --> $DIR/mmap_use_after_munmap.rs:LL:CC + | +LL | libc::munmap(ptr, 4096); + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/munmap_partial.rs b/src/tools/miri/tests/fail-dep/libc/munmap_partial.rs new file mode 100644 index 00000000000..4386dc71af6 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/munmap_partial.rs @@ -0,0 +1,20 @@ +//! The man pages for mmap/munmap suggest that it is possible to partly unmap a previously-mapped +//! region of address space, but to LLVM that would be partial deallocation, which LLVM does not +//! support. So even though the man pages say this sort of use is possible, we must report UB. +//@ignore-target-windows: No mmap on Windows +//@normalize-stderr-test: "size [0-9]+ and alignment" -> "size SIZE and alignment" + +fn main() { + unsafe { + let ptr = libc::mmap( + std::ptr::null_mut(), + page_size::get() * 2, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ); + libc::munmap(ptr, 1); + //~^ ERROR: Undefined Behavior + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr b/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr new file mode 100644 index 00000000000..39825eb27c0 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/munmap_partial.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size SIZE and alignment ALIGN, but gave size SIZE and alignment ALIGN + --> $DIR/munmap_partial.rs:LL:CC + | +LL | libc::munmap(ptr, 1); + | ^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size SIZE and alignment ALIGN, but gave size SIZE and alignment ALIGN + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/munmap_partial.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/realloc-zero.rs b/src/tools/miri/tests/fail-dep/libc/realloc-zero.rs new file mode 100644 index 00000000000..0e210f31356 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/realloc-zero.rs @@ -0,0 +1,8 @@ +fn main() { + unsafe { + let p1 = libc::malloc(20); + // C made this UB... + let p2 = libc::realloc(p1, 0); //~ERROR: `realloc` with a size of zero + assert!(p2.is_null()); + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr b/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr new file mode 100644 index 00000000000..749a61f7396 --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/realloc-zero.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `realloc` with a size of zero + --> $DIR/realloc-zero.rs:LL:CC + | +LL | let p2 = libc::realloc(p1, 0); + | ^^^^^^^^^^^^^^^^^^^^ `realloc` with a size of zero + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/realloc-zero.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.rs b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.rs new file mode 100644 index 00000000000..cd8422f4afd --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.rs @@ -0,0 +1,11 @@ +//! `signal()` is special on Linux and macOS that it's only supported within libstd. +//! The implementation is not complete enough to permit user code to call it. +//@ignore-target-windows: No `libc::signal` on Windows +//@normalize-stderr-test: "OS `.*`" -> "$$OS" + +fn main() { + unsafe { + libc::signal(libc::SIGPIPE, libc::SIG_IGN); + //~^ ERROR: unsupported operation: can't call foreign function `signal` + } +} diff --git a/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr new file mode 100644 index 00000000000..f62622e29bf --- /dev/null +++ b/src/tools/miri/tests/fail-dep/libc/unsupported_incomplete_function.stderr @@ -0,0 +1,15 @@ +error: unsupported operation: can't call foreign function `signal` on $OS + --> $DIR/unsupported_incomplete_function.rs:LL:CC + | +LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS + | + = help: if this is a basic API commonly used on this target, please report an issue with Miri + = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases + = note: BACKTRACE: + = note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail-dep/realloc-zero.rs b/src/tools/miri/tests/fail-dep/realloc-zero.rs deleted file mode 100644 index 1482798e90c..00000000000 --- a/src/tools/miri/tests/fail-dep/realloc-zero.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - unsafe { - let p1 = libc::malloc(20); - // C made this UB... - let p2 = libc::realloc(p1, 0); //~ERROR: `realloc` with a size of zero - assert!(p2.is_null()); - } -} diff --git a/src/tools/miri/tests/fail-dep/realloc-zero.stderr b/src/tools/miri/tests/fail-dep/realloc-zero.stderr deleted file mode 100644 index 749a61f7396..00000000000 --- a/src/tools/miri/tests/fail-dep/realloc-zero.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: `realloc` with a size of zero - --> $DIR/realloc-zero.rs:LL:CC - | -LL | let p2 = libc::realloc(p1, 0); - | ^^^^^^^^^^^^^^^^^^^^ `realloc` with a size of zero - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/realloc-zero.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs deleted file mode 100644 index 2b9e7a34d65..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0 -//@ignore-target-windows: No libc on Windows - -use std::env; -use std::thread; - -fn main() { - let t = thread::spawn(|| unsafe { - // Access the environment in another thread without taking the env lock. - // This represents some C code that queries the environment. - libc::getenv(b"TZ\0".as_ptr().cast()); //~ERROR: Data race detected - }); - // Meanwhile, the main thread uses the "safe" Rust env accessor. - env::set_var("MY_RUST_VAR", "Ferris"); - - t.join().unwrap(); -} diff --git a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr b/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr deleted file mode 100644 index f85234f5627..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/env-set_var-data-race.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here - --> $DIR/env-set_var-data-race.rs:LL:CC - | -LL | libc::getenv(b"TZ/0".as_ptr().cast()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `main` and (2) non-atomic read on thread `unnamed-ID` at ALLOC. (2) just happened here - | -help: and (1) occurred earlier here - --> $DIR/env-set_var-data-race.rs:LL:CC - | -LL | env::set_var("MY_RUST_VAR", "Ferris"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE (of the first span) on thread `unnamed-ID`: - = note: inside closure at $DIR/env-set_var-data-race.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs deleted file mode 100644 index 09da8509af4..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-disable-isolation - -// FIXME: standard handles cannot be closed (https://github.com/rust-lang/rust/issues/40032) - -fn main() { - unsafe { - libc::close(1); //~ ERROR: cannot close stdout - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr deleted file mode 100644 index e1b1b053bbc..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: cannot close stdout - --> $DIR/close_stdout.rs:LL:CC - | -LL | libc::close(1); - | ^^^^^^^^^^^^^^ cannot close stdout - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at $DIR/close_stdout.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs deleted file mode 100644 index a45f805696d..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() -> std::io::Result<()> { - let mut bytes = [0u8; 512]; - unsafe { - libc::read(0, bytes.as_mut_ptr() as *mut libc::c_void, 512); //~ ERROR: `read` from stdin not available when isolation is enabled - } - Ok(()) -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr deleted file mode 100644 index 1d6626dda70..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: unsupported operation: `read` from stdin not available when isolation is enabled - --> $DIR/isolated_stdin.rs:LL:CC - | -LL | libc::read(0, bytes.as_mut_ptr() as *mut libc::c_void, 512); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `read` from stdin not available when isolation is enabled - | - = help: pass the flag `-Zmiri-disable-isolation` to disable isolation; - = help: or pass `-Zmiri-isolation-error=warn` to configure Miri to return an error code from isolated operations (if supported for that operation) and continue with a warning - = note: BACKTRACE: - = note: inside `main` at $DIR/isolated_stdin.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs deleted file mode 100644 index ba9f404d7c9..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-disable-isolation - -fn main() { - test_mkstemp_immutable_arg(); -} - -fn test_mkstemp_immutable_arg() { - let s: *mut libc::c_char = b"fooXXXXXX\0" as *const _ as *mut _; - let _fd = unsafe { libc::mkstemp(s) }; //~ ERROR: Undefined Behavior: writing to alloc1 which is read-only -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr deleted file mode 100644 index 7a2757557ef..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: writing to ALLOC which is read-only - --> $DIR/mkstemp_immutable_arg.rs:LL:CC - | -LL | let _fd = unsafe { libc::mkstemp(s) }; - | ^^^^^^^^^^^^^^^^ writing to ALLOC which is read-only - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `test_mkstemp_immutable_arg` at $DIR/mkstemp_immutable_arg.rs:LL:CC -note: inside `main` - --> $DIR/mkstemp_immutable_arg.rs:LL:CC - | -LL | test_mkstemp_immutable_arg(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs deleted file mode 100644 index 073fca4712e..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@compile-flags: -Zmiri-disable-isolation -//@ignore-target-windows: No libc on Windows - -fn main() -> std::io::Result<()> { - let mut bytes = [0u8; 512]; - unsafe { - libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); //~ ERROR: cannot read from stdout - } - Ok(()) -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr deleted file mode 100644 index baa6eb5ad6a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: cannot read from stdout - --> $DIR/read_from_stdout.rs:LL:CC - | -LL | libc::read(1, bytes.as_mut_ptr() as *mut libc::c_void, 512); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot read from stdout - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at $DIR/read_from_stdout.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs deleted file mode 100644 index ae231d4be66..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-disable-isolation - -fn main() { - test_file_open_missing_needed_mode(); -} - -fn test_file_open_missing_needed_mode() { - let name = b"missing_arg.txt\0"; - let name_ptr = name.as_ptr().cast::(); - let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR: Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr deleted file mode 100644 index 0988eefe222..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 - --> $DIR/unix_open_missing_required_mode.rs:LL:CC - | -LL | ...safe { libc::open(name_ptr, libc::O_CREAT) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3 - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `test_file_open_missing_needed_mode` at $DIR/unix_open_missing_required_mode.rs:LL:CC -note: inside `main` - --> $DIR/unix_open_missing_required_mode.rs:LL:CC - | -LL | test_file_open_missing_needed_mode(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs deleted file mode 100644 index d039ad718d3..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() -> std::io::Result<()> { - let bytes = b"hello"; - unsafe { - libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); //~ ERROR: cannot write to stdin - } - Ok(()) -} diff --git a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr deleted file mode 100644 index 37323faf560..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unsupported operation: cannot write to stdin - --> $DIR/write_to_stdin.rs:LL:CC - | -LL | libc::write(0, bytes.as_ptr() as *const libc::c_void, 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot write to stdin - | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support - = note: BACKTRACE: - = note: inside `main` at $DIR/write_to_stdin.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/memchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memchr_null.rs deleted file mode 100644 index 6bc7af7e6bf..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memchr_null.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use std::ptr; - -// null is explicitly called out as UB in the C docs. -fn main() { - unsafe { - libc::memchr(ptr::null(), 0, 0); //~ERROR: dangling - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr deleted file mode 100644 index b76722f5f8f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - --> $DIR/memchr_null.rs:LL:CC - | -LL | libc::memchr(ptr::null(), 0, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/memchr_null.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs deleted file mode 100644 index a4e0034c40b..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use std::ptr; - -// null is explicitly called out as UB in the C docs. -fn main() { - unsafe { - libc::memcmp(ptr::null(), ptr::null(), 0); //~ERROR: dangling - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr deleted file mode 100644 index 5c6ba4fd979..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - --> $DIR/memcmp_null.rs:LL:CC - | -LL | libc::memcmp(ptr::null(), ptr::null(), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/memcmp_null.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs deleted file mode 100644 index f2ddc200563..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-permissive-provenance - -// C says that passing "invalid" pointers is UB for all string functions. -// It is unclear whether `(int*)42` is "invalid", but there is no actually -// a `char` living at that address, so arguably it cannot be a valid pointer. -// Hence this is UB. -fn main() { - let ptr = 42 as *const u8; - unsafe { - libc::memcmp(ptr.cast(), ptr.cast(), 0); //~ERROR: dangling - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr deleted file mode 100644 index 4ab37ab569f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance) - --> $DIR/memcmp_zero.rs:LL:CC - | -LL | libc::memcmp(ptr.cast(), ptr.cast(), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance) - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/memcmp_zero.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs deleted file mode 100644 index 5283fea4cb9..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-permissive-provenance -// C's memcpy is 0 bytes is UB for some pointers that are allowed in Rust's `copy_nonoverlapping`. - -fn main() { - let from = 42 as *const u8; - let to = 23 as *mut u8; - unsafe { - to.copy_from(from, 0); // this is fine - libc::memcpy(to.cast(), from.cast(), 0); //~ERROR: dangling - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr deleted file mode 100644 index 3e1ee7b86e3..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance) - --> $DIR/memcpy_zero.rs:LL:CC - | -LL | libc::memcpy(to.cast(), from.cast(), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x17[noalloc] is a dangling pointer (it has no provenance) - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/memcpy_zero.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs deleted file mode 100644 index b6707d558d8..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@ignore-target-apple: No `memrchr` on some apple targets - -use std::ptr; - -// null is explicitly called out as UB in the C docs. -fn main() { - unsafe { - libc::memrchr(ptr::null(), 0, 0); //~ERROR: dangling - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr deleted file mode 100644 index 0cc7ac19feb..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - --> $DIR/memrchr_null.rs:LL:CC - | -LL | libc::memrchr(ptr::null(), 0, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance) - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/memrchr_null.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs deleted file mode 100644 index 70f7a6a7cef..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@compile-flags: -Zmiri-disable-isolation -//@ignore-target-windows: No libc on Windows - -#![feature(rustc_private)] - -fn main() { - unsafe { - let ptr = libc::mmap( - std::ptr::null_mut(), - 4096, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - 0, - ); - libc::free(ptr); //~ ERROR: which is mmap memory, using C heap deallocation operation - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr deleted file mode 100644 index cec67b6ef84..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: deallocating ALLOC, which is mmap memory, using C heap deallocation operation - --> $DIR/mmap_invalid_dealloc.rs:LL:CC - | -LL | libc::free(ptr); - | ^^^^^^^^^^^^^^^ deallocating ALLOC, which is mmap memory, using C heap deallocation operation - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/mmap_invalid_dealloc.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs deleted file mode 100644 index c97b013ba5a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@compile-flags: -Zmiri-disable-isolation -//@ignore-target-windows: No libc on Windows - -#![feature(rustc_private)] - -fn main() { - unsafe { - let ptr = libc::mmap( - std::ptr::null_mut(), - 4096, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - 0, - ); - libc::munmap(ptr, 4096); - let _x = *(ptr as *mut u8); //~ ERROR: has been freed - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr deleted file mode 100644 index 49f2b84baa8..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling - --> $DIR/mmap_use_after_munmap.rs:LL:CC - | -LL | let _x = *(ptr as *mut u8); - | ^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/mmap_use_after_munmap.rs:LL:CC - | -LL | let ptr = libc::mmap( - | ___________________^ -LL | | std::ptr::null_mut(), -LL | | 4096, -LL | | libc::PROT_READ | libc::PROT_WRITE, -... | -LL | | 0, -LL | | ); - | |_________^ -help: ALLOC was deallocated here: - --> $DIR/mmap_use_after_munmap.rs:LL:CC - | -LL | libc::munmap(ptr, 4096); - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs b/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs deleted file mode 100644 index d7aef47235f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! The man pages for mmap/munmap suggest that it is possible to partly unmap a previously-mapped -//! region of address space, but to LLVM that would be partial deallocation, which LLVM does not -//! support. So even though the man pages say this sort of use is possible, we must report UB. -//@ignore-target-windows: No libc on Windows -//@normalize-stderr-test: "size [0-9]+ and alignment" -> "size SIZE and alignment" - -fn main() { - unsafe { - let ptr = libc::mmap( - std::ptr::null_mut(), - page_size::get() * 2, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - 0, - ); - libc::munmap(ptr, 1); - //~^ ERROR: Undefined Behavior - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr b/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr deleted file mode 100644 index 39825eb27c0..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size SIZE and alignment ALIGN, but gave size SIZE and alignment ALIGN - --> $DIR/munmap_partial.rs:LL:CC - | -LL | libc::munmap(ptr, 1); - | ^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size SIZE and alignment ALIGN, but gave size SIZE and alignment ALIGN - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/munmap_partial.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs deleted file mode 100644 index 94ca3496ed9..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -/// Test that destroying a pthread_cond twice fails, even without a check for number validity - -fn main() { - unsafe { - use core::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - libc::pthread_condattr_init(attr.as_mut_ptr()); - - let mut cond = MaybeUninit::::uninit(); - - libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()); - - libc::pthread_cond_destroy(cond.as_mut_ptr()); - - libc::pthread_cond_destroy(cond.as_mut_ptr()); - //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr deleted file mode 100644 index 899c217efbf..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - --> $DIR/libc_pthread_cond_double_destroy.rs:LL:CC - | -LL | libc::pthread_cond_destroy(cond.as_mut_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_cond_double_destroy.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs deleted file mode 100644 index b5427d55eb0..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@ignore-target-apple: Our macOS condattr don't have any fields so we do not notice this. - -/// Test that destroying a pthread_condattr twice fails, even without a check for number validity - -fn main() { - unsafe { - use core::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - - libc::pthread_condattr_init(attr.as_mut_ptr()); - - libc::pthread_condattr_destroy(attr.as_mut_ptr()); - - libc::pthread_condattr_destroy(attr.as_mut_ptr()); - //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr deleted file mode 100644 index ef75b03162d..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - --> $DIR/libc_pthread_condattr_double_destroy.rs:LL:CC - | -LL | libc::pthread_condattr_destroy(attr.as_mut_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_condattr_double_destroy.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs deleted file mode 100644 index 8b251073383..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ignore-target-windows: No libc on Windows -// -// Check that if we pass NULL attribute, then we get the default mutex type. - -fn main() { - unsafe { - let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, std::ptr::null() as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: Undefined Behavior: trying to acquire already locked default mutex - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr deleted file mode 100644 index 3675ce49f30..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: trying to acquire already locked default mutex - --> $DIR/libc_pthread_mutex_NULL_deadlock.rs:LL:CC - | -LL | libc::pthread_mutex_lock(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to acquire already locked default mutex - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_NULL_deadlock.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs deleted file mode 100644 index 60d56d41fd9..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@error-in-other-file: deadlock - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct Mutex(UnsafeCell); - -unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} - -fn new_lock() -> Arc { - Arc::new(Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_mutex_lock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr deleted file mode 100644 index 987d0fc4c2d..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_mutex_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_mutex_deadlock.rs:LL:CC - -error: deadlock: the evaluated program deadlocked - --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - | -LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` - --> $DIR/libc_pthread_mutex_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 2 previous errors - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs deleted file mode 100644 index f443768819f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ignore-target-windows: No libc on Windows -// -// Check that if we do not set the mutex type, it is the default. - -fn main() { - unsafe { - let mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); - let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: Undefined Behavior: trying to acquire already locked default mutex - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr deleted file mode 100644 index 4d41141b545..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: trying to acquire already locked default mutex - --> $DIR/libc_pthread_mutex_default_deadlock.rs:LL:CC - | -LL | libc::pthread_mutex_lock(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to acquire already locked default mutex - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_default_deadlock.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs deleted file mode 100644 index ec3965c7574..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - unsafe { - let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); - assert_eq!( - libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), - 0, - ); - let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - libc::pthread_mutex_destroy(&mut mutex as *mut _); //~ ERROR: destroyed a locked mutex - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr deleted file mode 100644 index ed5e27b607a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: destroyed a locked mutex - --> $DIR/libc_pthread_mutex_destroy_locked.rs:LL:CC - | -LL | libc::pthread_mutex_destroy(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked mutex - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_destroy_locked.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs deleted file mode 100644 index 622c3eaeae3..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -/// Test that destroying a pthread_mutex twice fails, even without a check for number validity - -fn main() { - unsafe { - use core::mem::MaybeUninit; - - let mut attr = MaybeUninit::::uninit(); - libc::pthread_mutexattr_init(attr.as_mut_ptr()); - - let mut mutex = MaybeUninit::::uninit(); - - libc::pthread_mutex_init(mutex.as_mut_ptr(), attr.as_ptr()); - - libc::pthread_mutex_destroy(mutex.as_mut_ptr()); - - libc::pthread_mutex_destroy(mutex.as_mut_ptr()); - //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr deleted file mode 100644 index 05b35ee3b30..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - --> $DIR/libc_pthread_mutex_double_destroy.rs:LL:CC - | -LL | libc::pthread_mutex_destroy(mutex.as_mut_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_double_destroy.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs deleted file mode 100644 index 5ea09fa5aac..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - unsafe { - let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); - assert_eq!( - libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), - 0, - ); - let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - libc::pthread_mutex_lock(&mut mutex as *mut _); //~ ERROR: deadlock: the evaluated program deadlocked - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr deleted file mode 100644 index 334c14ebf04..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_mutex_normal_deadlock.rs:LL:CC - | -LL | libc::pthread_mutex_lock(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_normal_deadlock.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs deleted file mode 100644 index 8ce7542edb8..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - unsafe { - let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); - assert_eq!( - libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), - 0, - ); - let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - libc::pthread_mutex_unlock(&mut mutex as *mut _); //~ ERROR: was not locked - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr deleted file mode 100644 index d717b4ec56b..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: unlocked a PTHREAD_MUTEX_NORMAL mutex that was not locked by the current thread - --> $DIR/libc_pthread_mutex_normal_unlock_unlocked.rs:LL:CC - | -LL | libc::pthread_mutex_unlock(&mut mutex as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked a PTHREAD_MUTEX_NORMAL mutex that was not locked by the current thread - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutex_normal_unlock_unlocked.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs deleted file mode 100644 index b56775252e4..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct Mutex(UnsafeCell); - -unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} - -fn new_lock() -> Arc { - Arc::new(Mutex(UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_mutex_lock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked a default mutex that was not locked by the current thread - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr deleted file mode 100644 index b8ec2d6d018..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: unlocked a default mutex that was not locked by the current thread - --> $DIR/libc_pthread_mutex_wrong_owner.rs:LL:CC - | -LL | ...t_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked a default mutex that was not locked by the current thread - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_mutex_wrong_owner.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs deleted file mode 100644 index 474a277516d..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -/// Test that destroying a pthread_mutexattr twice fails, even without a check for number validity - -fn main() { - unsafe { - use core::mem::MaybeUninit; - let mut attr = MaybeUninit::::uninit(); - - libc::pthread_mutexattr_init(attr.as_mut_ptr()); - - libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); - - libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); - //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr deleted file mode 100644 index a8425e6f81d..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - --> $DIR/libc_pthread_mutexattr_double_destroy.rs:LL:CC - | -LL | libc::pthread_mutexattr_destroy(attr.as_mut_ptr()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_mutexattr_double_destroy.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs deleted file mode 100644 index 603580ff58a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); - libc::pthread_rwlock_destroy(rw.get()); //~ ERROR: destroyed a locked rwlock - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr deleted file mode 100644 index bb90545c503..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: destroyed a locked rwlock - --> $DIR/libc_pthread_rwlock_destroy_read_locked.rs:LL:CC - | -LL | libc::pthread_rwlock_destroy(rw.get()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked rwlock - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_destroy_read_locked.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs deleted file mode 100644 index ae44f22d146..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - libc::pthread_rwlock_destroy(rw.get()); //~ ERROR: destroyed a locked rwlock - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr deleted file mode 100644 index 7210c6a742a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: destroyed a locked rwlock - --> $DIR/libc_pthread_rwlock_destroy_write_locked.rs:LL:CC - | -LL | libc::pthread_rwlock_destroy(rw.get()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ destroyed a locked rwlock - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_destroy_write_locked.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs deleted file mode 100644 index 800986f7506..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -/// Test that destroying a pthread_rwlock twice fails, even without a check for number validity - -fn main() { - unsafe { - let mut lock = libc::PTHREAD_RWLOCK_INITIALIZER; - - libc::pthread_rwlock_destroy(&mut lock); - - libc::pthread_rwlock_destroy(&mut lock); - //~^ ERROR: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr deleted file mode 100644 index 5032e98f116..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory - --> $DIR/libc_pthread_rwlock_double_destroy.rs:LL:CC - | -LL | libc::pthread_rwlock_destroy(&mut lock); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_double_destroy.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs deleted file mode 100644 index 782c95b6d2e..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); - libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr deleted file mode 100644 index 957458a7ba0..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC - | -LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_read_write_deadlock_single_thread.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs deleted file mode 100644 index 1b498ad8fcd..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct RwLock(UnsafeCell); - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -fn new_lock() -> Arc { - Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_rwlock_rdlock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked an rwlock that was not locked by the active thread - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr deleted file mode 100644 index a964a64284a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread - --> $DIR/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC - | -LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs deleted file mode 100644 index 05f7e7a06c5..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - libc::pthread_rwlock_unlock(rw.get()); //~ ERROR: was not locked - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr deleted file mode 100644 index 98b09472904..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread - --> $DIR/libc_pthread_rwlock_unlock_unlocked.rs:LL:CC - | -LL | libc::pthread_rwlock_unlock(rw.get()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_unlock_unlocked.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs deleted file mode 100644 index 0f02c3231a6..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@error-in-other-file: deadlock - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct RwLock(UnsafeCell); - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -fn new_lock() -> Arc { - Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_rwlock_rdlock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr deleted file mode 100644 index bc9b15f293e..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC - -error: deadlock: the evaluated program deadlocked - --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - | -LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` - --> $DIR/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 2 previous errors - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs deleted file mode 100644 index 538f14ef89f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - libc::pthread_rwlock_rdlock(rw.get()); //~ ERROR: deadlock - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr deleted file mode 100644 index d6cceaff166..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC - | -LL | libc::pthread_rwlock_rdlock(rw.get()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_write_read_deadlock_single_thread.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs deleted file mode 100644 index 10be5b33752..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@error-in-other-file: deadlock - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct RwLock(UnsafeCell); - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -fn new_lock() -> Arc { - Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_rwlock_wrlock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: deadlock - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr deleted file mode 100644 index 66c142bbc5c..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC - | -LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC - -error: deadlock: the evaluated program deadlocked - --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - | -LL | let ret = libc::pthread_join(self.id, ptr::null_mut()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC - = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC - = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC -note: inside `main` - --> $DIR/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC - | -LL | / thread::spawn(move || { -LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0); -LL | | }) -LL | | .join() - | |_______________^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 2 previous errors - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs deleted file mode 100644 index 2c963d36510..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -fn main() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - libc::pthread_rwlock_wrlock(rw.get()); //~ ERROR: deadlock - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr deleted file mode 100644 index 3ba99e3db4a..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: deadlock: the evaluated program deadlocked - --> $DIR/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC - | -LL | libc::pthread_rwlock_wrlock(rw.get()); - | ^ the evaluated program deadlocked - | - = note: BACKTRACE: - = note: inside `main` at $DIR/libc_pthread_rwlock_write_write_deadlock_single_thread.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs deleted file mode 100644 index dd099474d8f..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use std::cell::UnsafeCell; -use std::sync::Arc; -use std::thread; - -struct RwLock(UnsafeCell); - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -fn new_lock() -> Arc { - Arc::new(RwLock(UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER))) -} - -fn main() { - unsafe { - let lock = new_lock(); - assert_eq!(libc::pthread_rwlock_wrlock(lock.0.get() as *mut _), 0); - - let lock_copy = lock.clone(); - thread::spawn(move || { - assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); //~ ERROR: Undefined Behavior: unlocked an rwlock that was not locked by the active thread - }) - .join() - .unwrap(); - } -} diff --git a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr deleted file mode 100644 index c9c22dea655..00000000000 --- a/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: unlocked an rwlock that was not locked by the active thread - --> $DIR/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC - | -LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unlocked an rwlock that was not locked by the active thread - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE on thread `unnamed-ID`: - = note: inside closure at $DIR/libc_pthread_rwlock_write_wrong_owner.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs deleted file mode 100644 index 6ef842c9ccb..00000000000 --- a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! `signal()` is special on Linux and macOS that it's only supported within libstd. -//! The implementation is not complete enough to permit user code to call it. -//@ignore-target-windows: No libc on Windows -//@normalize-stderr-test: "OS `.*`" -> "$$OS" - -fn main() { - unsafe { - libc::signal(libc::SIGPIPE, libc::SIG_IGN); - //~^ ERROR: unsupported operation: can't call foreign function `signal` - } -} diff --git a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr deleted file mode 100644 index f62622e29bf..00000000000 --- a/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: unsupported operation: can't call foreign function `signal` on $OS - --> $DIR/unsupported_incomplete_function.rs:LL:CC - | -LL | libc::signal(libc::SIGPIPE, libc::SIG_IGN); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function `signal` on $OS - | - = help: if this is a basic API commonly used on this target, please report an issue with Miri - = help: however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases - = note: BACKTRACE: - = note: inside `main` at $DIR/unsupported_incomplete_function.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/panic/unsupported_syscall.rs b/src/tools/miri/tests/panic/unsupported_syscall.rs index 31d666e1d9d..30f9da5f80e 100644 --- a/src/tools/miri/tests/panic/unsupported_syscall.rs +++ b/src/tools/miri/tests/panic/unsupported_syscall.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: no `syscall` on Windows //@ignore-target-apple: `syscall` is not supported on macOS //@compile-flags: -Zmiri-panic-on-unsupported diff --git a/src/tools/miri/tests/pass-dep/calloc.rs b/src/tools/miri/tests/pass-dep/calloc.rs deleted file mode 100644 index 62ab63c5fc7..00000000000 --- a/src/tools/miri/tests/pass-dep/calloc.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use core::slice; - -fn main() { - unsafe { - let p1 = libc::calloc(0, 0); - assert!(p1.is_null()); - - let p2 = libc::calloc(20, 0); - assert!(p2.is_null()); - - let p3 = libc::calloc(0, 20); - assert!(p3.is_null()); - - let p4 = libc::calloc(4, 8); - assert!(!p4.is_null()); - let slice = slice::from_raw_parts(p4 as *const u8, 4 * 8); - assert_eq!(&slice, &[0_u8; 4 * 8]); - libc::free(p4); - } -} diff --git a/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs new file mode 100644 index 00000000000..86a47ba3655 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/concurrency/env-cleanup-data-race.rs @@ -0,0 +1,22 @@ +//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0 +//@ignore-target-windows: No libc env support on Windows + +use std::ffi::CStr; +use std::thread; + +fn main() { + unsafe { + thread::spawn(|| { + // Access the environment in another thread without taking the env lock + let s = libc::getenv("MIRI_ENV_VAR_TEST\0".as_ptr().cast()); + if s.is_null() { + panic!("null"); + } + let _s = String::from_utf8_lossy(CStr::from_ptr(s).to_bytes()); + }); + thread::yield_now(); + // After the main thread exits, env vars will be cleaned up -- but because we have not *joined* + // the other thread, those accesses technically race with those in the other thread. + // We don't want to emit an error here, though. + } +} diff --git a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait.rs b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait.rs index f362caa11dc..d758168c7c3 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //@ignore-target-apple: pthread_condattr_setclock is not supported on MacOS. //@compile-flags: -Zmiri-disable-isolation diff --git a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait_isolated.rs b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait_isolated.rs index 66c0895a5da..f1a3c5dc10d 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait_isolated.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/libc_pthread_cond_timedwait_isolated.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //@ignore-target-apple: pthread_condattr_setclock is not supported on MacOS. /// Test that conditional variable timeouts are working properly diff --git a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs index ae874740f2b..0eaab967642 100644 --- a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs +++ b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No pthreads on Windows //! Test that pthread_key destructors are run in the right order. //! Note that these are *not* used by actual `thread_local!` on Linux! Those use //! `thread_local_dtor::register_dtor` from the stdlib instead. In Miri this hits the fallback path diff --git a/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs b/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs index 716119a0fc3..1198168795d 100644 --- a/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs +++ b/src/tools/miri/tests/pass-dep/extra_fn_ptr_gc.rs @@ -1,4 +1,4 @@ -//@ignore-target-windows: No libc on Windows +//@ignore-target-windows: No `dlsym` on Windows //@compile-flags: -Zmiri-permissive-provenance #[path = "../utils/mod.rs"] diff --git a/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.rs b/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.rs new file mode 100644 index 00000000000..307906f2583 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.rs @@ -0,0 +1,12 @@ +//@only-target-apple: F_FULLFSYNC only on apple systems +//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace + +use std::io::Error; + +fn main() { + // test `fcntl(F_FULLFSYNC)` + unsafe { + assert_eq!(libc::fcntl(1, libc::F_FULLFSYNC, 0), -1); + assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM)); + } +} diff --git a/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.stderr b/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.stderr new file mode 100644 index 00000000000..09a24e1e5d7 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/fcntl_f-fullfsync_apple.stderr @@ -0,0 +1,2 @@ +warning: `fcntl` was made to return an error due to isolation + diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs new file mode 100644 index 00000000000..5185db0b0e2 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.rs @@ -0,0 +1,28 @@ +//@ignore-target-windows: no libc on Windows +//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace +//@normalize-stderr-test: "(stat(x)?)" -> "$$STAT" + +use std::ffi::CString; +use std::fs; +use std::io::{Error, ErrorKind}; + +fn main() { + // test `fcntl(F_DUPFD): should work even with isolation.` + unsafe { + assert!(libc::fcntl(1, libc::F_DUPFD, 0) >= 0); + } + + // test `readlink` + let symlink_c_str = CString::new("foo.txt").unwrap(); + let mut buf = vec![0; "foo_link.txt".len() + 1]; + unsafe { + assert_eq!(libc::readlink(symlink_c_str.as_ptr(), buf.as_mut_ptr(), buf.len()), -1); + assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES)); + } + + // test `stat` + let err = fs::metadata("foo.txt").unwrap_err(); + assert_eq!(err.kind(), ErrorKind::PermissionDenied); + // check that it is the right kind of `PermissionDenied` + assert_eq!(err.raw_os_error(), Some(libc::EACCES)); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.stderr b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.stderr new file mode 100644 index 00000000000..b0cadfb970b --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs-with-isolation.stderr @@ -0,0 +1,4 @@ +warning: `readlink` was made to return an error due to isolation + +warning: `$STAT` was made to return an error due to isolation + diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs new file mode 100644 index 00000000000..0dd849a045d --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs @@ -0,0 +1,430 @@ +//@ignore-target-windows: no libc on Windows +//@compile-flags: -Zmiri-disable-isolation + +#![feature(io_error_more)] +#![feature(io_error_uncategorized)] + +use std::ffi::{CStr, CString, OsString}; +use std::fs::{canonicalize, remove_dir_all, remove_file, File}; +use std::io::{Error, ErrorKind, Write}; +use std::os::unix::ffi::OsStrExt; +use std::os::unix::io::AsRawFd; +use std::path::PathBuf; + +#[path = "../../utils/mod.rs"] +mod utils; + +fn main() { + test_dup_stdout_stderr(); + test_canonicalize_too_long(); + test_rename(); + test_ftruncate::(libc::ftruncate); + #[cfg(target_os = "linux")] + test_ftruncate::(libc::ftruncate64); + test_readlink(); + test_file_open_unix_allow_two_args(); + test_file_open_unix_needs_three_args(); + test_file_open_unix_extra_third_arg(); + #[cfg(target_os = "linux")] + test_o_tmpfile_flag(); + test_posix_mkstemp(); + test_posix_realpath_alloc(); + test_posix_realpath_noalloc(); + test_posix_realpath_errors(); + #[cfg(target_os = "linux")] + test_posix_fadvise(); + #[cfg(target_os = "linux")] + test_sync_file_range(); + test_isatty(); +} + +/// Prepare: compute filename and make sure the file does not exist. +fn prepare(filename: &str) -> PathBuf { + let path = utils::tmp().join(filename); + // Clean the paths for robustness. + remove_file(&path).ok(); + path +} + +/// Prepare directory: compute directory name and make sure it does not exist. +#[allow(unused)] +fn prepare_dir(dirname: &str) -> PathBuf { + let path = utils::tmp().join(&dirname); + // Clean the directory for robustness. + remove_dir_all(&path).ok(); + path +} + +/// Prepare like above, and also write some initial content to the file. +fn prepare_with_content(filename: &str, content: &[u8]) -> PathBuf { + let path = prepare(filename); + let mut file = File::create(&path).unwrap(); + file.write(content).unwrap(); + path +} + +fn test_file_open_unix_allow_two_args() { + let path = prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]); + + let mut name = path.into_os_string(); + name.push("\0"); + let name_ptr = name.as_bytes().as_ptr().cast::(); + let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY) }; +} + +fn test_file_open_unix_needs_three_args() { + let path = prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]); + + let mut name = path.into_os_string(); + name.push("\0"); + let name_ptr = name.as_bytes().as_ptr().cast::(); + let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT, 0o666) }; +} + +fn test_file_open_unix_extra_third_arg() { + let path = prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]); + + let mut name = path.into_os_string(); + name.push("\0"); + let name_ptr = name.as_bytes().as_ptr().cast::(); + let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 42) }; +} + +fn test_dup_stdout_stderr() { + let bytes = b"hello dup fd\n"; + unsafe { + let new_stdout = libc::fcntl(1, libc::F_DUPFD, 0); + let new_stderr = libc::fcntl(2, libc::F_DUPFD, 0); + libc::write(new_stdout, bytes.as_ptr() as *const libc::c_void, bytes.len()); + libc::write(new_stderr, bytes.as_ptr() as *const libc::c_void, bytes.len()); + } +} + +fn test_canonicalize_too_long() { + // Make sure we get an error for long paths. + let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap()); + assert!(canonicalize(too_long).is_err()); +} + +fn test_readlink() { + let bytes = b"Hello, World!\n"; + let path = prepare_with_content("miri_test_fs_link_target.txt", bytes); + let expected_path = path.as_os_str().as_bytes(); + + let symlink_path = prepare("miri_test_fs_symlink.txt"); + std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); + + // Test that the expected string gets written to a buffer of proper + // length, and that a trailing null byte is not written. + let symlink_c_str = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); + let symlink_c_ptr = symlink_c_str.as_ptr(); + + // Make the buf one byte larger than it needs to be, + // and check that the last byte is not overwritten. + let mut large_buf = vec![0xFF; expected_path.len() + 1]; + let res = + unsafe { libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) }; + // Check that the resolved path was properly written into the buf. + assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); + assert_eq!(large_buf.last(), Some(&0xFF)); + assert_eq!(res, large_buf.len() as isize - 1); + + // Test that the resolved path is truncated if the provided buffer + // is too small. + let mut small_buf = [0u8; 2]; + let res = + unsafe { libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) }; + assert_eq!(small_buf, &expected_path[..small_buf.len()]); + assert_eq!(res, small_buf.len() as isize); + + // Test that we report a proper error for a missing path. + let bad_path = CString::new("MIRI_MISSING_FILE_NAME").unwrap(); + let res = unsafe { + libc::readlink(bad_path.as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len()) + }; + assert_eq!(res, -1); + assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); +} + +fn test_rename() { + let path1 = prepare("miri_test_libc_fs_source.txt"); + let path2 = prepare("miri_test_libc_fs_rename_destination.txt"); + + let file = File::create(&path1).unwrap(); + drop(file); + + let c_path1 = CString::new(path1.as_os_str().as_bytes()).expect("CString::new failed"); + let c_path2 = CString::new(path2.as_os_str().as_bytes()).expect("CString::new failed"); + + // Renaming should succeed + unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) }; + // Check that old file path isn't present + assert_eq!(ErrorKind::NotFound, path1.metadata().unwrap_err().kind()); + // Check that the file has moved successfully + assert!(path2.metadata().unwrap().is_file()); + + // Renaming a nonexistent file should fail + let res = unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) }; + assert_eq!(res, -1); + assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); + + remove_file(&path2).unwrap(); +} + +fn test_ftruncate>( + ftruncate: unsafe extern "C" fn(fd: libc::c_int, length: T) -> libc::c_int, +) { + // libc::off_t is i32 in target i686-unknown-linux-gnu + // https://docs.rs/libc/latest/i686-unknown-linux-gnu/libc/type.off_t.html + + let bytes = b"hello"; + let path = prepare("miri_test_libc_fs_ftruncate.txt"); + let mut file = File::create(&path).unwrap(); + file.write(bytes).unwrap(); + file.sync_all().unwrap(); + assert_eq!(file.metadata().unwrap().len(), 5); + + let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) }; + + // Truncate to a bigger size + let mut res = unsafe { ftruncate(fd, T::from(10)) }; + assert_eq!(res, 0); + assert_eq!(file.metadata().unwrap().len(), 10); + + // Write after truncate + file.write(b"dup").unwrap(); + file.sync_all().unwrap(); + assert_eq!(file.metadata().unwrap().len(), 10); + + // Truncate to smaller size + res = unsafe { ftruncate(fd, T::from(2)) }; + assert_eq!(res, 0); + assert_eq!(file.metadata().unwrap().len(), 2); + + remove_file(&path).unwrap(); +} + +#[cfg(target_os = "linux")] +fn test_o_tmpfile_flag() { + use std::fs::{create_dir, OpenOptions}; + use std::os::unix::fs::OpenOptionsExt; + let dir_path = prepare_dir("miri_test_fs_dir"); + create_dir(&dir_path).unwrap(); + // test that the `O_TMPFILE` custom flag gracefully errors instead of stopping execution + assert_eq!( + Some(libc::EOPNOTSUPP), + OpenOptions::new() + .read(true) + .write(true) + .custom_flags(libc::O_TMPFILE) + .open(dir_path) + .unwrap_err() + .raw_os_error(), + ); +} + +fn test_posix_mkstemp() { + use std::ffi::OsStr; + use std::os::unix::io::FromRawFd; + use std::path::Path; + + let valid_template = "fooXXXXXX"; + // C needs to own this as `mkstemp(3)` says: + // "Since it will be modified, `template` must not be a string constant, but + // should be declared as a character array." + // There seems to be no `as_mut_ptr` on `CString` so we need to use `into_raw`. + let ptr = CString::new(valid_template).unwrap().into_raw(); + let fd = unsafe { libc::mkstemp(ptr) }; + // Take ownership back in Rust to not leak memory. + let slice = unsafe { CString::from_raw(ptr) }; + assert!(fd > 0); + let osstr = OsStr::from_bytes(slice.to_bytes()); + let path: &Path = osstr.as_ref(); + let name = path.file_name().unwrap().to_string_lossy(); + assert!(name.ne("fooXXXXXX")); + assert!(name.starts_with("foo")); + assert_eq!(name.len(), 9); + assert_eq!( + name.chars().skip(3).filter(char::is_ascii_alphanumeric).collect::>().len(), + 6 + ); + let file = unsafe { File::from_raw_fd(fd) }; + assert!(file.set_len(0).is_ok()); + + let invalid_templates = vec!["foo", "barXX", "XXXXXXbaz", "whatXXXXXXever", "X"]; + for t in invalid_templates { + let ptr = CString::new(t).unwrap().into_raw(); + let fd = unsafe { libc::mkstemp(ptr) }; + let _ = unsafe { CString::from_raw(ptr) }; + // "On error, -1 is returned, and errno is set to + // indicate the error" + assert_eq!(fd, -1); + let e = std::io::Error::last_os_error(); + assert_eq!(e.raw_os_error(), Some(libc::EINVAL)); + assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput); + } +} + +/// Test allocating variant of `realpath`. +fn test_posix_realpath_alloc() { + use std::os::unix::ffi::OsStrExt; + use std::os::unix::ffi::OsStringExt; + + let buf; + let path = utils::tmp().join("miri_test_libc_posix_realpath_alloc"); + let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + + // Cleanup before test. + remove_file(&path).ok(); + // Create file. + drop(File::create(&path).unwrap()); + unsafe { + let r = libc::realpath(c_path.as_ptr(), std::ptr::null_mut()); + assert!(!r.is_null()); + buf = CStr::from_ptr(r).to_bytes().to_vec(); + libc::free(r as *mut _); + } + let canonical = PathBuf::from(OsString::from_vec(buf)); + assert_eq!(path.file_name(), canonical.file_name()); + + // Cleanup after test. + remove_file(&path).unwrap(); +} + +/// Test non-allocating variant of `realpath`. +fn test_posix_realpath_noalloc() { + use std::ffi::{CStr, CString}; + use std::os::unix::ffi::OsStrExt; + + let path = utils::tmp().join("miri_test_libc_posix_realpath_noalloc"); + let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); + + let mut v = vec![0; libc::PATH_MAX as usize]; + + // Cleanup before test. + remove_file(&path).ok(); + // Create file. + drop(File::create(&path).unwrap()); + unsafe { + let r = libc::realpath(c_path.as_ptr(), v.as_mut_ptr()); + assert!(!r.is_null()); + } + let c = unsafe { CStr::from_ptr(v.as_ptr()) }; + let canonical = PathBuf::from(c.to_str().expect("CStr to str")); + + assert_eq!(path.file_name(), canonical.file_name()); + + // Cleanup after test. + remove_file(&path).unwrap(); +} + +/// Test failure cases for `realpath`. +fn test_posix_realpath_errors() { + use std::ffi::CString; + use std::io::ErrorKind; + + // Test nonexistent path returns an error. + let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed"); + let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) }; + assert!(r.is_null()); + let e = std::io::Error::last_os_error(); + assert_eq!(e.raw_os_error(), Some(libc::ENOENT)); + assert_eq!(e.kind(), ErrorKind::NotFound); +} + +#[cfg(target_os = "linux")] +fn test_posix_fadvise() { + use std::io::Write; + + let path = utils::tmp().join("miri_test_libc_posix_fadvise.txt"); + // Cleanup before test + remove_file(&path).ok(); + + // Set up an open file + let mut file = File::create(&path).unwrap(); + let bytes = b"Hello, World!\n"; + file.write(bytes).unwrap(); + + // Test calling posix_fadvise on a file. + let result = unsafe { + libc::posix_fadvise( + file.as_raw_fd(), + 0, + bytes.len().try_into().unwrap(), + libc::POSIX_FADV_DONTNEED, + ) + }; + drop(file); + remove_file(&path).unwrap(); + assert_eq!(result, 0); +} + +#[cfg(target_os = "linux")] +fn test_sync_file_range() { + use std::io::Write; + + let path = utils::tmp().join("miri_test_libc_sync_file_range.txt"); + // Cleanup before test. + remove_file(&path).ok(); + + // Write to a file. + let mut file = File::create(&path).unwrap(); + let bytes = b"Hello, World!\n"; + file.write(bytes).unwrap(); + + // Test calling sync_file_range on the file. + let result_1 = unsafe { + libc::sync_file_range( + file.as_raw_fd(), + 0, + 0, + libc::SYNC_FILE_RANGE_WAIT_BEFORE + | libc::SYNC_FILE_RANGE_WRITE + | libc::SYNC_FILE_RANGE_WAIT_AFTER, + ) + }; + drop(file); + + // Test calling sync_file_range on a file opened for reading. + let file = File::open(&path).unwrap(); + let result_2 = unsafe { + libc::sync_file_range( + file.as_raw_fd(), + 0, + 0, + libc::SYNC_FILE_RANGE_WAIT_BEFORE + | libc::SYNC_FILE_RANGE_WRITE + | libc::SYNC_FILE_RANGE_WAIT_AFTER, + ) + }; + drop(file); + + remove_file(&path).unwrap(); + assert_eq!(result_1, 0); + assert_eq!(result_2, 0); +} + +fn test_isatty() { + // Testing whether our isatty shim returns the right value would require controlling whether + // these streams are actually TTYs, which is hard. + // For now, we just check that these calls are supported at all. + unsafe { + libc::isatty(libc::STDIN_FILENO); + libc::isatty(libc::STDOUT_FILENO); + libc::isatty(libc::STDERR_FILENO); + + // But when we open a file, it is definitely not a TTY. + let path = utils::tmp().join("notatty.txt"); + // Cleanup before test. + remove_file(&path).ok(); + let file = File::create(&path).unwrap(); + + assert_eq!(libc::isatty(file.as_raw_fd()), 0); + assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::ENOTTY); + + // Cleanup after test. + drop(file); + remove_file(&path).unwrap(); + } +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.stderr b/src/tools/miri/tests/pass-dep/libc/libc-fs.stderr new file mode 100644 index 00000000000..b6fa69e3d5d --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.stderr @@ -0,0 +1 @@ +hello dup fd diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.stdout b/src/tools/miri/tests/pass-dep/libc/libc-fs.stdout new file mode 100644 index 00000000000..b6fa69e3d5d --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.stdout @@ -0,0 +1 @@ +hello dup fd diff --git a/src/tools/miri/tests/pass-dep/libc/libc-mem.rs b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs new file mode 100644 index 00000000000..33cdc18b70f --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-mem.rs @@ -0,0 +1,255 @@ +#![feature(strict_provenance, pointer_is_aligned_to)] +use std::{mem, ptr, slice}; + +fn test_memcpy() { + unsafe { + let src = [1i8, 2, 3]; + let dest = libc::calloc(3, 1); + libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); + let slc = std::slice::from_raw_parts(dest as *const i8, 3); + assert_eq!(*slc, [1i8, 2, 3]); + libc::free(dest); + } + + unsafe { + let src = [1i8, 2, 3]; + let dest = libc::calloc(4, 1); + libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); + let slc = std::slice::from_raw_parts(dest as *const i8, 4); + assert_eq!(*slc, [1i8, 2, 3, 0]); + libc::free(dest); + } + + unsafe { + let src = 123_i32; + let mut dest = 0_i32; + libc::memcpy( + &mut dest as *mut i32 as *mut libc::c_void, + &src as *const i32 as *const libc::c_void, + mem::size_of::(), + ); + assert_eq!(dest, src); + } + + unsafe { + let src = Some(123); + let mut dest: Option = None; + libc::memcpy( + &mut dest as *mut Option as *mut libc::c_void, + &src as *const Option as *const libc::c_void, + mem::size_of::>(), + ); + assert_eq!(dest, src); + } + + unsafe { + let src = &123; + let mut dest = &42; + libc::memcpy( + &mut dest as *mut &'static i32 as *mut libc::c_void, + &src as *const &'static i32 as *const libc::c_void, + mem::size_of::<&'static i32>(), + ); + assert_eq!(*dest, 123); + } +} + +fn test_strcpy() { + use std::ffi::{CStr, CString}; + + // case: src_size equals dest_size + unsafe { + let src = CString::new("rust").unwrap(); + let size = src.as_bytes_with_nul().len(); + let dest = libc::malloc(size); + libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); + assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); + libc::free(dest); + } + + // case: src_size is less than dest_size + unsafe { + let src = CString::new("rust").unwrap(); + let size = src.as_bytes_with_nul().len(); + let dest = libc::malloc(size + 1); + libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); + assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); + libc::free(dest); + } +} + +fn test_malloc() { + // Test that small allocations sometimes *are* not very aligned. + let saw_unaligned = (0..64).any(|_| unsafe { + let p = libc::malloc(3); + libc::free(p); + (p as usize) % 4 != 0 // find any that this is *not* 4-aligned + }); + assert!(saw_unaligned); + + unsafe { + let p1 = libc::malloc(20); + p1.write_bytes(0u8, 20); + + // old size < new size + let p2 = libc::realloc(p1, 40); + let slice = slice::from_raw_parts(p2 as *const u8, 20); + assert_eq!(&slice, &[0_u8; 20]); + + // old size == new size + let p3 = libc::realloc(p2, 40); + let slice = slice::from_raw_parts(p3 as *const u8, 20); + assert_eq!(&slice, &[0_u8; 20]); + + // old size > new size + let p4 = libc::realloc(p3, 10); + let slice = slice::from_raw_parts(p4 as *const u8, 10); + assert_eq!(&slice, &[0_u8; 10]); + + libc::free(p4); + } + + unsafe { + // Realloc with size 0 is okay for the null pointer + let p2 = libc::realloc(ptr::null_mut(), 0); + assert!(p2.is_null()); + } + + unsafe { + let p1 = libc::realloc(ptr::null_mut(), 20); + assert!(!p1.is_null()); + + libc::free(p1); + } +} + +fn test_calloc() { + unsafe { + let p1 = libc::calloc(0, 0); + assert!(p1.is_null()); + + let p2 = libc::calloc(20, 0); + assert!(p2.is_null()); + + let p3 = libc::calloc(0, 20); + assert!(p3.is_null()); + + let p4 = libc::calloc(4, 8); + assert!(!p4.is_null()); + let slice = slice::from_raw_parts(p4 as *const u8, 4 * 8); + assert_eq!(&slice, &[0_u8; 4 * 8]); + libc::free(p4); + } +} + +#[cfg(not(target_os = "windows"))] +fn test_memalign() { + // A normal allocation. + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 8; + let size = 64; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } + + // Align > size. + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 64; + let size = 8; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } + + // Size not multiple of align + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 16; + let size = 31; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + assert!(!ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + ptr.cast::().write_bytes(1, size); + libc::free(ptr); + } + + // Size == 0 + unsafe { + let mut ptr: *mut libc::c_void = ptr::null_mut(); + let align = 64; + let size = 0; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); + // We are not required to return null if size == 0, but we currently do. + // It's fine to remove this assert if we start returning non-null pointers. + assert!(ptr.is_null()); + assert!(ptr.is_aligned_to(align)); + // Regardless of what we return, it must be `free`able. + libc::free(ptr); + } + + // Non-power of 2 align + unsafe { + let mut ptr: *mut libc::c_void = ptr::without_provenance_mut(0x1234567); + let align = 15; + let size = 8; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL); + // The pointer is not modified on failure, posix_memalign(3) says: + // > On Linux (and other systems), posix_memalign() does not modify memptr on failure. + // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2. + assert_eq!(ptr.addr(), 0x1234567); + } + + // Too small align (smaller than ptr) + unsafe { + let mut ptr: *mut libc::c_void = ptr::without_provenance_mut(0x1234567); + let align = std::mem::size_of::() / 2; + let size = 8; + assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL); + // The pointer is not modified on failure, posix_memalign(3) says: + // > On Linux (and other systems), posix_memalign() does not modify memptr on failure. + // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2. + assert_eq!(ptr.addr(), 0x1234567); + } +} + +#[cfg(not(any( + target_os = "windows", + target_os = "macos", + target_os = "illumos", + target_os = "solaris" +)))] +fn test_reallocarray() { + unsafe { + let mut p = libc::reallocarray(std::ptr::null_mut(), 4096, 2); + assert!(!p.is_null()); + libc::free(p); + p = libc::malloc(16); + let r = libc::reallocarray(p, 2, 32); + assert!(!r.is_null()); + libc::free(r); + } +} + +fn main() { + test_malloc(); + test_calloc(); + #[cfg(not(target_os = "windows"))] + test_memalign(); + #[cfg(not(any( + target_os = "windows", + target_os = "macos", + target_os = "illumos", + target_os = "solaris" + )))] + test_reallocarray(); + + test_memcpy(); + test_strcpy(); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs new file mode 100644 index 00000000000..736e0bf8eb7 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs @@ -0,0 +1,68 @@ +//@ignore-target-windows: only very limited libc on Windows +//@compile-flags: -Zmiri-disable-isolation +#![feature(io_error_more)] +#![feature(pointer_is_aligned_to)] +#![feature(strict_provenance)] + +use std::mem::transmute; + +/// Tests whether each thread has its own `__errno_location`. +fn test_thread_local_errno() { + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + use libc::___errno as __errno_location; + #[cfg(target_os = "linux")] + use libc::__errno_location; + #[cfg(any(target_os = "macos", target_os = "freebsd"))] + use libc::__error as __errno_location; + + unsafe { + *__errno_location() = 0xBEEF; + std::thread::spawn(|| { + assert_eq!(*__errno_location(), 0); + *__errno_location() = 0xBAD1DEA; + assert_eq!(*__errno_location(), 0xBAD1DEA); + }) + .join() + .unwrap(); + assert_eq!(*__errno_location(), 0xBEEF); + } +} + +#[cfg(target_os = "linux")] +fn test_sigrt() { + let min = libc::SIGRTMIN(); + let max = libc::SIGRTMAX(); + + // "The Linux kernel supports a range of 33 different real-time + // signals, numbered 32 to 64" + assert!(min >= 32); + assert!(max >= 32); + assert!(min <= 64); + assert!(max <= 64); + + // "POSIX.1-2001 requires that an implementation support at least + // _POSIX_RTSIG_MAX (8) real-time signals." + assert!(min < max); + assert!(max - min >= 8) +} + +fn test_dlsym() { + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"notasymbol\0".as_ptr().cast()) }; + assert!(addr as usize == 0); + + let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"isatty\0".as_ptr().cast()) }; + assert!(addr as usize != 0); + let isatty: extern "C" fn(i32) -> i32 = unsafe { transmute(addr) }; + assert_eq!(isatty(999), 0); + let errno = std::io::Error::last_os_error().raw_os_error().unwrap(); + assert_eq!(errno, libc::EBADF); +} + +fn main() { + test_thread_local_errno(); + + test_dlsym(); + + #[cfg(target_os = "linux")] + test_sigrt(); +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-random.rs b/src/tools/miri/tests/pass-dep/libc/libc-random.rs new file mode 100644 index 00000000000..71e33522634 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-random.rs @@ -0,0 +1,63 @@ +//@ignore-target-windows: no libc +//@revisions: isolation no_isolation +//@[no_isolation]compile-flags: -Zmiri-disable-isolation + +fn main() { + test_getentropy(); + #[cfg(not(target_os = "macos"))] + test_getrandom(); +} + +fn test_getentropy() { + use libc::getentropy; + + let mut buf1 = [0u8; 256]; + let mut buf2 = [0u8; 257]; + unsafe { + assert_eq!(getentropy(buf1.as_mut_ptr() as *mut libc::c_void, buf1.len()), 0); + assert_eq!(getentropy(buf2.as_mut_ptr() as *mut libc::c_void, buf2.len()), -1); + assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::EIO); + } +} + +#[cfg(not(target_os = "macos"))] +fn test_getrandom() { + use std::ptr; + + let mut buf = [0u8; 5]; + unsafe { + #[cfg(target_os = "linux")] + assert_eq!( + libc::syscall( + libc::SYS_getrandom, + ptr::null_mut::(), + 0 as libc::size_t, + 0 as libc::c_uint, + ), + 0, + ); + #[cfg(target_os = "linux")] + assert_eq!( + libc::syscall( + libc::SYS_getrandom, + buf.as_mut_ptr() as *mut libc::c_void, + 5 as libc::size_t, + 0 as libc::c_uint, + ), + 5, + ); + + assert_eq!( + libc::getrandom(ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint), + 0, + ); + assert_eq!( + libc::getrandom( + buf.as_mut_ptr() as *mut libc::c_void, + 5 as libc::size_t, + 0 as libc::c_uint, + ), + 5, + ); + } +} diff --git a/src/tools/miri/tests/pass-dep/libc/libc-time.rs b/src/tools/miri/tests/pass-dep/libc/libc-time.rs new file mode 100644 index 00000000000..69c75bd8caf --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/libc-time.rs @@ -0,0 +1,93 @@ +//@ignore-target-windows: no libc on Windows +//@compile-flags: -Zmiri-disable-isolation +use std::ffi::CStr; +use std::{env, mem, ptr}; + +fn main() { + test_clocks(); + test_posix_gettimeofday(); + test_localtime_r(); +} + +/// Tests whether clock support exists at all +fn test_clocks() { + let mut tp = mem::MaybeUninit::::uninit(); + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + #[cfg(any(target_os = "linux", target_os = "freebsd"))] + { + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + let is_error = + unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + } + #[cfg(target_os = "macos")] + { + let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) }; + assert_eq!(is_error, 0); + } +} + +fn test_posix_gettimeofday() { + let mut tp = mem::MaybeUninit::::uninit(); + let tz = ptr::null_mut::(); + let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz.cast()) }; + assert_eq!(is_error, 0); + let tv = unsafe { tp.assume_init() }; + assert!(tv.tv_sec > 0); + assert!(tv.tv_usec >= 0); // Theoretically this could be 0. + + // Test that non-null tz returns an error. + let mut tz = mem::MaybeUninit::::uninit(); + let tz_ptr = tz.as_mut_ptr(); + let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz_ptr.cast()) }; + assert_eq!(is_error, -1); +} + +fn test_localtime_r() { + // Set timezone to GMT. + let key = "TZ"; + env::set_var(key, "GMT"); + + const TIME_SINCE_EPOCH: libc::time_t = 1712475836; + let custom_time_ptr = &TIME_SINCE_EPOCH; + let mut tm = libc::tm { + tm_sec: 0, + tm_min: 0, + tm_hour: 0, + tm_mday: 0, + tm_mon: 0, + tm_year: 0, + tm_wday: 0, + tm_yday: 0, + tm_isdst: 0, + tm_gmtoff: 0, + tm_zone: std::ptr::null_mut::(), + }; + let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; + + assert_eq!(tm.tm_sec, 56); + assert_eq!(tm.tm_min, 43); + assert_eq!(tm.tm_hour, 7); + assert_eq!(tm.tm_mday, 7); + assert_eq!(tm.tm_mon, 3); + assert_eq!(tm.tm_year, 124); + assert_eq!(tm.tm_wday, 0); + assert_eq!(tm.tm_yday, 97); + assert_eq!(tm.tm_isdst, -1); + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] + assert_eq!(tm.tm_gmtoff, 0); + #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] + unsafe { + assert_eq!(CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00") + }; + + // The returned value is the pointer passed in. + assert!(ptr::eq(res, &mut tm)); + + // Remove timezone setting. + env::remove_var(key); +} diff --git a/src/tools/miri/tests/pass-dep/libc/mmap.rs b/src/tools/miri/tests/pass-dep/libc/mmap.rs new file mode 100644 index 00000000000..a0787c68907 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/mmap.rs @@ -0,0 +1,181 @@ +//@ignore-target-windows: No mmap on Windows +//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance +#![feature(strict_provenance)] + +use std::io::Error; +use std::{ptr, slice}; + +fn test_mmap( + mmap: unsafe extern "C" fn( + *mut libc::c_void, + libc::size_t, + libc::c_int, + libc::c_int, + libc::c_int, + Offset, + ) -> *mut libc::c_void, +) { + let page_size = page_size::get(); + let ptr = unsafe { + mmap( + ptr::null_mut(), + page_size, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + Default::default(), + ) + }; + assert!(!ptr.is_null()); + + // Ensure that freshly mapped allocations are zeroed + let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size) }; + assert!(slice.iter().all(|b| *b == 0)); + + // Do some writes, make sure they worked + for b in slice.iter_mut() { + *b = 1; + } + assert!(slice.iter().all(|b| *b == 1)); + + // Ensure that we can munmap + let res = unsafe { libc::munmap(ptr, page_size) }; + assert_eq!(res, 0i32); + + // Test all of our error conditions + let ptr = unsafe { + mmap( + ptr::null_mut(), + page_size, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared + -1, + Default::default(), + ) + }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); + + let ptr = unsafe { + mmap( + ptr::null_mut(), + 0, // Can't map no memory + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + Default::default(), + ) + }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); + + let ptr = unsafe { + mmap( + ptr::without_provenance_mut(page_size * 64), + page_size, + libc::PROT_READ | libc::PROT_WRITE, + // We don't support MAP_FIXED + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED, + -1, + Default::default(), + ) + }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP); + + // We don't support protections other than read+write + for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] { + let ptr = unsafe { + mmap( + ptr::null_mut(), + page_size, + prot, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + Default::default(), + ) + }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP); + } + + // We report an error for mappings whose length cannot be rounded up to a multiple of + // the page size. + let ptr = unsafe { + mmap( + ptr::null_mut(), + usize::MAX - 1, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + Default::default(), + ) + }; + assert_eq!(ptr, libc::MAP_FAILED); + + // We report an error when trying to munmap an address which is not a multiple of the page size + let res = unsafe { libc::munmap(ptr::without_provenance_mut(1), page_size) }; + assert_eq!(res, -1); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); + + // We report an error when trying to munmap a length that cannot be rounded up to a multiple of + // the page size. + let res = unsafe { libc::munmap(ptr::without_provenance_mut(page_size), usize::MAX - 1) }; + assert_eq!(res, -1); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); +} + +#[cfg(target_os = "linux")] +fn test_mremap() { + let page_size = page_size::get(); + let ptr = unsafe { + libc::mmap( + ptr::null_mut(), + page_size, + libc::PROT_READ | libc::PROT_WRITE, + libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, + -1, + 0, + ) + }; + let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size) }; + for b in slice.iter_mut() { + *b = 1; + } + + let ptr = unsafe { libc::mremap(ptr, page_size, page_size * 2, libc::MREMAP_MAYMOVE) }; + assert!(!ptr.is_null()); + + let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size * 2) }; + assert!(&slice[..page_size].iter().all(|b| *b == 1)); + assert!(&slice[page_size..].iter().all(|b| *b == 0)); + + let res = unsafe { libc::munmap(ptr, page_size * 2) }; + assert_eq!(res, 0i32); + + // Test all of our error conditions + // Not aligned + let ptr = unsafe { + libc::mremap(ptr::without_provenance_mut(1), page_size, page_size, libc::MREMAP_MAYMOVE) + }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); + + // Zero size + let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, 0, libc::MREMAP_MAYMOVE) }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); + + // Not setting MREMAP_MAYMOVE + let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, page_size, 0) }; + assert_eq!(ptr, libc::MAP_FAILED); + assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); +} + +fn main() { + test_mmap(libc::mmap); + #[cfg(target_os = "linux")] + test_mmap(libc::mmap64); + #[cfg(target_os = "linux")] + test_mremap(); +} diff --git a/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs new file mode 100644 index 00000000000..14275262128 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/pthread-sync.rs @@ -0,0 +1,315 @@ +//@ignore-target-windows: No pthreads on Windows +// We use `yield` to test specific interleavings, so disable automatic preemption. +//@compile-flags: -Zmiri-preemption-rate=0 +#![feature(sync_unsafe_cell)] + +use std::cell::SyncUnsafeCell; +use std::mem::MaybeUninit; +use std::{mem, ptr, thread}; + +fn main() { + test_mutex_libc_init_recursive(); + test_mutex_libc_init_normal(); + test_mutex_libc_init_errorcheck(); + test_rwlock_libc_static_initializer(); + #[cfg(target_os = "linux")] + test_mutex_libc_static_initializer_recursive(); + + check_mutex(); + check_rwlock_write(); + check_rwlock_read_no_deadlock(); + check_cond(); + check_condattr(); +} + +fn test_mutex_libc_init_recursive() { + unsafe { + let mut attr: libc::pthread_mutexattr_t = mem::zeroed(); + assert_eq!(libc::pthread_mutexattr_init(&mut attr as *mut _), 0); + assert_eq!( + libc::pthread_mutexattr_settype(&mut attr as *mut _, libc::PTHREAD_MUTEX_RECURSIVE), + 0, + ); + let mut mutex: libc::pthread_mutex_t = mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mut attr as *mut _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM); + assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutexattr_destroy(&mut attr as *mut _), 0); + } +} + +fn test_mutex_libc_init_normal() { + unsafe { + let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed(); + assert_eq!( + libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, 0x12345678), + libc::EINVAL, + ); + assert_eq!( + libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), + 0, + ); + let mut mutex: libc::pthread_mutex_t = mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); + } +} + +fn test_mutex_libc_init_errorcheck() { + unsafe { + let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed(); + assert_eq!( + libc::pthread_mutexattr_settype( + &mut mutexattr as *mut _, + libc::PTHREAD_MUTEX_ERRORCHECK, + ), + 0, + ); + let mut mutex: libc::pthread_mutex_t = mem::zeroed(); + assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY); + assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), libc::EDEADLK); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); + assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM); + assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); + } +} + +// Only linux provides PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +// libc for macOS just has the default PTHREAD_MUTEX_INITIALIZER. +#[cfg(target_os = "linux")] +fn test_mutex_libc_static_initializer_recursive() { + let mutex = std::cell::UnsafeCell::new(libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); + unsafe { + assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); + assert_eq!(libc::pthread_mutex_unlock(mutex.get()), libc::EPERM); + assert_eq!(libc::pthread_mutex_destroy(mutex.get()), 0); + } +} + +struct SendPtr { + ptr: *mut T, +} +unsafe impl Send for SendPtr {} +impl Copy for SendPtr {} +impl Clone for SendPtr { + fn clone(&self) -> Self { + *self + } +} + +fn check_mutex() { + // Specifically *not* using `Arc` to make sure there is no synchronization apart from the mutex. + unsafe { + let data = SyncUnsafeCell::new((libc::PTHREAD_MUTEX_INITIALIZER, 0)); + let ptr = SendPtr { ptr: data.get() }; + let mut threads = Vec::new(); + + for _ in 0..3 { + let thread = thread::spawn(move || { + let ptr = ptr; // circumvent per-field closure capture + let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0); + assert_eq!(libc::pthread_mutex_lock(mutexptr), 0); + thread::yield_now(); + (*ptr.ptr).1 += 1; + assert_eq!(libc::pthread_mutex_unlock(mutexptr), 0); + }); + threads.push(thread); + } + + for thread in threads { + thread.join().unwrap(); + } + + let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0); + assert_eq!(libc::pthread_mutex_trylock(mutexptr), 0); + assert_eq!((*ptr.ptr).1, 3); + } +} + +fn check_rwlock_write() { + unsafe { + let data = SyncUnsafeCell::new((libc::PTHREAD_RWLOCK_INITIALIZER, 0)); + let ptr = SendPtr { ptr: data.get() }; + let mut threads = Vec::new(); + + for _ in 0..3 { + let thread = thread::spawn(move || { + let ptr = ptr; // circumvent per-field closure capture + let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); + assert_eq!(libc::pthread_rwlock_wrlock(rwlockptr), 0); + thread::yield_now(); + (*ptr.ptr).1 += 1; + assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0); + }); + threads.push(thread); + + let readthread = thread::spawn(move || { + let ptr = ptr; // circumvent per-field closure capture + let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); + assert_eq!(libc::pthread_rwlock_rdlock(rwlockptr), 0); + thread::yield_now(); + let val = (*ptr.ptr).1; + assert!(val >= 0 && val <= 3); + assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0); + }); + threads.push(readthread); + } + + for thread in threads { + thread.join().unwrap(); + } + + let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); + assert_eq!(libc::pthread_rwlock_tryrdlock(rwlockptr), 0); + assert_eq!((*ptr.ptr).1, 3); + } +} + +fn check_rwlock_read_no_deadlock() { + unsafe { + let l1 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + let l1 = SendPtr { ptr: l1.get() }; + let l2 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + let l2 = SendPtr { ptr: l2.get() }; + + // acquire l1 and hold it until after the other thread is done + assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0); + let handle = thread::spawn(move || { + let l1 = l1; // circumvent per-field closure capture + let l2 = l2; // circumvent per-field closure capture + // acquire l2 before the other thread + assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0); + thread::yield_now(); + assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0); + thread::yield_now(); + assert_eq!(libc::pthread_rwlock_unlock(l1.ptr), 0); + assert_eq!(libc::pthread_rwlock_unlock(l2.ptr), 0); + }); + thread::yield_now(); + assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0); + handle.join().unwrap(); + } +} + +fn check_cond() { + unsafe { + let mut cond: MaybeUninit = MaybeUninit::uninit(); + assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), ptr::null()), 0); + let cond = SendPtr { ptr: cond.as_mut_ptr() }; + + let mut mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; + let mutex = SendPtr { ptr: &mut mutex }; + + let mut data = 0; + let data = SendPtr { ptr: &mut data }; + + let t = thread::spawn(move || { + let mutex = mutex; // circumvent per-field closure capture + let cond = cond; + let data = data; + assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); + assert!(data.ptr.read() == 0); + data.ptr.write(1); + libc::pthread_cond_wait(cond.ptr, mutex.ptr); + assert!(data.ptr.read() == 3); + data.ptr.write(4); + assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); + }); + + thread::yield_now(); + + assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); + assert!(data.ptr.read() == 1); + data.ptr.write(2); + assert_eq!(libc::pthread_cond_signal(cond.ptr), 0); + thread::yield_now(); // the other thread wakes up but can't get the lock yet + assert!(data.ptr.read() == 2); + data.ptr.write(3); + assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); + + thread::yield_now(); // now the other thread gets the lock back + + assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); + assert!(data.ptr.read() == 4); + assert_eq!(libc::pthread_cond_broadcast(cond.ptr), 0); // just a smoke test + assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); + + t.join().unwrap(); + } +} + +fn check_condattr() { + unsafe { + // Just smoke-testing that these functions can be called. + let mut attr: MaybeUninit = MaybeUninit::uninit(); + assert_eq!(libc::pthread_condattr_init(attr.as_mut_ptr()), 0); + + #[cfg(not(target_os = "macos"))] // setclock-getclock do not exist on macOS + { + let clock_id = libc::CLOCK_MONOTONIC; + assert_eq!(libc::pthread_condattr_setclock(attr.as_mut_ptr(), clock_id), 0); + let mut check_clock_id = MaybeUninit::::uninit(); + assert_eq!( + libc::pthread_condattr_getclock(attr.as_mut_ptr(), check_clock_id.as_mut_ptr()), + 0 + ); + assert_eq!(check_clock_id.assume_init(), clock_id); + } + + let mut cond: MaybeUninit = MaybeUninit::uninit(); + assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()), 0); + assert_eq!(libc::pthread_condattr_destroy(attr.as_mut_ptr()), 0); + assert_eq!(libc::pthread_cond_destroy(cond.as_mut_ptr()), 0); + } +} + +// std::sync::RwLock does not even used pthread_rwlock any more. +// Do some smoke testing of the API surface. +fn test_rwlock_libc_static_initializer() { + let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); + unsafe { + assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); + assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); + + assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY); + assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); + assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); + + assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), 0); + assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY); + assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); + assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); + + assert_eq!(libc::pthread_rwlock_destroy(rw.get()), 0); + } +} diff --git a/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs b/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs new file mode 100644 index 00000000000..4c4f542dfd4 --- /dev/null +++ b/src/tools/miri/tests/pass-dep/libc/pthread-threadname.rs @@ -0,0 +1,51 @@ +//@ignore-target-windows: No pthreads on Windows +use std::ffi::CStr; +#[cfg(not(target_os = "freebsd"))] +use std::ffi::CString; +use std::thread; + +fn main() { + let long_name = std::iter::once("test_named_thread_truncation") + .chain(std::iter::repeat(" yada").take(100)) + .collect::(); + + fn set_thread_name(name: &CStr) -> i32 { + #[cfg(target_os = "linux")] + return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; + #[cfg(target_os = "freebsd")] + unsafe { + // pthread_set_name_np does not return anything + libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast()); + return 0; + }; + #[cfg(target_os = "macos")] + return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }; + } + + let result = thread::Builder::new().name(long_name.clone()).spawn(move || { + // Rust remembers the full thread name itself. + assert_eq!(thread::current().name(), Some(long_name.as_str())); + + // But the system is limited -- make sure we successfully set a truncation. + let mut buf = vec![0u8; long_name.len() + 1]; + #[cfg(not(target_os = "freebsd"))] + unsafe { + libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) + }; + #[cfg(target_os = "freebsd")] + unsafe { + libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) + }; + let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); + assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars + assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); + + // Also test directly calling pthread_setname to check its return value. + assert_eq!(set_thread_name(&cstr), 0); + // But with a too long name it should fail (except on FreeBSD where the + // function has no return, hence cannot indicate failure). + #[cfg(not(target_os = "freebsd"))] + assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0); + }); + result.unwrap().join().unwrap(); +} diff --git a/src/tools/miri/tests/pass-dep/malloc.rs b/src/tools/miri/tests/pass-dep/malloc.rs deleted file mode 100644 index 35cd137931f..00000000000 --- a/src/tools/miri/tests/pass-dep/malloc.rs +++ /dev/null @@ -1,48 +0,0 @@ -//@ignore-target-windows: No libc on Windows - -use core::{ptr, slice}; - -fn main() { - // Test that small allocations sometimes *are* not very aligned. - let saw_unaligned = (0..64).any(|_| unsafe { - let p = libc::malloc(3); - libc::free(p); - (p as usize) % 4 != 0 // find any that this is *not* 4-aligned - }); - assert!(saw_unaligned); - - unsafe { - // Use calloc for initialized memory - let p1 = libc::calloc(20, 1); - - // old size < new size - let p2 = libc::realloc(p1, 40); - let slice = slice::from_raw_parts(p2 as *const u8, 20); - assert_eq!(&slice, &[0_u8; 20]); - - // old size == new size - let p3 = libc::realloc(p2, 40); - let slice = slice::from_raw_parts(p3 as *const u8, 20); - assert_eq!(&slice, &[0_u8; 20]); - - // old size > new size - let p4 = libc::realloc(p3, 10); - let slice = slice::from_raw_parts(p4 as *const u8, 10); - assert_eq!(&slice, &[0_u8; 10]); - - libc::free(p4); - } - - unsafe { - // Realloc with size 0 is okay for the null pointer - let p2 = libc::realloc(ptr::null_mut(), 0); - assert!(p2.is_null()); - } - - unsafe { - let p1 = libc::realloc(ptr::null_mut(), 20); - assert!(!p1.is_null()); - - libc::free(p1); - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs b/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs deleted file mode 100644 index 5c29a1b15a7..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/env-cleanup-data-race.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@compile-flags: -Zmiri-disable-isolation -Zmiri-preemption-rate=0 -//@ignore-target-windows: No libc on Windows - -use std::ffi::CStr; -use std::thread; - -fn main() { - unsafe { - thread::spawn(|| { - // Access the environment in another thread without taking the env lock - let s = libc::getenv("MIRI_ENV_VAR_TEST\0".as_ptr().cast()); - if s.is_null() { - panic!("null"); - } - let _s = String::from_utf8_lossy(CStr::from_ptr(s).to_bytes()); - }); - thread::yield_now(); - // After the main thread exits, env vars will be cleaned up -- but because we have not *joined* - // the other thread, those accesses technically race with those in the other thread. - // We don't want to emit an error here, though. - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.rs b/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.rs deleted file mode 100644 index 307906f2583..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@only-target-apple: F_FULLFSYNC only on apple systems -//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace - -use std::io::Error; - -fn main() { - // test `fcntl(F_FULLFSYNC)` - unsafe { - assert_eq!(libc::fcntl(1, libc::F_FULLFSYNC, 0), -1); - assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EPERM)); - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.stderr b/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.stderr deleted file mode 100644 index 09a24e1e5d7..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/fcntl_f-fullfsync_apple.stderr +++ /dev/null @@ -1,2 +0,0 @@ -warning: `fcntl` was made to return an error due to isolation - diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs deleted file mode 100644 index 5185db0b0e2..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ignore-target-windows: no libc on Windows -//@compile-flags: -Zmiri-isolation-error=warn-nobacktrace -//@normalize-stderr-test: "(stat(x)?)" -> "$$STAT" - -use std::ffi::CString; -use std::fs; -use std::io::{Error, ErrorKind}; - -fn main() { - // test `fcntl(F_DUPFD): should work even with isolation.` - unsafe { - assert!(libc::fcntl(1, libc::F_DUPFD, 0) >= 0); - } - - // test `readlink` - let symlink_c_str = CString::new("foo.txt").unwrap(); - let mut buf = vec![0; "foo_link.txt".len() + 1]; - unsafe { - assert_eq!(libc::readlink(symlink_c_str.as_ptr(), buf.as_mut_ptr(), buf.len()), -1); - assert_eq!(Error::last_os_error().raw_os_error(), Some(libc::EACCES)); - } - - // test `stat` - let err = fs::metadata("foo.txt").unwrap_err(); - assert_eq!(err.kind(), ErrorKind::PermissionDenied); - // check that it is the right kind of `PermissionDenied` - assert_eq!(err.raw_os_error(), Some(libc::EACCES)); -} diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr deleted file mode 100644 index b0cadfb970b..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.stderr +++ /dev/null @@ -1,4 +0,0 @@ -warning: `readlink` was made to return an error due to isolation - -warning: `$STAT` was made to return an error due to isolation - diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs.rs deleted file mode 100644 index 0dd849a045d..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs.rs +++ /dev/null @@ -1,430 +0,0 @@ -//@ignore-target-windows: no libc on Windows -//@compile-flags: -Zmiri-disable-isolation - -#![feature(io_error_more)] -#![feature(io_error_uncategorized)] - -use std::ffi::{CStr, CString, OsString}; -use std::fs::{canonicalize, remove_dir_all, remove_file, File}; -use std::io::{Error, ErrorKind, Write}; -use std::os::unix::ffi::OsStrExt; -use std::os::unix::io::AsRawFd; -use std::path::PathBuf; - -#[path = "../../utils/mod.rs"] -mod utils; - -fn main() { - test_dup_stdout_stderr(); - test_canonicalize_too_long(); - test_rename(); - test_ftruncate::(libc::ftruncate); - #[cfg(target_os = "linux")] - test_ftruncate::(libc::ftruncate64); - test_readlink(); - test_file_open_unix_allow_two_args(); - test_file_open_unix_needs_three_args(); - test_file_open_unix_extra_third_arg(); - #[cfg(target_os = "linux")] - test_o_tmpfile_flag(); - test_posix_mkstemp(); - test_posix_realpath_alloc(); - test_posix_realpath_noalloc(); - test_posix_realpath_errors(); - #[cfg(target_os = "linux")] - test_posix_fadvise(); - #[cfg(target_os = "linux")] - test_sync_file_range(); - test_isatty(); -} - -/// Prepare: compute filename and make sure the file does not exist. -fn prepare(filename: &str) -> PathBuf { - let path = utils::tmp().join(filename); - // Clean the paths for robustness. - remove_file(&path).ok(); - path -} - -/// Prepare directory: compute directory name and make sure it does not exist. -#[allow(unused)] -fn prepare_dir(dirname: &str) -> PathBuf { - let path = utils::tmp().join(&dirname); - // Clean the directory for robustness. - remove_dir_all(&path).ok(); - path -} - -/// Prepare like above, and also write some initial content to the file. -fn prepare_with_content(filename: &str, content: &[u8]) -> PathBuf { - let path = prepare(filename); - let mut file = File::create(&path).unwrap(); - file.write(content).unwrap(); - path -} - -fn test_file_open_unix_allow_two_args() { - let path = prepare_with_content("test_file_open_unix_allow_two_args.txt", &[]); - - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::(); - let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY) }; -} - -fn test_file_open_unix_needs_three_args() { - let path = prepare_with_content("test_file_open_unix_needs_three_args.txt", &[]); - - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::(); - let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT, 0o666) }; -} - -fn test_file_open_unix_extra_third_arg() { - let path = prepare_with_content("test_file_open_unix_extra_third_arg.txt", &[]); - - let mut name = path.into_os_string(); - name.push("\0"); - let name_ptr = name.as_bytes().as_ptr().cast::(); - let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 42) }; -} - -fn test_dup_stdout_stderr() { - let bytes = b"hello dup fd\n"; - unsafe { - let new_stdout = libc::fcntl(1, libc::F_DUPFD, 0); - let new_stderr = libc::fcntl(2, libc::F_DUPFD, 0); - libc::write(new_stdout, bytes.as_ptr() as *const libc::c_void, bytes.len()); - libc::write(new_stderr, bytes.as_ptr() as *const libc::c_void, bytes.len()); - } -} - -fn test_canonicalize_too_long() { - // Make sure we get an error for long paths. - let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap()); - assert!(canonicalize(too_long).is_err()); -} - -fn test_readlink() { - let bytes = b"Hello, World!\n"; - let path = prepare_with_content("miri_test_fs_link_target.txt", bytes); - let expected_path = path.as_os_str().as_bytes(); - - let symlink_path = prepare("miri_test_fs_symlink.txt"); - std::os::unix::fs::symlink(&path, &symlink_path).unwrap(); - - // Test that the expected string gets written to a buffer of proper - // length, and that a trailing null byte is not written. - let symlink_c_str = CString::new(symlink_path.as_os_str().as_bytes()).unwrap(); - let symlink_c_ptr = symlink_c_str.as_ptr(); - - // Make the buf one byte larger than it needs to be, - // and check that the last byte is not overwritten. - let mut large_buf = vec![0xFF; expected_path.len() + 1]; - let res = - unsafe { libc::readlink(symlink_c_ptr, large_buf.as_mut_ptr().cast(), large_buf.len()) }; - // Check that the resolved path was properly written into the buf. - assert_eq!(&large_buf[..(large_buf.len() - 1)], expected_path); - assert_eq!(large_buf.last(), Some(&0xFF)); - assert_eq!(res, large_buf.len() as isize - 1); - - // Test that the resolved path is truncated if the provided buffer - // is too small. - let mut small_buf = [0u8; 2]; - let res = - unsafe { libc::readlink(symlink_c_ptr, small_buf.as_mut_ptr().cast(), small_buf.len()) }; - assert_eq!(small_buf, &expected_path[..small_buf.len()]); - assert_eq!(res, small_buf.len() as isize); - - // Test that we report a proper error for a missing path. - let bad_path = CString::new("MIRI_MISSING_FILE_NAME").unwrap(); - let res = unsafe { - libc::readlink(bad_path.as_ptr(), small_buf.as_mut_ptr().cast(), small_buf.len()) - }; - assert_eq!(res, -1); - assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); -} - -fn test_rename() { - let path1 = prepare("miri_test_libc_fs_source.txt"); - let path2 = prepare("miri_test_libc_fs_rename_destination.txt"); - - let file = File::create(&path1).unwrap(); - drop(file); - - let c_path1 = CString::new(path1.as_os_str().as_bytes()).expect("CString::new failed"); - let c_path2 = CString::new(path2.as_os_str().as_bytes()).expect("CString::new failed"); - - // Renaming should succeed - unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) }; - // Check that old file path isn't present - assert_eq!(ErrorKind::NotFound, path1.metadata().unwrap_err().kind()); - // Check that the file has moved successfully - assert!(path2.metadata().unwrap().is_file()); - - // Renaming a nonexistent file should fail - let res = unsafe { libc::rename(c_path1.as_ptr(), c_path2.as_ptr()) }; - assert_eq!(res, -1); - assert_eq!(Error::last_os_error().kind(), ErrorKind::NotFound); - - remove_file(&path2).unwrap(); -} - -fn test_ftruncate>( - ftruncate: unsafe extern "C" fn(fd: libc::c_int, length: T) -> libc::c_int, -) { - // libc::off_t is i32 in target i686-unknown-linux-gnu - // https://docs.rs/libc/latest/i686-unknown-linux-gnu/libc/type.off_t.html - - let bytes = b"hello"; - let path = prepare("miri_test_libc_fs_ftruncate.txt"); - let mut file = File::create(&path).unwrap(); - file.write(bytes).unwrap(); - file.sync_all().unwrap(); - assert_eq!(file.metadata().unwrap().len(), 5); - - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); - let fd = unsafe { libc::open(c_path.as_ptr(), libc::O_RDWR) }; - - // Truncate to a bigger size - let mut res = unsafe { ftruncate(fd, T::from(10)) }; - assert_eq!(res, 0); - assert_eq!(file.metadata().unwrap().len(), 10); - - // Write after truncate - file.write(b"dup").unwrap(); - file.sync_all().unwrap(); - assert_eq!(file.metadata().unwrap().len(), 10); - - // Truncate to smaller size - res = unsafe { ftruncate(fd, T::from(2)) }; - assert_eq!(res, 0); - assert_eq!(file.metadata().unwrap().len(), 2); - - remove_file(&path).unwrap(); -} - -#[cfg(target_os = "linux")] -fn test_o_tmpfile_flag() { - use std::fs::{create_dir, OpenOptions}; - use std::os::unix::fs::OpenOptionsExt; - let dir_path = prepare_dir("miri_test_fs_dir"); - create_dir(&dir_path).unwrap(); - // test that the `O_TMPFILE` custom flag gracefully errors instead of stopping execution - assert_eq!( - Some(libc::EOPNOTSUPP), - OpenOptions::new() - .read(true) - .write(true) - .custom_flags(libc::O_TMPFILE) - .open(dir_path) - .unwrap_err() - .raw_os_error(), - ); -} - -fn test_posix_mkstemp() { - use std::ffi::OsStr; - use std::os::unix::io::FromRawFd; - use std::path::Path; - - let valid_template = "fooXXXXXX"; - // C needs to own this as `mkstemp(3)` says: - // "Since it will be modified, `template` must not be a string constant, but - // should be declared as a character array." - // There seems to be no `as_mut_ptr` on `CString` so we need to use `into_raw`. - let ptr = CString::new(valid_template).unwrap().into_raw(); - let fd = unsafe { libc::mkstemp(ptr) }; - // Take ownership back in Rust to not leak memory. - let slice = unsafe { CString::from_raw(ptr) }; - assert!(fd > 0); - let osstr = OsStr::from_bytes(slice.to_bytes()); - let path: &Path = osstr.as_ref(); - let name = path.file_name().unwrap().to_string_lossy(); - assert!(name.ne("fooXXXXXX")); - assert!(name.starts_with("foo")); - assert_eq!(name.len(), 9); - assert_eq!( - name.chars().skip(3).filter(char::is_ascii_alphanumeric).collect::>().len(), - 6 - ); - let file = unsafe { File::from_raw_fd(fd) }; - assert!(file.set_len(0).is_ok()); - - let invalid_templates = vec!["foo", "barXX", "XXXXXXbaz", "whatXXXXXXever", "X"]; - for t in invalid_templates { - let ptr = CString::new(t).unwrap().into_raw(); - let fd = unsafe { libc::mkstemp(ptr) }; - let _ = unsafe { CString::from_raw(ptr) }; - // "On error, -1 is returned, and errno is set to - // indicate the error" - assert_eq!(fd, -1); - let e = std::io::Error::last_os_error(); - assert_eq!(e.raw_os_error(), Some(libc::EINVAL)); - assert_eq!(e.kind(), std::io::ErrorKind::InvalidInput); - } -} - -/// Test allocating variant of `realpath`. -fn test_posix_realpath_alloc() { - use std::os::unix::ffi::OsStrExt; - use std::os::unix::ffi::OsStringExt; - - let buf; - let path = utils::tmp().join("miri_test_libc_posix_realpath_alloc"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); - - // Cleanup before test. - remove_file(&path).ok(); - // Create file. - drop(File::create(&path).unwrap()); - unsafe { - let r = libc::realpath(c_path.as_ptr(), std::ptr::null_mut()); - assert!(!r.is_null()); - buf = CStr::from_ptr(r).to_bytes().to_vec(); - libc::free(r as *mut _); - } - let canonical = PathBuf::from(OsString::from_vec(buf)); - assert_eq!(path.file_name(), canonical.file_name()); - - // Cleanup after test. - remove_file(&path).unwrap(); -} - -/// Test non-allocating variant of `realpath`. -fn test_posix_realpath_noalloc() { - use std::ffi::{CStr, CString}; - use std::os::unix::ffi::OsStrExt; - - let path = utils::tmp().join("miri_test_libc_posix_realpath_noalloc"); - let c_path = CString::new(path.as_os_str().as_bytes()).expect("CString::new failed"); - - let mut v = vec![0; libc::PATH_MAX as usize]; - - // Cleanup before test. - remove_file(&path).ok(); - // Create file. - drop(File::create(&path).unwrap()); - unsafe { - let r = libc::realpath(c_path.as_ptr(), v.as_mut_ptr()); - assert!(!r.is_null()); - } - let c = unsafe { CStr::from_ptr(v.as_ptr()) }; - let canonical = PathBuf::from(c.to_str().expect("CStr to str")); - - assert_eq!(path.file_name(), canonical.file_name()); - - // Cleanup after test. - remove_file(&path).unwrap(); -} - -/// Test failure cases for `realpath`. -fn test_posix_realpath_errors() { - use std::ffi::CString; - use std::io::ErrorKind; - - // Test nonexistent path returns an error. - let c_path = CString::new("./nothing_to_see_here").expect("CString::new failed"); - let r = unsafe { libc::realpath(c_path.as_ptr(), std::ptr::null_mut()) }; - assert!(r.is_null()); - let e = std::io::Error::last_os_error(); - assert_eq!(e.raw_os_error(), Some(libc::ENOENT)); - assert_eq!(e.kind(), ErrorKind::NotFound); -} - -#[cfg(target_os = "linux")] -fn test_posix_fadvise() { - use std::io::Write; - - let path = utils::tmp().join("miri_test_libc_posix_fadvise.txt"); - // Cleanup before test - remove_file(&path).ok(); - - // Set up an open file - let mut file = File::create(&path).unwrap(); - let bytes = b"Hello, World!\n"; - file.write(bytes).unwrap(); - - // Test calling posix_fadvise on a file. - let result = unsafe { - libc::posix_fadvise( - file.as_raw_fd(), - 0, - bytes.len().try_into().unwrap(), - libc::POSIX_FADV_DONTNEED, - ) - }; - drop(file); - remove_file(&path).unwrap(); - assert_eq!(result, 0); -} - -#[cfg(target_os = "linux")] -fn test_sync_file_range() { - use std::io::Write; - - let path = utils::tmp().join("miri_test_libc_sync_file_range.txt"); - // Cleanup before test. - remove_file(&path).ok(); - - // Write to a file. - let mut file = File::create(&path).unwrap(); - let bytes = b"Hello, World!\n"; - file.write(bytes).unwrap(); - - // Test calling sync_file_range on the file. - let result_1 = unsafe { - libc::sync_file_range( - file.as_raw_fd(), - 0, - 0, - libc::SYNC_FILE_RANGE_WAIT_BEFORE - | libc::SYNC_FILE_RANGE_WRITE - | libc::SYNC_FILE_RANGE_WAIT_AFTER, - ) - }; - drop(file); - - // Test calling sync_file_range on a file opened for reading. - let file = File::open(&path).unwrap(); - let result_2 = unsafe { - libc::sync_file_range( - file.as_raw_fd(), - 0, - 0, - libc::SYNC_FILE_RANGE_WAIT_BEFORE - | libc::SYNC_FILE_RANGE_WRITE - | libc::SYNC_FILE_RANGE_WAIT_AFTER, - ) - }; - drop(file); - - remove_file(&path).unwrap(); - assert_eq!(result_1, 0); - assert_eq!(result_2, 0); -} - -fn test_isatty() { - // Testing whether our isatty shim returns the right value would require controlling whether - // these streams are actually TTYs, which is hard. - // For now, we just check that these calls are supported at all. - unsafe { - libc::isatty(libc::STDIN_FILENO); - libc::isatty(libc::STDOUT_FILENO); - libc::isatty(libc::STDERR_FILENO); - - // But when we open a file, it is definitely not a TTY. - let path = utils::tmp().join("notatty.txt"); - // Cleanup before test. - remove_file(&path).ok(); - let file = File::create(&path).unwrap(); - - assert_eq!(libc::isatty(file.as_raw_fd()), 0); - assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::ENOTTY); - - // Cleanup after test. - drop(file); - remove_file(&path).unwrap(); - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.stderr b/src/tools/miri/tests/pass-dep/shims/libc-fs.stderr deleted file mode 100644 index b6fa69e3d5d..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs.stderr +++ /dev/null @@ -1 +0,0 @@ -hello dup fd diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs.stdout b/src/tools/miri/tests/pass-dep/shims/libc-fs.stdout deleted file mode 100644 index b6fa69e3d5d..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-fs.stdout +++ /dev/null @@ -1 +0,0 @@ -hello dup fd diff --git a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs b/src/tools/miri/tests/pass-dep/shims/libc-misc.rs deleted file mode 100644 index 32898d49593..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-misc.rs +++ /dev/null @@ -1,242 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-disable-isolation -#![feature(io_error_more)] -#![feature(pointer_is_aligned_to)] -#![feature(strict_provenance)] - -use std::mem::{self, transmute}; -use std::ptr; - -/// Tests whether each thread has its own `__errno_location`. -fn test_thread_local_errno() { - #[cfg(any(target_os = "illumos", target_os = "solaris"))] - use libc::___errno as __errno_location; - #[cfg(target_os = "linux")] - use libc::__errno_location; - #[cfg(any(target_os = "macos", target_os = "freebsd"))] - use libc::__error as __errno_location; - - unsafe { - *__errno_location() = 0xBEEF; - std::thread::spawn(|| { - assert_eq!(*__errno_location(), 0); - *__errno_location() = 0xBAD1DEA; - assert_eq!(*__errno_location(), 0xBAD1DEA); - }) - .join() - .unwrap(); - assert_eq!(*__errno_location(), 0xBEEF); - } -} - -fn test_memcpy() { - unsafe { - let src = [1i8, 2, 3]; - let dest = libc::calloc(3, 1); - libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); - let slc = std::slice::from_raw_parts(dest as *const i8, 3); - assert_eq!(*slc, [1i8, 2, 3]); - libc::free(dest); - } - - unsafe { - let src = [1i8, 2, 3]; - let dest = libc::calloc(4, 1); - libc::memcpy(dest, src.as_ptr() as *const libc::c_void, 3); - let slc = std::slice::from_raw_parts(dest as *const i8, 4); - assert_eq!(*slc, [1i8, 2, 3, 0]); - libc::free(dest); - } - - unsafe { - let src = 123_i32; - let mut dest = 0_i32; - libc::memcpy( - &mut dest as *mut i32 as *mut libc::c_void, - &src as *const i32 as *const libc::c_void, - mem::size_of::(), - ); - assert_eq!(dest, src); - } - - unsafe { - let src = Some(123); - let mut dest: Option = None; - libc::memcpy( - &mut dest as *mut Option as *mut libc::c_void, - &src as *const Option as *const libc::c_void, - mem::size_of::>(), - ); - assert_eq!(dest, src); - } - - unsafe { - let src = &123; - let mut dest = &42; - libc::memcpy( - &mut dest as *mut &'static i32 as *mut libc::c_void, - &src as *const &'static i32 as *const libc::c_void, - mem::size_of::<&'static i32>(), - ); - assert_eq!(*dest, 123); - } -} - -fn test_strcpy() { - use std::ffi::{CStr, CString}; - - // case: src_size equals dest_size - unsafe { - let src = CString::new("rust").unwrap(); - let size = src.as_bytes_with_nul().len(); - let dest = libc::malloc(size); - libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); - assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); - libc::free(dest); - } - - // case: src_size is less than dest_size - unsafe { - let src = CString::new("rust").unwrap(); - let size = src.as_bytes_with_nul().len(); - let dest = libc::malloc(size + 1); - libc::strcpy(dest as *mut libc::c_char, src.as_ptr()); - assert_eq!(CStr::from_ptr(dest as *const libc::c_char), src.as_ref()); - libc::free(dest); - } -} - -#[cfg(target_os = "linux")] -fn test_sigrt() { - let min = libc::SIGRTMIN(); - let max = libc::SIGRTMAX(); - - // "The Linux kernel supports a range of 33 different real-time - // signals, numbered 32 to 64" - assert!(min >= 32); - assert!(max >= 32); - assert!(min <= 64); - assert!(max <= 64); - - // "POSIX.1-2001 requires that an implementation support at least - // _POSIX_RTSIG_MAX (8) real-time signals." - assert!(min < max); - assert!(max - min >= 8) -} - -fn test_dlsym() { - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"notasymbol\0".as_ptr().cast()) }; - assert!(addr as usize == 0); - - let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, b"isatty\0".as_ptr().cast()) }; - assert!(addr as usize != 0); - let isatty: extern "C" fn(i32) -> i32 = unsafe { transmute(addr) }; - assert_eq!(isatty(999), 0); - let errno = std::io::Error::last_os_error().raw_os_error().unwrap(); - assert_eq!(errno, libc::EBADF); -} - -#[cfg(not(any(target_os = "macos", target_os = "illumos", target_os = "solaris")))] -fn test_reallocarray() { - unsafe { - let mut p = libc::reallocarray(std::ptr::null_mut(), 4096, 2); - assert!(!p.is_null()); - libc::free(p); - p = libc::malloc(16); - let r = libc::reallocarray(p, 2, 32); - assert!(!r.is_null()); - libc::free(r); - } -} - -fn test_memalign() { - // A normal allocation. - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 8; - let size = 64; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } - - // Align > size. - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 64; - let size = 8; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } - - // Size not multiple of align - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 16; - let size = 31; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - assert!(!ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - ptr.cast::().write_bytes(1, size); - libc::free(ptr); - } - - // Size == 0 - unsafe { - let mut ptr: *mut libc::c_void = ptr::null_mut(); - let align = 64; - let size = 0; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), 0); - // We are not required to return null if size == 0, but we currently do. - // It's fine to remove this assert if we start returning non-null pointers. - assert!(ptr.is_null()); - assert!(ptr.is_aligned_to(align)); - // Regardless of what we return, it must be `free`able. - libc::free(ptr); - } - - // Non-power of 2 align - unsafe { - let mut ptr: *mut libc::c_void = ptr::without_provenance_mut(0x1234567); - let align = 15; - let size = 8; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL); - // The pointer is not modified on failure, posix_memalign(3) says: - // > On Linux (and other systems), posix_memalign() does not modify memptr on failure. - // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2. - assert_eq!(ptr.addr(), 0x1234567); - } - - // Too small align (smaller than ptr) - unsafe { - let mut ptr: *mut libc::c_void = ptr::without_provenance_mut(0x1234567); - let align = std::mem::size_of::() / 2; - let size = 8; - assert_eq!(libc::posix_memalign(&mut ptr, align, size), libc::EINVAL); - // The pointer is not modified on failure, posix_memalign(3) says: - // > On Linux (and other systems), posix_memalign() does not modify memptr on failure. - // > A requirement standardizing this behavior was added in POSIX.1-2008 TC2. - assert_eq!(ptr.addr(), 0x1234567); - } -} - -fn main() { - test_thread_local_errno(); - - test_dlsym(); - - test_memcpy(); - test_strcpy(); - - test_memalign(); - #[cfg(not(any(target_os = "macos", target_os = "illumos", target_os = "solaris")))] - test_reallocarray(); - - #[cfg(target_os = "linux")] - test_sigrt(); -} diff --git a/src/tools/miri/tests/pass-dep/shims/libc-random.rs b/src/tools/miri/tests/pass-dep/shims/libc-random.rs deleted file mode 100644 index 71e33522634..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-random.rs +++ /dev/null @@ -1,63 +0,0 @@ -//@ignore-target-windows: no libc -//@revisions: isolation no_isolation -//@[no_isolation]compile-flags: -Zmiri-disable-isolation - -fn main() { - test_getentropy(); - #[cfg(not(target_os = "macos"))] - test_getrandom(); -} - -fn test_getentropy() { - use libc::getentropy; - - let mut buf1 = [0u8; 256]; - let mut buf2 = [0u8; 257]; - unsafe { - assert_eq!(getentropy(buf1.as_mut_ptr() as *mut libc::c_void, buf1.len()), 0); - assert_eq!(getentropy(buf2.as_mut_ptr() as *mut libc::c_void, buf2.len()), -1); - assert_eq!(std::io::Error::last_os_error().raw_os_error().unwrap(), libc::EIO); - } -} - -#[cfg(not(target_os = "macos"))] -fn test_getrandom() { - use std::ptr; - - let mut buf = [0u8; 5]; - unsafe { - #[cfg(target_os = "linux")] - assert_eq!( - libc::syscall( - libc::SYS_getrandom, - ptr::null_mut::(), - 0 as libc::size_t, - 0 as libc::c_uint, - ), - 0, - ); - #[cfg(target_os = "linux")] - assert_eq!( - libc::syscall( - libc::SYS_getrandom, - buf.as_mut_ptr() as *mut libc::c_void, - 5 as libc::size_t, - 0 as libc::c_uint, - ), - 5, - ); - - assert_eq!( - libc::getrandom(ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint), - 0, - ); - assert_eq!( - libc::getrandom( - buf.as_mut_ptr() as *mut libc::c_void, - 5 as libc::size_t, - 0 as libc::c_uint, - ), - 5, - ); - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/libc-time.rs b/src/tools/miri/tests/pass-dep/shims/libc-time.rs deleted file mode 100644 index 69c75bd8caf..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/libc-time.rs +++ /dev/null @@ -1,93 +0,0 @@ -//@ignore-target-windows: no libc on Windows -//@compile-flags: -Zmiri-disable-isolation -use std::ffi::CStr; -use std::{env, mem, ptr}; - -fn main() { - test_clocks(); - test_posix_gettimeofday(); - test_localtime_r(); -} - -/// Tests whether clock support exists at all -fn test_clocks() { - let mut tp = mem::MaybeUninit::::uninit(); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - #[cfg(any(target_os = "linux", target_os = "freebsd"))] - { - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - let is_error = - unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - } - #[cfg(target_os = "macos")] - { - let is_error = unsafe { libc::clock_gettime(libc::CLOCK_UPTIME_RAW, tp.as_mut_ptr()) }; - assert_eq!(is_error, 0); - } -} - -fn test_posix_gettimeofday() { - let mut tp = mem::MaybeUninit::::uninit(); - let tz = ptr::null_mut::(); - let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz.cast()) }; - assert_eq!(is_error, 0); - let tv = unsafe { tp.assume_init() }; - assert!(tv.tv_sec > 0); - assert!(tv.tv_usec >= 0); // Theoretically this could be 0. - - // Test that non-null tz returns an error. - let mut tz = mem::MaybeUninit::::uninit(); - let tz_ptr = tz.as_mut_ptr(); - let is_error = unsafe { libc::gettimeofday(tp.as_mut_ptr(), tz_ptr.cast()) }; - assert_eq!(is_error, -1); -} - -fn test_localtime_r() { - // Set timezone to GMT. - let key = "TZ"; - env::set_var(key, "GMT"); - - const TIME_SINCE_EPOCH: libc::time_t = 1712475836; - let custom_time_ptr = &TIME_SINCE_EPOCH; - let mut tm = libc::tm { - tm_sec: 0, - tm_min: 0, - tm_hour: 0, - tm_mday: 0, - tm_mon: 0, - tm_year: 0, - tm_wday: 0, - tm_yday: 0, - tm_isdst: 0, - tm_gmtoff: 0, - tm_zone: std::ptr::null_mut::(), - }; - let res = unsafe { libc::localtime_r(custom_time_ptr, &mut tm) }; - - assert_eq!(tm.tm_sec, 56); - assert_eq!(tm.tm_min, 43); - assert_eq!(tm.tm_hour, 7); - assert_eq!(tm.tm_mday, 7); - assert_eq!(tm.tm_mon, 3); - assert_eq!(tm.tm_year, 124); - assert_eq!(tm.tm_wday, 0); - assert_eq!(tm.tm_yday, 97); - assert_eq!(tm.tm_isdst, -1); - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] - assert_eq!(tm.tm_gmtoff, 0); - #[cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))] - unsafe { - assert_eq!(CStr::from_ptr(tm.tm_zone).to_str().unwrap(), "+00") - }; - - // The returned value is the pointer passed in. - assert!(ptr::eq(res, &mut tm)); - - // Remove timezone setting. - env::remove_var(key); -} diff --git a/src/tools/miri/tests/pass-dep/shims/mmap.rs b/src/tools/miri/tests/pass-dep/shims/mmap.rs deleted file mode 100644 index 5acdedc67bf..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/mmap.rs +++ /dev/null @@ -1,181 +0,0 @@ -//@ignore-target-windows: No libc on Windows -//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -#![feature(strict_provenance)] - -use std::io::Error; -use std::{ptr, slice}; - -fn test_mmap( - mmap: unsafe extern "C" fn( - *mut libc::c_void, - libc::size_t, - libc::c_int, - libc::c_int, - libc::c_int, - Offset, - ) -> *mut libc::c_void, -) { - let page_size = page_size::get(); - let ptr = unsafe { - mmap( - ptr::null_mut(), - page_size, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - Default::default(), - ) - }; - assert!(!ptr.is_null()); - - // Ensure that freshly mapped allocations are zeroed - let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size) }; - assert!(slice.iter().all(|b| *b == 0)); - - // Do some writes, make sure they worked - for b in slice.iter_mut() { - *b = 1; - } - assert!(slice.iter().all(|b| *b == 1)); - - // Ensure that we can munmap - let res = unsafe { libc::munmap(ptr, page_size) }; - assert_eq!(res, 0i32); - - // Test all of our error conditions - let ptr = unsafe { - mmap( - ptr::null_mut(), - page_size, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_SHARED, // Can't be both private and shared - -1, - Default::default(), - ) - }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); - - let ptr = unsafe { - mmap( - ptr::null_mut(), - 0, // Can't map no memory - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - Default::default(), - ) - }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); - - let ptr = unsafe { - mmap( - ptr::without_provenance_mut(page_size * 64), - page_size, - libc::PROT_READ | libc::PROT_WRITE, - // We don't support MAP_FIXED - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED, - -1, - Default::default(), - ) - }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP); - - // We don't support protections other than read+write - for prot in [libc::PROT_NONE, libc::PROT_EXEC, libc::PROT_READ, libc::PROT_WRITE] { - let ptr = unsafe { - mmap( - ptr::null_mut(), - page_size, - prot, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - Default::default(), - ) - }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::ENOTSUP); - } - - // We report an error for mappings whose length cannot be rounded up to a multiple of - // the page size. - let ptr = unsafe { - mmap( - ptr::null_mut(), - usize::MAX - 1, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - Default::default(), - ) - }; - assert_eq!(ptr, libc::MAP_FAILED); - - // We report an error when trying to munmap an address which is not a multiple of the page size - let res = unsafe { libc::munmap(ptr::without_provenance_mut(1), page_size) }; - assert_eq!(res, -1); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); - - // We report an error when trying to munmap a length that cannot be rounded up to a multiple of - // the page size. - let res = unsafe { libc::munmap(ptr::without_provenance_mut(page_size), usize::MAX - 1) }; - assert_eq!(res, -1); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); -} - -#[cfg(target_os = "linux")] -fn test_mremap() { - let page_size = page_size::get(); - let ptr = unsafe { - libc::mmap( - ptr::null_mut(), - page_size, - libc::PROT_READ | libc::PROT_WRITE, - libc::MAP_PRIVATE | libc::MAP_ANONYMOUS, - -1, - 0, - ) - }; - let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size) }; - for b in slice.iter_mut() { - *b = 1; - } - - let ptr = unsafe { libc::mremap(ptr, page_size, page_size * 2, libc::MREMAP_MAYMOVE) }; - assert!(!ptr.is_null()); - - let slice = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, page_size * 2) }; - assert!(&slice[..page_size].iter().all(|b| *b == 1)); - assert!(&slice[page_size..].iter().all(|b| *b == 0)); - - let res = unsafe { libc::munmap(ptr, page_size * 2) }; - assert_eq!(res, 0i32); - - // Test all of our error conditions - // Not aligned - let ptr = unsafe { - libc::mremap(ptr::without_provenance_mut(1), page_size, page_size, libc::MREMAP_MAYMOVE) - }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); - - // Zero size - let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, 0, libc::MREMAP_MAYMOVE) }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); - - // Not setting MREMAP_MAYMOVE - let ptr = unsafe { libc::mremap(ptr::null_mut(), page_size, page_size, 0) }; - assert_eq!(ptr, libc::MAP_FAILED); - assert_eq!(Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL); -} - -fn main() { - test_mmap(libc::mmap); - #[cfg(target_os = "linux")] - test_mmap(libc::mmap64); - #[cfg(target_os = "linux")] - test_mremap(); -} diff --git a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs b/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs deleted file mode 100644 index 12d3f2b6f14..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/pthread-sync.rs +++ /dev/null @@ -1,315 +0,0 @@ -//@ignore-target-windows: No libc on Windows -// We use `yield` to test specific interleavings, so disable automatic preemption. -//@compile-flags: -Zmiri-preemption-rate=0 -#![feature(sync_unsafe_cell)] - -use std::cell::SyncUnsafeCell; -use std::mem::MaybeUninit; -use std::{mem, ptr, thread}; - -fn main() { - test_mutex_libc_init_recursive(); - test_mutex_libc_init_normal(); - test_mutex_libc_init_errorcheck(); - test_rwlock_libc_static_initializer(); - #[cfg(target_os = "linux")] - test_mutex_libc_static_initializer_recursive(); - - check_mutex(); - check_rwlock_write(); - check_rwlock_read_no_deadlock(); - check_cond(); - check_condattr(); -} - -fn test_mutex_libc_init_recursive() { - unsafe { - let mut attr: libc::pthread_mutexattr_t = mem::zeroed(); - assert_eq!(libc::pthread_mutexattr_init(&mut attr as *mut _), 0); - assert_eq!( - libc::pthread_mutexattr_settype(&mut attr as *mut _, libc::PTHREAD_MUTEX_RECURSIVE), - 0, - ); - let mut mutex: libc::pthread_mutex_t = mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mut attr as *mut _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM); - assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutexattr_destroy(&mut attr as *mut _), 0); - } -} - -fn test_mutex_libc_init_normal() { - unsafe { - let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed(); - assert_eq!( - libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, 0x12345678), - libc::EINVAL, - ); - assert_eq!( - libc::pthread_mutexattr_settype(&mut mutexattr as *mut _, libc::PTHREAD_MUTEX_NORMAL), - 0, - ); - let mut mutex: libc::pthread_mutex_t = mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); - } -} - -fn test_mutex_libc_init_errorcheck() { - unsafe { - let mut mutexattr: libc::pthread_mutexattr_t = mem::zeroed(); - assert_eq!( - libc::pthread_mutexattr_settype( - &mut mutexattr as *mut _, - libc::PTHREAD_MUTEX_ERRORCHECK, - ), - 0, - ); - let mut mutex: libc::pthread_mutex_t = mem::zeroed(); - assert_eq!(libc::pthread_mutex_init(&mut mutex as *mut _, &mutexattr as *const _), 0); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), libc::EBUSY); - assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), libc::EDEADLK); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_trylock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0); - assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), libc::EPERM); - assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0); - } -} - -// Only linux provides PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, -// libc for macOS just has the default PTHREAD_MUTEX_INITIALIZER. -#[cfg(target_os = "linux")] -fn test_mutex_libc_static_initializer_recursive() { - let mutex = std::cell::UnsafeCell::new(libc::PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - unsafe { - assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_trylock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_lock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_unlock(mutex.get()), 0); - assert_eq!(libc::pthread_mutex_unlock(mutex.get()), libc::EPERM); - assert_eq!(libc::pthread_mutex_destroy(mutex.get()), 0); - } -} - -struct SendPtr { - ptr: *mut T, -} -unsafe impl Send for SendPtr {} -impl Copy for SendPtr {} -impl Clone for SendPtr { - fn clone(&self) -> Self { - *self - } -} - -fn check_mutex() { - // Specifically *not* using `Arc` to make sure there is no synchronization apart from the mutex. - unsafe { - let data = SyncUnsafeCell::new((libc::PTHREAD_MUTEX_INITIALIZER, 0)); - let ptr = SendPtr { ptr: data.get() }; - let mut threads = Vec::new(); - - for _ in 0..3 { - let thread = thread::spawn(move || { - let ptr = ptr; // circumvent per-field closure capture - let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0); - assert_eq!(libc::pthread_mutex_lock(mutexptr), 0); - thread::yield_now(); - (*ptr.ptr).1 += 1; - assert_eq!(libc::pthread_mutex_unlock(mutexptr), 0); - }); - threads.push(thread); - } - - for thread in threads { - thread.join().unwrap(); - } - - let mutexptr = ptr::addr_of_mut!((*ptr.ptr).0); - assert_eq!(libc::pthread_mutex_trylock(mutexptr), 0); - assert_eq!((*ptr.ptr).1, 3); - } -} - -fn check_rwlock_write() { - unsafe { - let data = SyncUnsafeCell::new((libc::PTHREAD_RWLOCK_INITIALIZER, 0)); - let ptr = SendPtr { ptr: data.get() }; - let mut threads = Vec::new(); - - for _ in 0..3 { - let thread = thread::spawn(move || { - let ptr = ptr; // circumvent per-field closure capture - let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); - assert_eq!(libc::pthread_rwlock_wrlock(rwlockptr), 0); - thread::yield_now(); - (*ptr.ptr).1 += 1; - assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0); - }); - threads.push(thread); - - let readthread = thread::spawn(move || { - let ptr = ptr; // circumvent per-field closure capture - let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); - assert_eq!(libc::pthread_rwlock_rdlock(rwlockptr), 0); - thread::yield_now(); - let val = (*ptr.ptr).1; - assert!(val >= 0 && val <= 3); - assert_eq!(libc::pthread_rwlock_unlock(rwlockptr), 0); - }); - threads.push(readthread); - } - - for thread in threads { - thread.join().unwrap(); - } - - let rwlockptr = ptr::addr_of_mut!((*ptr.ptr).0); - assert_eq!(libc::pthread_rwlock_tryrdlock(rwlockptr), 0); - assert_eq!((*ptr.ptr).1, 3); - } -} - -fn check_rwlock_read_no_deadlock() { - unsafe { - let l1 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - let l1 = SendPtr { ptr: l1.get() }; - let l2 = SyncUnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - let l2 = SendPtr { ptr: l2.get() }; - - // acquire l1 and hold it until after the other thread is done - assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0); - let handle = thread::spawn(move || { - let l1 = l1; // circumvent per-field closure capture - let l2 = l2; // circumvent per-field closure capture - // acquire l2 before the other thread - assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0); - thread::yield_now(); - assert_eq!(libc::pthread_rwlock_rdlock(l1.ptr), 0); - thread::yield_now(); - assert_eq!(libc::pthread_rwlock_unlock(l1.ptr), 0); - assert_eq!(libc::pthread_rwlock_unlock(l2.ptr), 0); - }); - thread::yield_now(); - assert_eq!(libc::pthread_rwlock_rdlock(l2.ptr), 0); - handle.join().unwrap(); - } -} - -fn check_cond() { - unsafe { - let mut cond: MaybeUninit = MaybeUninit::uninit(); - assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), ptr::null()), 0); - let cond = SendPtr { ptr: cond.as_mut_ptr() }; - - let mut mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; - let mutex = SendPtr { ptr: &mut mutex }; - - let mut data = 0; - let data = SendPtr { ptr: &mut data }; - - let t = thread::spawn(move || { - let mutex = mutex; // circumvent per-field closure capture - let cond = cond; - let data = data; - assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); - assert!(data.ptr.read() == 0); - data.ptr.write(1); - libc::pthread_cond_wait(cond.ptr, mutex.ptr); - assert!(data.ptr.read() == 3); - data.ptr.write(4); - assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); - }); - - thread::yield_now(); - - assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); - assert!(data.ptr.read() == 1); - data.ptr.write(2); - assert_eq!(libc::pthread_cond_signal(cond.ptr), 0); - thread::yield_now(); // the other thread wakes up but can't get the lock yet - assert!(data.ptr.read() == 2); - data.ptr.write(3); - assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); - - thread::yield_now(); // now the other thread gets the lock back - - assert_eq!(libc::pthread_mutex_lock(mutex.ptr), 0); - assert!(data.ptr.read() == 4); - assert_eq!(libc::pthread_cond_broadcast(cond.ptr), 0); // just a smoke test - assert_eq!(libc::pthread_mutex_unlock(mutex.ptr), 0); - - t.join().unwrap(); - } -} - -fn check_condattr() { - unsafe { - // Just smoke-testing that these functions can be called. - let mut attr: MaybeUninit = MaybeUninit::uninit(); - assert_eq!(libc::pthread_condattr_init(attr.as_mut_ptr()), 0); - - #[cfg(not(target_os = "macos"))] // setclock-getclock do not exist on macOS - { - let clock_id = libc::CLOCK_MONOTONIC; - assert_eq!(libc::pthread_condattr_setclock(attr.as_mut_ptr(), clock_id), 0); - let mut check_clock_id = MaybeUninit::::uninit(); - assert_eq!( - libc::pthread_condattr_getclock(attr.as_mut_ptr(), check_clock_id.as_mut_ptr()), - 0 - ); - assert_eq!(check_clock_id.assume_init(), clock_id); - } - - let mut cond: MaybeUninit = MaybeUninit::uninit(); - assert_eq!(libc::pthread_cond_init(cond.as_mut_ptr(), attr.as_ptr()), 0); - assert_eq!(libc::pthread_condattr_destroy(attr.as_mut_ptr()), 0); - assert_eq!(libc::pthread_cond_destroy(cond.as_mut_ptr()), 0); - } -} - -// std::sync::RwLock does not even used pthread_rwlock any more. -// Do some smoke testing of the API surface. -fn test_rwlock_libc_static_initializer() { - let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); - unsafe { - assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_rdlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); - assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); - - assert_eq!(libc::pthread_rwlock_wrlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY); - assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); - assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); - - assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), 0); - assert_eq!(libc::pthread_rwlock_tryrdlock(rw.get()), libc::EBUSY); - assert_eq!(libc::pthread_rwlock_trywrlock(rw.get()), libc::EBUSY); - assert_eq!(libc::pthread_rwlock_unlock(rw.get()), 0); - - assert_eq!(libc::pthread_rwlock_destroy(rw.get()), 0); - } -} diff --git a/src/tools/miri/tests/pass-dep/shims/pthread-threadname.rs b/src/tools/miri/tests/pass-dep/shims/pthread-threadname.rs deleted file mode 100644 index bc782044d4d..00000000000 --- a/src/tools/miri/tests/pass-dep/shims/pthread-threadname.rs +++ /dev/null @@ -1,51 +0,0 @@ -//@ignore-target-windows: No libc on Windows -use std::ffi::CStr; -#[cfg(not(target_os = "freebsd"))] -use std::ffi::CString; -use std::thread; - -fn main() { - let long_name = std::iter::once("test_named_thread_truncation") - .chain(std::iter::repeat(" yada").take(100)) - .collect::(); - - fn set_thread_name(name: &CStr) -> i32 { - #[cfg(target_os = "linux")] - return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; - #[cfg(target_os = "freebsd")] - unsafe { - // pthread_set_name_np does not return anything - libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr().cast()); - return 0; - }; - #[cfg(target_os = "macos")] - return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }; - } - - let result = thread::Builder::new().name(long_name.clone()).spawn(move || { - // Rust remembers the full thread name itself. - assert_eq!(thread::current().name(), Some(long_name.as_str())); - - // But the system is limited -- make sure we successfully set a truncation. - let mut buf = vec![0u8; long_name.len() + 1]; - #[cfg(not(target_os = "freebsd"))] - unsafe { - libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) - }; - #[cfg(target_os = "freebsd")] - unsafe { - libc::pthread_get_name_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) - }; - let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); - assert!(cstr.to_bytes().len() >= 15, "name is too short: len={}", cstr.to_bytes().len()); // POSIX seems to promise at least 15 chars - assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); - - // Also test directly calling pthread_setname to check its return value. - assert_eq!(set_thread_name(&cstr), 0); - // But with a too long name it should fail (except on FreeBSD where the - // function has no return, hence cannot indicate failure). - #[cfg(not(target_os = "freebsd"))] - assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0); - }); - result.unwrap().join().unwrap(); -} -- cgit 1.4.1-3-g733a5