summaryrefslogtreecommitdiff
path: root/dbg_mlc.c
diff options
context:
space:
mode:
authorivmai <ivmai>2011-03-27 20:19:47 +0000
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 21:06:57 +0400
commitbfda2d071b53ba9cafff211434812821d969c29d (patch)
tree4e6a71202ef733ab5233e07fa715c849f1593d42 /dbg_mlc.c
parent2de7add91598ef5ba24e869c15b4003bc57819b1 (diff)
downloadbdwgc-bfda2d071b53ba9cafff211434812821d969c29d.tar.gz
2011-03-27 Ivan Maidanski <ivmai@mail.ru>
* dbg_mlc.c (GC_debug_strdup, GC_debug_free): Output a portability warning if the argument is NULL and GC is in leaks detection mode. * dbg_mlc.c (GC_debug_strndup, GC_debug_wcsdup): New public function definition. * malloc.c (GC_strndup, GC_wcsdup, strndup): Ditto. * mallocx.c (GC_posix_memalign): Ditto. * malloc.c (strdup): Fix string size value; rename "len" to "lb". * mallocx.c: Include errno.h unless WinCE (otherwise include windows.h for Win32 error constants). * win32_threads.c: Define WIN32_LEAN_AND_MEAN and NOSERVICE before windows.h inclusion. * misc.c (GC_init): Register at-exit callback if GC_find_leak (even if GC_FIND_LEAK macro is unset). * pthread_stop_world.c (NACL_STORE_REGS, __nacl_suspend_thread_if_needed, GC_nacl_initialize_gc_thread): Use BCOPY() instead of memcpy(). * pthread_support.c (GC_init_real_syms): Ditto. * doc/README: Update year in copyright. * include/gc.h: Ditto. * doc/README.macros (GC_DEBUG_REPLACEMENT, GC_REQUIRE_WCSDUP): Document new macro. * doc/README.macros (REDIRECT_MALLOC): Update documentation. * include/gc.h (GC_strndup, GC_posix_memalign, GC_debug_strndup): New API function prototype. * include/gc.h (GC_MALLOC, GC_REALLOC): Redirect to GC_debug_malloc/realloc_replacement() if GC_DEBUG_REPLACEMENT. * include/gc.h (GC_STRDUP): Remove redundant parentheses. * include/leak_detector.h (realloc, strdup): Ditto. * include/gc.h (GC_STRNDUP): New API macro. * include/gc.h (GC_NEW, GC_NEW_ATOMIC, GC_NEW_STUBBORN, GC_NEW_UNCOLLECTABLE): Add missing parentheses. * include/gc.h (GC_wcsdup, GC_debug_wcsdup): New API function prototype (only if GC_REQUIRE_WCSDUP). * include/gc.h (GC_WCSDUP): New API macro (only if GC_REQUIRE_WCSDUP). * include/leak_detector.h: Add copyright header; add usage comment; include stdlib.h and string.h after gc.h (unless GC_DONT_INCLUDE_STDLIB). * include/leak_detector.h (malloc, calloc, free, realloc): Undefine symbol before its redefinition. * include/leak_detector.h (strndup, memalign, posix_memalign): Redefine to the corresponding GC function. * include/leak_detector.h (wcsdup): Redefine to GC_WCSDUP (only if GC_REQUIRE_WCSDUP). * include/leak_detector.h (CHECK_LEAKS): Add comment; don't define the macro if already defined.
Diffstat (limited to 'dbg_mlc.c')
-rw-r--r--dbg_mlc.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/dbg_mlc.c b/dbg_mlc.c
index e1bd4a09..d4db3b3b 100644
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -661,25 +661,66 @@ GC_API void * GC_CALL GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
GC_API char * GC_CALL GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
{
- char *copy;
- size_t lb;
- if (str == NULL) return NULL;
- lb = strlen(str) + 1;
- copy = GC_debug_malloc_atomic(lb, OPT_RA s, i);
+ char *copy;
+ size_t lb;
+ if (str == NULL) {
+ if (GC_find_leak)
+ WARN("strdup(NULL) behavior is undefined\n", 0);
+ return NULL;
+ }
+ lb = strlen(str) + 1;
+ copy = GC_debug_malloc_atomic(lb, OPT_RA s, i);
+ if (copy == NULL) {
+# ifndef MSWINCE
+ errno = ENOMEM;
+# endif
+ return NULL;
+ }
+# ifndef MSWINCE
+ strcpy(copy, str);
+# else
+ /* strcpy() is deprecated in WinCE */
+ memcpy(copy, str, lb);
+# endif
+ return copy;
+}
+
+GC_API char * GC_CALL GC_debug_strndup(const char *str, size_t size,
+ GC_EXTRA_PARAMS)
+{
+ char *copy;
+ size_t len = strlen(str); /* str is expected to be non-NULL */
+ if (len > size)
+ len = size;
+ copy = GC_debug_malloc_atomic(len + 1, OPT_RA s, i);
+ if (copy == NULL) {
+# ifndef MSWINCE
+ errno = ENOMEM;
+# endif
+ return NULL;
+ }
+ BCOPY(str, copy, len);
+ copy[len] = '\0';
+ return copy;
+}
+
+#ifdef GC_REQUIRE_WCSDUP
+# include <wchar.h> /* for wcslen() */
+
+ GC_API wchar_t * GC_CALL GC_debug_wcsdup(const wchar_t *str, GC_EXTRA_PARAMS)
+ {
+ size_t lb = (wcslen(str) + 1) * sizeof(wchar_t);
+ wchar_t *copy = GC_debug_malloc_atomic(lb, OPT_RA s, i);
if (copy == NULL) {
# ifndef MSWINCE
errno = ENOMEM;
# endif
return NULL;
}
-# ifndef MSWINCE
- strcpy(copy, str);
-# else
- /* strcpy() is deprecated in WinCE */
- memcpy(copy, str, lb);
-# endif
+ BCOPY(str, copy, lb);
return copy;
-}
+ }
+#endif /* GC_REQUIRE_WCSDUP */
GC_API void * GC_CALL GC_debug_malloc_uncollectable(size_t lb,
GC_EXTRA_PARAMS)
@@ -729,7 +770,11 @@ GC_API void GC_CALL GC_debug_free(void * p)
ptr_t clobbered;
# endif
- if (0 == p) return;
+ if (0 == p) {
+ if (GC_find_leak)
+ WARN("free(NULL) is non-portable\n", 0);
+ return;
+ }
base = GC_base(p);
if (base == 0) {
GC_err_printf("Attempt to free invalid pointer %p\n", p);