From 9c580e14c9d2301cea21eed66bbf7d0caf142653 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 13:44:28 -0700 Subject: [PATCH] Added functions to query and set the SDL memory allocation functions: SDL_GetMemoryFunctions() SDL_SetMemoryFunctions() SDL_GetNumAllocations() --- CMakeLists.txt | 4 +- VisualC/SDLtest/SDLtest.vcxproj | 3 +- WhatsNew.txt | 4 + .../SDL2test.xcodeproj/project.pbxproj | 8 + .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 4 + configure | 15 +- configure.in | 5 +- include/SDL_config.h.cmake | 2 +- include/SDL_config.h.in | 2 +- include/SDL_config_android.h | 2 +- include/SDL_config_iphoneos.h | 2 +- include/SDL_config_macosx.h | 2 +- include/SDL_config_pandora.h | 1 - include/SDL_config_psp.h | 1 - include/SDL_config_wiz.h | 1 - include/SDL_stdinc.h | 31 ++++ include/SDL_test.h | 13 +- include/SDL_test_crc32.h | 2 +- include/SDL_test_memory.h | 63 +++++++ src/dynapi/SDL_dynapi_overrides.h | 3 + src/dynapi/SDL_dynapi_procs.h | 3 + src/stdlib/SDL_malloc.c | 172 ++++++++++++++---- src/stdlib/SDL_string.c | 4 - src/test/SDL_test_common.c | 26 ++- src/test/SDL_test_crc32.c | 2 - 25 files changed, 309 insertions(+), 66 deletions(-) create mode 100644 include/SDL_test_memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a36967efa8aa..4af51987e2357 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -653,7 +653,7 @@ if(LIBC) check_include_file(sys/types.h HAVE_SYS_TYPES_H) foreach(_HEADER stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h limits.h - strings.h wchar.h inttypes.h stdint.h ctype.h math.h iconv.h signal.h) + strings.h wchar.h inttypes.h stdint.h ctype.h math.h iconv.h signal.h libunwind.h) string(TOUPPER "HAVE_${_HEADER}" _UPPER) string(REPLACE "." "_" _HAVE_H ${_UPPER}) check_include_file("${_HEADER}" ${_HAVE_H}) @@ -669,7 +669,7 @@ if(LIBC) foreach(_FN strtod malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat - strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa + _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp diff --git a/VisualC/SDLtest/SDLtest.vcxproj b/VisualC/SDLtest/SDLtest.vcxproj index 6190a7dfa797a..e2e39f935fe18 100644 --- a/VisualC/SDLtest/SDLtest.vcxproj +++ b/VisualC/SDLtest/SDLtest.vcxproj @@ -164,9 +164,10 @@ + - \ No newline at end of file + diff --git a/WhatsNew.txt b/WhatsNew.txt index 9e845f5cd4c37..04eeaad71059e 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -6,6 +6,10 @@ This is a list of major changes in SDL's version history. --------------------------------------------------------------------------- General: +* Added functions to query and set the SDL memory allocation functions: + SDL_GetMemoryFunctions() + SDL_SetMemoryFunctions() + SDL_GetNumAllocations() * Added locking functions for multi-threaded access to the joystick and game controller APIs: SDL_LockJoysticks() SDL_UnlockJoysticks() diff --git a/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj b/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj index 0d4fce7e93909..99afeb1ee0e1a 100644 --- a/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; }; AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; }; AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; }; + AAF030011F9009B100B9A9FB /* SDL_test_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */; }; + AAF030021F9009B100B9A9FB /* SDL_test_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF030001F9009B100B9A9FB /* SDL_test_assert.c */; }; FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE454176059AB0029C7A5 /* SDL_test_common.c */; }; FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */; }; FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */; }; @@ -65,6 +67,8 @@ AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_log.c; path = ../../src/test/SDL_test_log.c; sourceTree = ""; }; AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_md5.c; path = ../../src/test/SDL_test_md5.c; sourceTree = ""; }; AA1EE461176059AB0029C7A5 /* SDL_test_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_random.c; path = ../../src/test/SDL_test_random.c; sourceTree = ""; }; + AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_memory.c; path = ../../src/test/SDL_test_memory.c; sourceTree = ""; }; + AAF030001F9009B100B9A9FB /* SDL_test_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_assert.c; path = ../../src/test/SDL_test_assert.c; sourceTree = ""; }; FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDL2test-TV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -106,6 +110,7 @@ AA1EE453176059770029C7A5 /* Library Source */ = { isa = PBXGroup; children = ( + AAF030001F9009B100B9A9FB /* SDL_test_assert.c */, AA1EE454176059AB0029C7A5 /* SDL_test_common.c */, AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */, AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */, @@ -119,6 +124,7 @@ AA1EE45E176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c */, AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */, AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */, + AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */, AA1EE461176059AB0029C7A5 /* SDL_test_random.c */, ); name = "Library Source"; @@ -213,12 +219,14 @@ AA1EE464176059AB0029C7A5 /* SDL_test_crc32.c in Sources */, AA1EE465176059AB0029C7A5 /* SDL_test_font.c in Sources */, AA1EE466176059AB0029C7A5 /* SDL_test_fuzzer.c in Sources */, + AAF030021F9009B100B9A9FB /* SDL_test_assert.c in Sources */, AA1EE467176059AB0029C7A5 /* SDL_test_harness.c in Sources */, AA1EE468176059AB0029C7A5 /* SDL_test_imageBlit.c in Sources */, AA1EE469176059AB0029C7A5 /* SDL_test_imageBlitBlend.c in Sources */, AA1EE46A176059AB0029C7A5 /* SDL_test_imageFace.c in Sources */, AA1EE46B176059AB0029C7A5 /* SDL_test_imagePrimitives.c in Sources */, AA1EE46C176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c in Sources */, + AAF030011F9009B100B9A9FB /* SDL_test_memory.c in Sources */, AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */, AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */, AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */, diff --git a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj index 144d24ca5e8a6..cff071c7b70e1 100755 --- a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -348,6 +348,7 @@ 00794EF009D23739003FC8A1 /* utf8.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6309D20839003FC8A1 /* utf8.txt */; }; 00794EF709D237DE003FC8A1 /* moose.dat in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5E09D20839003FC8A1 /* moose.dat */; }; 453774A5120915E3002F0F45 /* testshape.c in Sources */ = {isa = PBXBuildFile; fileRef = 453774A4120915E3002F0F45 /* testshape.c */; }; + AAF02FFA1F90092700B9A9FB /* SDL_test_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */; }; BBFC08C0164C6862003E6A99 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; BBFC08C1164C6862003E6A99 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; BBFC08C2164C6862003E6A99 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; @@ -1152,6 +1153,7 @@ 092D6D75FFB313BB7F000001 /* testlock.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testlock.c; path = ../../test/testlock.c; sourceTree = SOURCE_ROOT; }; 4537749212091504002F0F45 /* testshape */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testshape; sourceTree = BUILT_PRODUCTS_DIR; }; 453774A4120915E3002F0F45 /* testshape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testshape.c; path = ../../test/testshape.c; sourceTree = SOURCE_ROOT; }; + AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_memory.c; path = ../../src/test/SDL_test_memory.c; sourceTree = ""; }; BBFC088E164C6820003E6A99 /* testgamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testgamecontroller.c; path = ../../test/testgamecontroller.c; sourceTree = ""; }; BBFC08CD164C6862003E6A99 /* testgamecontroller */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testgamecontroller; sourceTree = BUILT_PRODUCTS_DIR; }; BEC566B60761D90300A33029 /* checkkeys */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = checkkeys; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2212,6 +2214,7 @@ DB166D8F16A1D1A500A1396C /* SDL_test_imagePrimitivesBlend.c */, DB166D9016A1D1A500A1396C /* SDL_test_log.c */, DB166D9116A1D1A500A1396C /* SDL_test_md5.c */, + AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */, DB166D9216A1D1A500A1396C /* SDL_test_random.c */, ); name = SDL_Test; @@ -3393,6 +3396,7 @@ DB166D9E16A1D1A500A1396C /* SDL_test_imagePrimitivesBlend.c in Sources */, DB166D9F16A1D1A500A1396C /* SDL_test_log.c in Sources */, DB166DA016A1D1A500A1396C /* SDL_test_md5.c in Sources */, + AAF02FFA1F90092700B9A9FB /* SDL_test_memory.c in Sources */, DB166DA116A1D1A500A1396C /* SDL_test_random.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/configure b/configure index fc0d3466cd1e1..b622085ed5e99 100755 --- a/configure +++ b/configure @@ -16635,7 +16635,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll + for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -16761,6 +16761,19 @@ $as_echo "#define HAVE_SA_SIGACTION 1" >>confdefs.h fi + + for ac_header in libunwind.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUNWIND_H 1 +_ACEOF + +fi + +done + fi diff --git a/configure.in b/configure.in index a4b88f9d16a74..5ac2130844d99 100644 --- a/configure.in +++ b/configure.in @@ -268,7 +268,7 @@ if test x$enable_libc = xyes; then AC_DEFINE(HAVE_MPROTECT, 1, [ ]) ]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) AC_CHECK_FUNCS(atan atan2 acos asin ceil copysign cos cosf fabs floor log pow scalbn sin sinf sqrt sqrtf tan tanf) @@ -277,6 +277,9 @@ if test x$enable_libc = xyes; then AC_CHECK_FUNCS(iconv) AC_CHECK_MEMBER(struct sigaction.sa_sigaction,[AC_DEFINE([HAVE_SA_SIGACTION], 1, [ ])], ,[#include ]) + + dnl Check for additional non-standard headers + AC_CHECK_HEADERS(libunwind.h) fi dnl AC_CHECK_SIZEOF(void*) diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 9befa422f1011..9b20398d0deab 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -72,6 +72,7 @@ #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_WCHAR_H 1 #cmakedefine HAVE_PTHREAD_NP_H 1 +#cmakedefine HAVE_LIBUNWIND_H 1 /* C library functions */ #cmakedefine HAVE_MALLOC 1 @@ -99,7 +100,6 @@ #cmakedefine HAVE_STRLEN 1 #cmakedefine HAVE_STRLCPY 1 #cmakedefine HAVE_STRLCAT 1 -#cmakedefine HAVE_STRDUP 1 #cmakedefine HAVE__STRREV 1 #cmakedefine HAVE__STRUPR 1 #cmakedefine HAVE__STRLWR 1 diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 988d3d93d09a7..a28e83ff07c7e 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -75,6 +75,7 @@ #undef HAVE_SYS_TYPES_H #undef HAVE_WCHAR_H #undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUNWIND_H /* C library functions */ #undef HAVE_MALLOC @@ -102,7 +103,6 @@ #undef HAVE_STRLEN #undef HAVE_STRLCPY #undef HAVE_STRLCAT -#undef HAVE_STRDUP #undef HAVE__STRREV #undef HAVE__STRUPR #undef HAVE__STRLWR diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index c3169e557c42a..46638193d70c6 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -46,6 +46,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -68,7 +69,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index 94ab6933c495b..38dcd9a77da8a 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -44,6 +44,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -66,7 +67,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 67f879a492a01..f75507894efdf 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -49,6 +49,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -70,7 +71,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_pandora.h b/include/SDL_config_pandora.h index f6f52fc11ee09..f421c74a88b1c 100644 --- a/include/SDL_config_pandora.h +++ b/include/SDL_config_pandora.h @@ -70,7 +70,6 @@ #define HAVE_MEMCPY 1 #define HAVE_MEMMOVE 1 #define HAVE_STRLEN 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_psp.h b/include/SDL_config_psp.h index 0e61979066a84..b76cf7de22320 100644 --- a/include/SDL_config_psp.h +++ b/include/SDL_config_psp.h @@ -66,7 +66,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_wiz.h b/include/SDL_config_wiz.h index 3afd8d8af4e80..0c8f02d8b746a 100644 --- a/include/SDL_config_wiz.h +++ b/include/SDL_config_wiz.h @@ -64,7 +64,6 @@ #define HAVE_MEMCPY 1 #define HAVE_MEMMOVE 1 #define HAVE_STRLEN 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 546544f10dee6..16100b8b8700c 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -347,6 +347,37 @@ extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); extern DECLSPEC void SDLCALL SDL_free(void *mem); +typedef void *(SDLCALL *SDL_malloc_func)(size_t size); +typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); +typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); +typedef void (SDLCALL *SDL_free_func)(void *mem); + +/** + * \brief Get the current set of SDL memory functions + */ +extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * \brief Replace SDL's memory allocation functions with a custom set + * + * \note If you are replacing SDL's memory functions, you should call + * SDL_GetNumAllocations() and be very careful if it returns non-zero. + * That means that your free function will be called with memory + * allocated by the previous memory allocation functions. + */ +extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func); + +/** + * \brief Get the number of outstanding (unfreed) allocations + */ +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(); + extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); diff --git a/include/SDL_test.h b/include/SDL_test.h index 62c1be37bf86f..f55afcb022739 100644 --- a/include/SDL_test.h +++ b/include/SDL_test.h @@ -31,17 +31,18 @@ #define SDL_test_h_ #include "SDL.h" +#include "SDL_test_assert.h" #include "SDL_test_common.h" +#include "SDL_test_compare.h" +#include "SDL_test_crc32.h" #include "SDL_test_font.h" -#include "SDL_test_random.h" #include "SDL_test_fuzzer.h" -#include "SDL_test_crc32.h" -#include "SDL_test_md5.h" -#include "SDL_test_log.h" -#include "SDL_test_assert.h" #include "SDL_test_harness.h" #include "SDL_test_images.h" -#include "SDL_test_compare.h" +#include "SDL_test_log.h" +#include "SDL_test_md5.h" +#include "SDL_test_memory.h" +#include "SDL_test_random.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ diff --git a/include/SDL_test_crc32.h b/include/SDL_test_crc32.h index 65aa64edb307d..add480c349fd9 100644 --- a/include/SDL_test_crc32.h +++ b/include/SDL_test_crc32.h @@ -93,7 +93,7 @@ extern "C" { * \returns 0 for OK, -1 on error * */ -int SDLTest_crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); /* Same routine broken down into three steps */ int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); diff --git a/include/SDL_test_memory.h b/include/SDL_test_memory.h new file mode 100644 index 0000000000000..43b67f521be34 --- /dev/null +++ b/include/SDL_test_memory.h @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/** + * \file SDL_test_memory.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_memory_h_ +#define SDL_test_memory_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Start tracking SDL memory allocations + * + * \note This should be called before any other SDL functions for complete tracking coverage + */ +int SDLTest_TrackAllocations(); + +/** + * \brief Print a log of any outstanding allocations + * + * \note This can be called after SDL_Quit() + */ +void SDLTest_LogAllocations(); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_memory_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 3ef56d23af2db..a079e92a3fbb1 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -637,3 +637,6 @@ #define SDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize_REAL #define SDL_LockJoysticks SDL_LockJoysticks_REAL #define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL +#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL +#define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL +#define SDL_GetNumAllocations SDL_GetNumAllocations_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 730fbcc327e97..237c54aac5a9b 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -671,3 +671,6 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_LockJoysticks,(void),(),) SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),) +SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) +SDL_DYNAPI_PROC(int,SDL_SetMemoryFunctions,(SDL_malloc_func a, SDL_calloc_func b, SDL_realloc_func c, SDL_free_func d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index de7f13a9456b2..ac13373d0b9bf 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -26,39 +26,11 @@ #include "../SDL_internal.h" /* This file contains portable memory management functions for SDL */ - #include "SDL_stdinc.h" +#include "SDL_atomic.h" +#include "SDL_error.h" -#if defined(HAVE_MALLOC) - -void *SDL_malloc(size_t size) -{ - if (!size) { - return malloc(1); - } - return malloc(size); -} - -void *SDL_calloc(size_t nmemb, size_t size) -{ - if (!size || !nmemb) { - return calloc(1,1); - } - return calloc(nmemb, size); -} - -void *SDL_realloc(void *ptr, size_t size) -{ - return realloc(ptr, size); -} - -void SDL_free(void *ptr) -{ - free(ptr); -} - -#else /* the rest of this is a LOT of tapdancing to implement malloc. :) */ - +#ifndef HAVE_MALLOC #define LACKS_SYS_TYPES_H #define LACKS_STDIO_H #define LACKS_STRINGS_H @@ -66,6 +38,7 @@ void SDL_free(void *ptr) #define LACKS_STDLIB_H #define ABORT #define USE_LOCKS 1 +#define USE_DL_PREFIX /* This is a version (aka dlmalloc) of malloc/free/realloc written by @@ -642,12 +615,12 @@ DEFAULT_MMAP_THRESHOLD default: 256K #define MALLINFO_FIELD_TYPE size_t #endif /* MALLINFO_FIELD_TYPE */ +#ifndef memset #define memset SDL_memset +#endif +#ifndef memcpy #define memcpy SDL_memcpy -#define malloc SDL_malloc -#define calloc SDL_calloc -#define realloc SDL_realloc -#define free SDL_free +#endif /* mallopt tuning options. SVID/XPG defines four standard parameter @@ -5271,4 +5244,133 @@ mspace_mallopt(int param_number, int value) #endif /* !HAVE_MALLOC */ +#ifdef HAVE_MALLOC +#define real_malloc malloc +#define real_calloc calloc +#define real_realloc realloc +#define real_free free +#else +#define real_malloc dlmalloc +#define real_calloc dlcalloc +#define real_realloc dlrealloc +#define real_free dlfree +#endif + +/* Memory functions used by SDL that can be replaced by the application */ +static struct +{ + SDL_malloc_func malloc_func; + SDL_calloc_func calloc_func; + SDL_realloc_func realloc_func; + SDL_free_func free_func; + SDL_atomic_t num_allocations; +} s_mem = { + real_malloc, real_calloc, real_realloc, real_free, { 0 } +}; + +void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func) +{ + if (malloc_func) { + *malloc_func = s_mem.malloc_func; + } + if (calloc_func) { + *calloc_func = s_mem.calloc_func; + } + if (realloc_func) { + *realloc_func = s_mem.realloc_func; + } + if (free_func) { + *free_func = s_mem.free_func; + } +} + +int SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func) +{ + if (!malloc_func) { + return SDL_InvalidParamError("malloc_func"); + } + if (!calloc_func) { + return SDL_InvalidParamError("calloc_func"); + } + if (!realloc_func) { + return SDL_InvalidParamError("realloc_func"); + } + if (!free_func) { + return SDL_InvalidParamError("free_func"); + } + + s_mem.malloc_func = malloc_func; + s_mem.calloc_func = calloc_func; + s_mem.realloc_func = realloc_func; + s_mem.free_func = free_func; + return 0; +} + +int SDL_GetNumAllocations() +{ + return SDL_AtomicGet(&s_mem.num_allocations); +} + +void *SDL_malloc(size_t size) +{ + void *mem; + + if (!size) { + size = 1; + } + + mem = s_mem.malloc_func(size); + if (mem) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void *SDL_calloc(size_t nmemb, size_t size) +{ + void *mem; + + if (!nmemb || !size) { + nmemb = 1; + size = 1; + } + + mem = s_mem.calloc_func(nmemb, size); + if (mem) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void *SDL_realloc(void *ptr, size_t size) +{ + void *mem; + + if (!ptr && !size) { + size = 1; + } + + mem = s_mem.realloc_func(ptr, size); + if (mem && !ptr) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void SDL_free(void *ptr) +{ + if (!ptr) { + return; + } + + s_mem.free_func(ptr); + SDL_AtomicDecRef(&s_mem.num_allocations); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 1b6c39304e039..ae5fef214d874 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -561,16 +561,12 @@ SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen) char * SDL_strdup(const char *string) { -#if defined(HAVE_STRDUP) - return strdup(string); -#else size_t len = SDL_strlen(string) + 1; char *newstr = SDL_malloc(len); if (newstr) { SDL_strlcpy(newstr, string, len); } return newstr; -#endif /* HAVE_STRDUP */ } char * diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 780993c5b9682..f288d2330b26c 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -47,7 +47,18 @@ static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags) { - SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); + int i; + SDLTest_CommonState *state; + + /* Do this first so we catch all allocations */ + for (i = 1; argv[i]; ++i) { + if (SDL_strcasecmp(argv[i], "--trackmem") == 0) { + SDLTest_TrackAllocations(); + break; + } + } + + state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); if (!state) { SDL_OutOfMemory(); return NULL; @@ -447,6 +458,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); return 2; } + if (SDL_strcasecmp(argv[index], "--trackmem") == 0) { + /* Already handled in SDLTest_CommonCreateState() */ + return 1; + } if ((SDL_strcasecmp(argv[index], "-h") == 0) || (SDL_strcasecmp(argv[index], "--help") == 0)) { /* Print the usage message */ @@ -464,13 +479,13 @@ SDLTest_CommonUsage(SDLTest_CommonState * state) { switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { case SDL_INIT_VIDEO: - return VIDEO_USAGE; + return "[--trackmem] " VIDEO_USAGE; case SDL_INIT_AUDIO: - return AUDIO_USAGE; + return "[--trackmem] " AUDIO_USAGE; case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): - return VIDEO_USAGE " " AUDIO_USAGE; + return "[--trackmem] " VIDEO_USAGE " " AUDIO_USAGE; default: - return ""; + return "[--trackmem]"; } } @@ -1762,6 +1777,7 @@ SDLTest_CommonQuit(SDLTest_CommonState * state) } SDL_free(state); SDL_Quit(); + SDLTest_LogAllocations(); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/test/SDL_test_crc32.c b/src/test/SDL_test_crc32.c index a8878eaa2aa81..867f7c611a708 100644 --- a/src/test/SDL_test_crc32.c +++ b/src/test/SDL_test_crc32.c @@ -69,7 +69,6 @@ int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext) } /* Complete CRC32 calculation on a memory block */ -/* un-used int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) { if (SDLTest_Crc32CalcStart(crcContext,crc32)) { @@ -86,7 +85,6 @@ int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUin return 0; } -*/ /* Start crc calculation */