diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml new file mode 100644 index 00000000..51e14794 --- /dev/null +++ b/.github/workflows/sanitizer.yml @@ -0,0 +1,17 @@ +name: Sanitizer checks + +on: [push, pull_request] + +jobs: + asan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Envinfo + run: npx envinfo + - name: ASAN + run: | + mkdir build + cd build && cmake .. -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug + cmake --build . && ./uv_run_tests_a + diff --git a/CMakeLists.txt b/CMakeLists.txt index e648b00b..10236dec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,13 @@ if(QEMU) add_definitions(-D__QEMU__=1) endif() +option(ASAN "Enable AddressSanitizer (ASan)" OFF) +if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") + add_definitions(-D__ASAN__=1) + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") +endif() + # Compiler check string(CONCAT is-msvc $, diff --git a/test/test-error.c b/test/test-error.c index 7f44f4a1..35d108a4 100644 --- a/test/test-error.c +++ b/test/test-error.c @@ -37,6 +37,9 @@ * See https://github.com/joyent/libuv/issues/210 */ TEST_IMPL(error_message) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif char buf[32]; /* Cop out. Can't do proper checks on systems with diff --git a/test/test-fs-copyfile.c b/test/test-fs-copyfile.c index c785a4b5..fa00fe4e 100644 --- a/test/test-fs-copyfile.c +++ b/test/test-fs-copyfile.c @@ -96,6 +96,9 @@ static void touch_file(const char* name, unsigned int size) { TEST_IMPL(fs_copyfile) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif const char src[] = "test_file_src"; uv_loop_t* loop; uv_fs_t req; diff --git a/test/test-fs-event.c b/test/test-fs-event.c index 28a6a1eb..0992d598 100644 --- a/test/test-fs-event.c +++ b/test/test-fs-event.c @@ -673,6 +673,9 @@ TEST_IMPL(fs_event_watch_file_exact_path) { TEST_IMPL(fs_event_watch_file_twice) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); #endif const char path[] = "test/fixtures/empty_file"; uv_fs_event_t watchers[2]; diff --git a/test/test-fs-readdir.c b/test/test-fs-readdir.c index 5efc853c..cccaa743 100644 --- a/test/test-fs-readdir.c +++ b/test/test-fs-readdir.c @@ -230,6 +230,9 @@ static void file_opendir_cb(uv_fs_t* req) { } TEST_IMPL(fs_readdir_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif const char* path; int r; diff --git a/test/test-fs.c b/test/test-fs.c index 63189d01..aca7a2ae 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -2837,6 +2837,9 @@ TEST_IMPL(fs_scandir_non_existent_dir) { } TEST_IMPL(fs_scandir_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif const char* path; int r; @@ -3083,6 +3086,9 @@ static void fs_read_bufs(int add_flags) { uv_fs_req_cleanup(&close_req); } TEST_IMPL(fs_read_bufs) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif fs_read_bufs(0); fs_read_bufs(UV_FS_O_FILEMAP); diff --git a/test/test-ipc.c b/test/test-ipc.c index 39ef4f11..ba3ba737 100644 --- a/test/test-ipc.c +++ b/test/test-ipc.c @@ -693,6 +693,11 @@ static void ipc_on_connection(uv_stream_t* server, int status) { } +static void close_and_free_cb(uv_handle_t* handle) { + close_cb_called++; + free(handle); +} + static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) { int r; uv_buf_t buf; @@ -721,7 +726,7 @@ static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) { on_tcp_child_process_read); ASSERT_EQ(r, 0); - uv_close((uv_handle_t*)conn, close_cb); + uv_close((uv_handle_t*)conn, close_and_free_cb); } diff --git a/test/test-pipe-connect-error.c b/test/test-pipe-connect-error.c index ebb2a6ca..8bba328a 100644 --- a/test/test-pipe-connect-error.c +++ b/test/test-pipe-connect-error.c @@ -76,6 +76,9 @@ TEST_IMPL(pipe_connect_bad_name) { TEST_IMPL(pipe_connect_to_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif const char* path = "test/fixtures/empty_file"; uv_pipe_t client; uv_connect_t req; diff --git a/test/test-platform-output.c b/test/test-platform-output.c index f547ddfd..341c7ae5 100644 --- a/test/test-platform-output.c +++ b/test/test-platform-output.c @@ -155,6 +155,7 @@ TEST_IMPL(platform_output) { printf(" username: %s\n", pwd.username); printf(" shell: %s\n", pwd.shell); printf(" home directory: %s\n", pwd.homedir); + uv_os_free_passwd(&pwd); pid = uv_os_getpid(); ASSERT(pid > 0); diff --git a/test/test-tty.c b/test/test-tty.c index a9d38f22..ff7d388d 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -426,6 +426,9 @@ TEST_IMPL(tty_pty) { #if defined(__QEMU__) RETURN_SKIP("Test does not currently work in QEMU"); #endif +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif #if defined(__APPLE__) || \ defined(__DragonFly__) || \