Created
May 25, 2019 02:23
-
-
Save jefgen/560077b80c64a833495e0d6c657f2b3d to your computer and use it in GitHub Desktop.
Testing ICU DLL unload for leaking OS Critical Sections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a simple test program to verify that ICU doesn't leak critical | |
// sections when the ICU library DLLs are dynamically loaded and unloaded | |
// from a running process. | |
// | |
// Compile and run this program under a debugger with AppVerifier enabled | |
// to see the output (either leaks or no leaks). | |
// | |
// Note: You need to add the path to the ICU DLL to your PATH first. | |
// | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <Windows.h> | |
// U_STABLE const char* U_EXPORT2 uloc_getDefault(void); | |
typedef const char* (__cdecl* pfn_uloc_getDefault)(void); | |
// U_STABLE void U_EXPORT2 u_cleanup(void); | |
typedef void(__cdecl* pfn_u_cleanup)(void); | |
// U_STABLE int32_t U_EXPORT2 ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec); | |
typedef int32_t (__cdecl* pfn_ucal_getDefaultTimeZone)(char16_t*, int32_t, int32_t*); | |
int main() | |
{ | |
wprintf(L"Testing ICU for leaking Critical Sections.\n"); | |
HINSTANCE hIcuCommonLib = nullptr; | |
HINSTANCE hIcuI18nLib = nullptr; | |
pfn_uloc_getDefault func_uloc_getDefault = nullptr; | |
pfn_ucal_getDefaultTimeZone func_ucal_getDefaultTimeZone = nullptr; | |
pfn_u_cleanup func_u_cleanup = nullptr; | |
// Change the version number for the version of ICU you are testing, then rebuild. | |
hIcuCommonLib = LoadLibraryW(L"icuuc64.dll"); | |
hIcuI18nLib = LoadLibraryW(L"icuin64.dll"); | |
if ((hIcuCommonLib != nullptr) && (hIcuI18nLib != nullptr)) | |
{ | |
func_uloc_getDefault = (pfn_uloc_getDefault)GetProcAddress(hIcuCommonLib, "uloc_getDefault_64"); | |
func_u_cleanup = (pfn_u_cleanup)GetProcAddress(hIcuCommonLib, "u_cleanup_64"); | |
func_ucal_getDefaultTimeZone = (pfn_ucal_getDefaultTimeZone)GetProcAddress(hIcuI18nLib, "ucal_getDefaultTimeZone_64"); | |
if ((func_uloc_getDefault != nullptr) && (func_u_cleanup != nullptr) && (func_ucal_getDefaultTimeZone != nullptr)) | |
{ | |
const char* locale = func_uloc_getDefault(); | |
wprintf(L" ICU default locale = '%hs'\n", locale); | |
int32_t error = 0; | |
char16_t timezone[100] = {0}; | |
func_ucal_getDefaultTimeZone(timezone, 100, &error); | |
if (error == 0) | |
{ | |
wprintf(L" ICU default timezone = '%s'\n", timezone); | |
} | |
// Tell ICU to clean up. This should also free up any OS Critical Sections. | |
func_u_cleanup(); | |
} | |
else | |
{ | |
wprintf(L"ERROR: Failed to get the function addresses.\n"); | |
} | |
// Unloading the DLLs shouldn't trigger any AppVerifier leaks. | |
if (FreeLibrary(hIcuI18nLib)) | |
{ | |
wprintf(L"ERROR: Failed to unload the DLL. GetLastError = 0x%08x \n", GetLastError()); | |
} | |
if (FreeLibrary(hIcuCommonLib)) | |
{ | |
wprintf(L"ERROR: Failed to unload the DLL. GetLastError = 0x%08x \n", GetLastError()); | |
} | |
} | |
else | |
{ | |
wprintf(L"ERROR: Failed to load the DLL. (Are the ICU DLLs in your PATH ?). \n"); | |
} | |
wprintf(L"End.\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment