diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2023-02-10 00:04:10 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2023-02-11 23:50:05 +0300 |
commit | d7e3062a03cab55e2551bd0353efd31c408c80dd (patch) | |
tree | 4e37cf79a8668eae1ad5bf9c9631f40ba3f73462 /tests | |
parent | dac8f776145e437de006fe416b4cf0678b5f9523 (diff) | |
download | bdwgc-d7e3062a03cab55e2551bd0353efd31c408c80dd.tar.gz |
Add testing of remaining API functions (gctest and leaktest)
Previously the functions were marked as UNTESTED in gctest.
* tests/gctest.c: Include javaxfc.h unconditionally.
* tests/gctest.c (tiny_reverse_test_inner): New function.
* tests/gctest.c [!GC_NO_FINALIZATION] (dummy_finalizer): Likewise.
* tests/gctest.c [THREADS && GC_PTHREADS && !MSWINCE && !MSWIN_XBOX1
&& !NO_CRT && !NO_TEST_ENDTHREADEX] (TEST_ENDTHREADEX): Define macro.
* tests/gctest.c [THREADS && GC_PTHREADS && !MSWINCE && !MSWIN_XBOX1
&& !NO_CRT && !NO_TEST_ENDTHREADEX] (tiny_reverse_test): Specify
return type to unsigned.
* tests/gctest.c [THREADS] (tiny_reverse_test): Call
tiny_reverse_test_inner() instead of check_ints() calls.
* tests/gctest.c [THREADS && GC_PTHREADS && !GC_NO_PTHREAD_CANCEL]
(tiny_reverse_test): Call GC_pthread_cancel().
* tests/gctest.c [THREADS && GC_PTHREADS && GC_HAVE_PTHREAD_EXIT]
(tiny_reverse_test): Call GC_pthread_exit().
* tests/gctest.c [THREADS && GC_WIN32_THREADS && !GC_PTHREADS]
(tiny_reverse_test): Call GC_endthreadex(0) or GC_ExitThread(0).
* tests/gctest.c [THREADS && !GC_PTHREADS && GC_WIN32_THREADS
&& TEST_ENDTHREADEX] (fork_a_thread): Define thread_id local variable
of unsigned type instead of DWORD; call GC_beginthreadex() instead of
CreateThread().
* tests/gctest.c (finalizer): Do not define if GC_NO_FINALIZATION.
* tests/gctest.c (run_one_test): Define x local variable even if
DBG_HDRS_ALL.
* tests/gctest.c [!DBG_HDRS_ALL] (run_one_test): Call
GC_posix_memalign().
* tests/gctest.c (run_one_test): Call GC_STRNDUP() and strlen().
* tests/gctest.c [GC_REQUIRE_WCSDUP] (run_one_test): Call GC_WCSDUP().
* tests/gctest.c [!GC_NO_FINALIZATION] (run_one_test): Call
GC_MALLOC_ATOMIC() and pass its result to
GC_register_disappearing_link(), GC_REGISTER_FINALIZER_UNREACHABLE().
* tests/gctest.c [!NO_TEST_HANDLE_FORK && THREADS] (run_one_test): Call
tiny_reverse_test_inner() instead of tiny_reverse_test().
* tests/gctest [!GC_NO_FINALIZATION && !GC_TOGGLE_REFS_NOT_NEEDED]
(run_one_test): Call GC_toggleref_add().
* tests/gctest.c [!NO_DEBUGGING] (run_one_test): Call GC_is_tmp_root()
and GC_count_set_marks_in_hblk(dp).
* tests/gctest.c [CPPCHECK] (main): Remove UNTESTED() for
GC_debug_generic_or_special_malloc, GC_debug_register_displacement,
GC_post_incr, GC_pre_incr, GC_debug_gcj_malloc, GC_debug_strndup,
GC_strndup, GC_posix_memalign, GC_clear_roots, GC_is_tmp_root,
GC_print_trace, GC_debug_register_finalizer_unreachable,
GC_register_disappearing_link, GC_should_invoke_finalizers,
GC_finalize_all, GC_stop_world_external, GC_start_world_external,
GC_pthread_cancel, GC_pthread_exit, GC_pthread_sigmask,
GC_atfork_child, GC_atfork_parent, GC_atfork_prepare,
GC_set_handle_fork, GC_start_mark_threads, GC_exclude_static_roots,
GC_new_proc, GC_register_describe_type_fn,
GC_register_has_static_roots_callback.
* tests/gctest.c [CPPCHECK && !NO_DEBUGGING] (main): Remove UNTESTED()
for GC_count_set_marks_in_hblk.
* tests/gctest.c [CPPCHECK && !GC_NO_FINALIZATION
&& !GC_TOGGLE_REFS_NOT_NEEDED] (main): Remove UNTESTED() for
GC_toggleref_add.
* tests/gctest.c [CPPCHECK && !OS2 && !MACOS && !GC_ANDROID_LOG
&& !MSWIN32 && !MSWINCE] (main): Remove UNTESTED() for GC_set_log_fd.
* tests/gctest.c [CPPCHECK && !REDIRECT_MALLOC_IN_HEADER
&& REDIRECT_MALLOC] (main): Remove UNTESTED() for strndup, strdup.
* tests/gctest.c [CPPCHECK && !REDIRECT_MALLOC_IN_HEADER
&& REDIRECT_REALLOC] (main): Remove UNTESTED() for realloc().
* tests/gctest.c [CPPCHECK && GC_WIN32_THREADS] (main): Remove
UNTESTED() for GC_ExitThread, GC_beginthreadex, GC_endthreadex.
* tests/gctest.c [!PCR && !GC_WIN32_THREADS && !GC_PTHREADS
&& !GC_ANDROID_LOG && !MACOS && !OS2 && !MSWIN32 && !MSWINCE] (main):
Call GC_set_log_fd().
* tests/gctest.c [GC_PTHREADS] (describe_norm_type, has_static_roots):
New function.
* tests/gctest.c [GC_PTHREADS && TRACE_BUF] (main): Call
GC_print_trace().
* tests/gctest.c [GC_PTHREADS && GC_NO_PTHREAD_SIGMASK] (main): Define
blocked local variable and call GC_pthread_sigmask() (twice).
* tests/gctest.c [GC_PTHREADS] (main): Call GC_exclude_static_roots(),
GC_register_has_static_roots_callback, GC_register_describe_type_fn
(after set_print_procs).
* tests/gctest.c [GC_PTHREADS && GC_GCJ_SUPPORT] (main): Call
GC_new_proc().
* tests/gctest.c [GC_PTHREADS] (main): Call GC_stop_world_external(),
GC_start_world_external(), and GC_clear_roots() (almost at the end of
main).
* tests/gctest.c [GC_PTHREADS && !GC_NO_FINALIZATION
&& !JAVA_FINALIZATION_NOT_NEEDED] (main): Call GC_finalize_all().
* tests/gctest.c [GC_PTHREADS && CPPCHECK && !GC_NO_DLOPEN] (main):
Remove UNTESTED() for GC_dlopen.
* tests/gctest.c [GC_PTHREADS && !GC_NO_DLOPEN && !DARWIN
&& !GC_WIN32_THREADS] (main): Call GC_dlopen() and dlclose().
* tests/leak.c (main): Call strdup() instead of malloc() on loop
iteration 0; do not call reallocarray() or realloc() for loop
iterations 1 and 2; do not call free() for loop iteration 1; call
strndup() instead of malloc() on iteration 3..6 of the last loop;
reduce number of iteration from N_TESTS/2 to N_TESTS/8 of the last
loop.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/gctest.c | 351 | ||||
-rw-r--r-- | tests/leak.c | 13 |
2 files changed, 224 insertions, 140 deletions
diff --git a/tests/gctest.c b/tests/gctest.c index 709d65cd..03dcd585 100644 --- a/tests/gctest.c +++ b/tests/gctest.c @@ -41,6 +41,7 @@ # undef GC_NO_THREAD_REDIRECTS #endif #include "gc.h" +#include "gc/javaxfc.h" #ifndef NTHREADS /* Number of additional threads to fork. */ # define NTHREADS 5 /* Excludes main thread, which also runs a test. */ @@ -360,7 +361,7 @@ struct fake_vtable gcj_class_struct2 = struct GC_ms_entry * fake_gcj_mark_proc(word * addr, struct GC_ms_entry *mark_stack_ptr, struct GC_ms_entry *mark_stack_limit, - word env ) + word env) { sexpr x; if (1 == env) { @@ -379,7 +380,6 @@ struct GC_ms_entry * fake_gcj_mark_proc(word * addr, #endif /* GC_GCJ_SUPPORT */ - sexpr small_cons (sexpr x, sexpr y) { sexpr r = GC_NEW(struct SEXPR); @@ -635,15 +635,27 @@ void check_marks_int_list(sexpr x) # define TINY_REVERSE_UPPER_VALUE 10 # endif -# if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) - DWORD __stdcall -# else + void tiny_reverse_test_inner(void) + { + int i; + + for (i = 0; i < 5; ++i) { + check_ints(reverse(reverse(ints(1, TINY_REVERSE_UPPER_VALUE))), + 1, TINY_REVERSE_UPPER_VALUE); + } + } + +# if defined(GC_PTHREADS) void* +# elif !defined(MSWINCE) && !defined(MSWIN_XBOX1) && !defined(NO_CRT) \ + && !defined(NO_TEST_ENDTHREADEX) +# define TEST_ENDTHREADEX + unsigned __stdcall +# else + DWORD __stdcall # endif tiny_reverse_test(void *p_resumed) { - int i; - # if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_OSF1_THREADS) \ && defined(SIGNAL_BASED_STOP_WORLD) if (p_resumed != NULL) { @@ -654,15 +666,38 @@ void check_marks_int_list(sexpr x) # else (void)p_resumed; # endif - - for (i = 0; i < 5; ++i) { - check_ints(reverse(reverse(ints(1, TINY_REVERSE_UPPER_VALUE))), - 1, TINY_REVERSE_UPPER_VALUE); - } + tiny_reverse_test_inner(); # if defined(GC_ENABLE_SUSPEND_THREAD) /* Force collection from a thread. */ GC_gcollect(); # endif +# if defined(GC_PTHREADS) && !defined(GC_NO_PTHREAD_CANCEL) + { + static volatile AO_t tiny_cancel_cnt = 0; + + if (AO_fetch_and_add1(&tiny_cancel_cnt) % 3 == 0 + && GC_pthread_cancel(pthread_self()) != 0) { + GC_printf("pthread_cancel failed\n"); + FAIL; + } + } +# endif +# if defined(GC_PTHREADS) && defined(GC_HAVE_PTHREAD_EXIT) \ + || (defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)) + { + static volatile AO_t tiny_exit_cnt = 0; + + if ((AO_fetch_and_add1(&tiny_exit_cnt) & 1) == 0) { +# ifdef TEST_ENDTHREADEX + GC_endthreadex(0); +# elif defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) + GC_ExitThread(0); +# else + GC_pthread_exit(p_resumed); +# endif + } + } +# endif return 0; } @@ -675,7 +710,7 @@ void check_marks_int_list(sexpr x) static volatile AO_t forked_cnt = 0; volatile AO_t *p_resumed = NULL; - if ((AO_fetch_and_add1(&forked_cnt) % 2) == 0) { + if (AO_fetch_and_add1(&forked_cnt) % 2 == 0) { p_resumed = GC_NEW(AO_t); CHECK_OUT_OF_MEMORY(p_resumed); AO_fetch_and_add1(&collectable_count); @@ -731,12 +766,22 @@ void check_marks_int_list(sexpr x) # elif defined(GC_WIN32_THREADS) void fork_a_thread(void) { - DWORD thread_id; HANDLE h; - h = CreateThread((SECURITY_ATTRIBUTES *)NULL, (word)0, - tiny_reverse_test, NULL, (DWORD)0, &thread_id); +# ifdef TEST_ENDTHREADEX + unsigned thread_id; + + h = (HANDLE)GC_beginthreadex(NULL /* security */, + 0 /* stack_size */, tiny_reverse_test, + NULL /* arglist */, 0 /* initflag */, + &thread_id); +# else + DWORD thread_id; + + h = CreateThread((SECURITY_ATTRIBUTES *)NULL, (word)0, + tiny_reverse_test, NULL, (DWORD)0, &thread_id); /* Explicitly specify types of the */ /* arguments to test the prototype. */ +# endif if (h == (HANDLE)NULL) { GC_printf("Small thread creation failed, errcode= %d\n", (int)GetLastError()); @@ -949,19 +994,27 @@ typedef struct treenode { int finalized_count = 0; int dropped_something = 0; -void GC_CALLBACK finalizer(void * obj, void * client_data) -{ - tn * t = (tn *)obj; +#ifndef GC_NO_FINALIZATION + void GC_CALLBACK finalizer(void *obj, void *client_data) + { + tn *t = (tn *)obj; + + FINALIZER_LOCK(); + if ((int)(GC_word)client_data != t -> level) { + GC_printf("Wrong finalization data - collector is broken\n"); + FAIL; + } + finalized_count++; + t -> level = -1; /* detect duplicate finalization immediately */ + FINALIZER_UNLOCK(); + } - FINALIZER_LOCK(); - if ((int)(GC_word)client_data != t -> level) { - GC_printf("Wrong finalization data - collector is broken\n"); - FAIL; + void GC_CALLBACK dummy_finalizer(void *obj, void *client_data) + { + UNUSED_ARG(obj); + UNUSED_ARG(client_data); } - finalized_count++; - t -> level = -1; /* detect duplicate finalization immediately */ - FINALIZER_UNLOCK(); -} +#endif /* !GC_NO_FINALIZATION */ # define MAX_FINALIZED ((NTHREADS+1)*4000) @@ -1031,25 +1084,25 @@ tn * mktree(int n) GC_REGISTER_FINALIZER((void *)result, finalizer, (void *)(GC_word)n, (GC_finalization_proc *)0, (void * *)0); if (my_index >= MAX_FINALIZED) { - GC_printf("live_indicators overflowed\n"); - FAIL; + GC_printf("live_indicators overflowed\n"); + FAIL; } live_indicators[my_index] = 13; if (GC_GENERAL_REGISTER_DISAPPEARING_LINK( - (void * *)(&(live_indicators[my_index])), result) != 0) { - GC_printf("GC_general_register_disappearing_link failed\n"); - FAIL; + (void **)(&(live_indicators[my_index])), result) != 0) { + GC_printf("GC_general_register_disappearing_link failed\n"); + FAIL; } if (GC_move_disappearing_link((void **)(&(live_indicators[my_index])), - (void **)(&(live_indicators[my_index]))) != GC_SUCCESS) { - GC_printf("GC_move_disappearing_link(link,link) failed\n"); - FAIL; + (void **)(&(live_indicators[my_index]))) != GC_SUCCESS) { + GC_printf("GC_move_disappearing_link(link,link) failed\n"); + FAIL; } *new_link = (void *)live_indicators[my_index]; if (GC_move_disappearing_link((void **)(&(live_indicators[my_index])), new_link) != GC_SUCCESS) { - GC_printf("GC_move_disappearing_link(new_link) failed\n"); - FAIL; + GC_printf("GC_move_disappearing_link(new_link) failed\n"); + FAIL; } /* Note: if other thread is performing fork at this moment, */ /* then the stack of the current thread is dropped (together */ @@ -1057,18 +1110,18 @@ tn * mktree(int n) /* GC_dl_hashtbl entry with the link equal to new_link will be */ /* removed when a collection occurs (as expected). */ if (GC_unregister_disappearing_link(new_link) == 0) { - GC_printf("GC_unregister_disappearing_link failed\n"); - FAIL; + GC_printf("GC_unregister_disappearing_link failed\n"); + FAIL; } if (GC_move_disappearing_link((void **)(&(live_indicators[my_index])), new_link) != GC_NOT_FOUND) { - GC_printf("GC_move_disappearing_link(new_link) failed 2\n"); - FAIL; + GC_printf("GC_move_disappearing_link(new_link) failed 2\n"); + FAIL; } if (GC_GENERAL_REGISTER_DISAPPEARING_LINK( - (void * *)(&(live_indicators[my_index])), result) != 0) { - GC_printf("GC_general_register_disappearing_link failed 2\n"); - FAIL; + (void **)(&(live_indicators[my_index])), result) != 0) { + GC_printf("GC_general_register_disappearing_link failed 2\n"); + FAIL; } # ifndef GC_LONG_REFS_NOT_NEEDED if (GC_REGISTER_LONG_LINK(&live_long_refs[my_index], result) != 0) { @@ -1434,8 +1487,9 @@ void * GC_CALLBACK set_stackbottom(void *cd) void run_one_test(void) { + char *x; # ifndef DBG_HDRS_ALL - char *x, *y; + char *y; char **z; # endif # ifndef NO_CLOCK @@ -1555,7 +1609,8 @@ void run_one_test(void) GC_printf("GC_is_valid_displacement produced incorrect result\n"); FAIL; } - { + + { size_t i; void *p; @@ -1574,7 +1629,9 @@ void run_one_test(void) FAIL; } } - } + (void)GC_posix_memalign(&p, 64, 1); + AO_fetch_and_add1(&collectable_count); + } # ifndef GC_NO_VALLOC { void *p = GC_valloc(78); @@ -1609,6 +1666,49 @@ void run_one_test(void) } # endif # endif /* DBG_HDRS_ALL */ + x = GC_STRNDUP("abc", 1); + CHECK_OUT_OF_MEMORY(x); + AO_fetch_and_add1(&atomic_count); + if (strlen(x) != 1) { + GC_printf("GC_strndup unexpected result\n"); + FAIL; + } +# ifdef GC_REQUIRE_WCSDUP + { + static const wchar_t ws[] = { 'a', 'b', 'c', 0 }; + void *p = GC_WCSDUP(ws); + + CHECK_OUT_OF_MEMORY(p); + AO_fetch_and_add1(&atomic_count); + } +# endif +# ifndef GC_NO_FINALIZATION + if (!GC_get_find_leak()) { + void **p = (void **)GC_MALLOC_ATOMIC(sizeof(void*)); + + CHECK_OUT_OF_MEMORY(p); + AO_fetch_and_add1(&atomic_count); + *p = x; + if (GC_register_disappearing_link(p) != 0) { + GC_printf("GC_register_disappearing_link failed\n"); + FAIL; + } + if (GC_get_java_finalization()) { + GC_finalization_proc ofn = 0; + void *ocd = NULL; + + GC_REGISTER_FINALIZER_UNREACHABLE(p, dummy_finalizer, NULL, + &ofn, &ocd); + if (ofn != 0 || ocd != NULL) { + GC_printf("GC_register_finalizer_unreachable unexpected result\n"); + FAIL; + } + } +# ifndef GC_TOGGLE_REFS_NOT_NEEDED + (void)GC_toggleref_add(p, 1); +# endif + } +# endif /* Test floating point alignment */ { double *dp = GC_NEW(double); @@ -1620,6 +1720,9 @@ void run_one_test(void) CHECK_OUT_OF_MEMORY(dp); AO_fetch_and_add1(&collectable_count); *dp = 1.0; +# ifndef NO_DEBUGGING + (void)GC_count_set_marks_in_hblk(dp); +# endif } /* Test size 0 allocation a bit more */ { @@ -1707,7 +1810,7 @@ void run_one_test(void) if (print_stats) GC_log_printf("Starting tiny reverse test, pid= %ld\n", (long)child_pid); - tiny_reverse_test(0); + tiny_reverse_test_inner(); GC_gcollect(); # endif if (print_stats) @@ -1761,6 +1864,9 @@ void run_one_test(void) # endif /* Run reverse_test a second time, so we hopefully notice corruption. */ reverse_test(); +# ifndef NO_DEBUGGING + (void)GC_is_tmp_root((/* no volatile */ void *)&atomic_count); +# endif # ifndef NO_CLOCK if (print_stats) { GET_TIME(reverse_time); @@ -2066,7 +2172,6 @@ void enable_incremental_mode(void) } #if defined(CPPCHECK) -# include "gc/javaxfc.h" /* for GC_finalize_all */ # define UNTESTED(sym) GC_noop1((word)&sym) #endif @@ -2161,15 +2266,6 @@ void enable_incremental_mode(void) # endif # if defined(CPPCHECK) /* Entry points we should be testing, but aren't. */ -# ifndef GC_DEBUG - UNTESTED(GC_debug_generic_or_special_malloc); - UNTESTED(GC_debug_register_displacement); - UNTESTED(GC_post_incr); - UNTESTED(GC_pre_incr); -# ifdef GC_GCJ_SUPPORT - UNTESTED(GC_debug_gcj_malloc); -# endif -# endif # ifdef AMIGA # ifdef GC_AMIGA_FASTALLOC UNTESTED(GC_amiga_get_mem); @@ -2182,57 +2278,16 @@ void enable_incremental_mode(void) UNTESTED(GC_MacTemporaryNewPtr); # endif UNTESTED(GC_abort_on_oom); - UNTESTED(GC_debug_strndup); UNTESTED(GC_deinit); - UNTESTED(GC_strndup); - UNTESTED(GC_posix_memalign); - UNTESTED(GC_new_proc); - UNTESTED(GC_clear_roots); - UNTESTED(GC_exclude_static_roots); - UNTESTED(GC_register_describe_type_fn); - UNTESTED(GC_register_has_static_roots_callback); # ifndef NO_DEBUGGING - UNTESTED(GC_count_set_marks_in_hblk); UNTESTED(GC_dump); UNTESTED(GC_dump_regions); - UNTESTED(GC_is_tmp_root); UNTESTED(GC_print_free_list); # endif -# ifdef TRACE_BUF - UNTESTED(GC_print_trace); -# endif -# ifndef GC_NO_FINALIZATION - UNTESTED(GC_debug_register_finalizer_unreachable); - UNTESTED(GC_register_disappearing_link); - UNTESTED(GC_should_invoke_finalizers); -# ifndef JAVA_FINALIZATION_NOT_NEEDED - UNTESTED(GC_finalize_all); -# endif -# ifndef GC_TOGGLE_REFS_NOT_NEEDED - UNTESTED(GC_toggleref_add); -# endif -# endif -# if !defined(OS2) && !defined(MACOS) && !defined(GC_ANDROID_LOG) \ - && !defined(MSWIN32) && !defined(MSWINCE) - UNTESTED(GC_set_log_fd); -# endif -# ifndef REDIRECT_MALLOC_IN_HEADER -# ifdef REDIRECT_MALLOC -# ifndef strndup - UNTESTED(strndup); -# endif -# ifndef strdup - UNTESTED(strdup); -# endif -# endif -# ifdef REDIRECT_REALLOC - UNTESTED(realloc); -# endif -# endif /* !REDIRECT_MALLOC_IN_HEADER */ -# ifdef GC_REQUIRE_WCSDUP - UNTESTED(GC_wcsdup); - UNTESTED(GC_debug_wcsdup); -# endif +# endif +# if !defined(GC_ANDROID_LOG) && !defined(MACOS) && !defined(OS2) \ + && !defined(MSWIN32) && !defined(MSWINCE) + GC_set_log_fd(2); # endif # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) GC_win32_free_heap(); @@ -2415,13 +2470,6 @@ DWORD __stdcall thr_window(void *arg) # endif run_single_threaded_test(); check_heap_stats(); -# if defined(CPPCHECK) && defined(GC_WIN32_THREADS) - UNTESTED(GC_ExitThread); -# if !defined(MSWINCE) && !defined(CYGWIN32) - UNTESTED(GC_beginthreadex); - UNTESTED(GC_endthreadex); -# endif -# endif return 0; } @@ -2471,6 +2519,21 @@ void * thr_run_one_test(void *arg) return 0; } +void GC_CALLBACK describe_norm_type(void *p, char *out_buf) +{ + UNUSED_ARG(p); + BCOPY("NORMAL", out_buf, sizeof("NORMAL")); +} + +int GC_CALLBACK has_static_roots(const char *dlpi_name, + void *section_start, size_t section_size) +{ + UNUSED_ARG(dlpi_name); + UNUSED_ARG(section_start); + UNUSED_ARG(section_size); + return 1; +} + #ifdef GC_DEBUG # define GC_free GC_debug_free #endif @@ -2496,8 +2559,8 @@ int main(void) } # endif /* GC_HPUX_THREADS */ # ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np (); - pthread_win32_thread_attach_np (); + pthread_win32_process_attach_np(); + pthread_win32_thread_attach_np(); # endif # if defined(GC_DARWIN_THREADS) && !defined(GC_NO_THREADS_DISCOVERY) \ && !defined(DARWIN_DONT_PARSE_STACK) && !defined(THREAD_LOCAL_ALLOC) @@ -2539,6 +2602,16 @@ int main(void) FAIL; } set_print_procs(); + + /* Minimal testing of some API functions. */ + GC_exclude_static_roots((void *)&atomic_count, + (void *)((word)&atomic_count + sizeof(atomic_count))); + GC_register_has_static_roots_callback(has_static_roots); + GC_register_describe_type_fn(GC_I_NORMAL, describe_norm_type); +# ifdef GC_GCJ_SUPPORT + (void)GC_new_proc(fake_gcj_mark_proc); +# endif + # if NTHREADS > 0 for (i = 0; i < NTHREADS; ++i) { if ((code = pthread_create(th+i, &attr, thr_run_one_test, 0)) != 0) { @@ -2561,6 +2634,9 @@ int main(void) run_one_test(); # endif run_single_threaded_test(); +# ifdef TRACE_BUF + GC_print_trace(0); +# endif check_heap_stats(); (void)fflush(stdout); (void)pthread_attr_destroy(&attr); @@ -2613,31 +2689,36 @@ int main(void) # endif # if defined(CPPCHECK) UNTESTED(GC_register_altstack); - UNTESTED(GC_stop_world_external); - UNTESTED(GC_start_world_external); -# ifndef GC_NO_DLOPEN - UNTESTED(GC_dlopen); -# endif -# ifndef GC_NO_PTHREAD_CANCEL - UNTESTED(GC_pthread_cancel); -# endif -# ifdef GC_HAVE_PTHREAD_EXIT - UNTESTED(GC_pthread_exit); -# endif -# ifndef GC_NO_PTHREAD_SIGMASK - UNTESTED(GC_pthread_sigmask); -# endif -# ifdef NO_TEST_HANDLE_FORK - UNTESTED(GC_atfork_child); - UNTESTED(GC_atfork_parent); - UNTESTED(GC_atfork_prepare); - UNTESTED(GC_set_handle_fork); - UNTESTED(GC_start_mark_threads); -# endif # endif /* CPPCHECK */ + +# if !defined(GC_NO_DLOPEN) && !defined(DARWIN) \ + && !defined(GC_WIN32_THREADS) + { + void *h = GC_dlopen("libc.so", 0); + if (h != NULL) dlclose(h); + } +# endif +# ifndef GC_NO_PTHREAD_SIGMASK + { + sigset_t blocked; + + if (GC_pthread_sigmask(SIG_BLOCK, NULL, &blocked) != 0 + || GC_pthread_sigmask(SIG_BLOCK, &blocked, NULL) != 0) { + GC_printf("pthread_sigmask failed\n"); + FAIL; + } + } +# endif + GC_stop_world_external(); + GC_start_world_external(); +# if !defined(GC_NO_FINALIZATION) && !defined(JAVA_FINALIZATION_NOT_NEEDED) + GC_finalize_all(); +# endif + GC_clear_roots(); + # ifdef PTW32_STATIC_LIB - pthread_win32_thread_detach_np (); - pthread_win32_process_detach_np (); + pthread_win32_thread_detach_np(); + pthread_win32_process_detach_np(); # endif return 0; } diff --git a/tests/leak.c b/tests/leak.c index 900139c1..dc2fb8fa 100644 --- a/tests/leak.c +++ b/tests/leak.c @@ -8,6 +8,7 @@ int main(void) { char *p[N_TESTS]; int i; + GC_set_find_leak(1); /* for new collect versions not compiled */ /* with -DFIND_LEAK. */ @@ -15,19 +16,21 @@ int main(void) { /* FIXME: This is not ideal. */ for (i = 0; i < N_TESTS; ++i) { - p[i] = (char*)malloc(sizeof(int)+i); + p[i] = i > 0 ? (char*)malloc(sizeof(int)+i) + : strdup("abc"); } CHECK_LEAKS(); - for (i = 1; i < N_TESTS / 2; ++i) { + for (i = 3; i < N_TESTS / 2; ++i) { p[i] = (char*)((i & 1) != 0 ? reallocarray(p[i], i, 43) : realloc(p[i], i * 16 + 1)); } CHECK_LEAKS(); - for (i = 1; i < N_TESTS; ++i) { + for (i = 2; i < N_TESTS; ++i) { free(p[i]); } - for (i = 0; i < N_TESTS / 2; ++i) { - p[i] = (char*)malloc(sizeof(int)+i); + for (i = 0; i < N_TESTS / 8; ++i) { + p[i] = i < 3 || i > 6 ? (char*)malloc(sizeof(int)+i) + : strndup("abcd", (unsigned)i); } CHECK_LEAKS(); CHECK_LEAKS(); |