summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2023-02-10 00:04:10 +0300
committerIvan Maidanski <ivmai@mail.ru>2023-02-11 23:50:05 +0300
commitd7e3062a03cab55e2551bd0353efd31c408c80dd (patch)
tree4e37cf79a8668eae1ad5bf9c9631f40ba3f73462 /tests
parentdac8f776145e437de006fe416b4cf0678b5f9523 (diff)
downloadbdwgc-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.c351
-rw-r--r--tests/leak.c13
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();