Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[StaticScan] Fix resource leak warnings (due to missing dlclose()) by…
… maintaining an array of all dlopen handles and freeing them at ydb_exit() time
  • Loading branch information
nars1 committed Sep 18, 2018
1 parent 745b6f1 commit 1327c9d
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 4 deletions.
12 changes: 9 additions & 3 deletions sr_linux/hugetlbfs_overrides.c
@@ -1,6 +1,9 @@
/****************************************************************
* *
* Copyright 2012, 2013 Fidelity Information Services, Inc *
* Copyright 2012, 2013 Fidelity Information Services, Inc *
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
Expand Down Expand Up @@ -34,6 +37,7 @@
#undef shmget
#include "send_msg.h"
#include "wbox_test_init.h"
#include "dlopen_handle_array.h"
#ifdef DEBUG
# define WBTEST_HUGETLB_DLSYM_ERROR "WBTEST_HUGETLB_DLSYM error"
#endif
Expand Down Expand Up @@ -81,8 +85,10 @@ void libhugetlbfs_init(void)
GTM_WHITE_BOX_TEST(WBTEST_HUGETLB_DLOPEN, handle, NULL);
if (NULL != handle)
{
/* C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used
* below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; */
dlopen_handle_array_add(handle);
/* C99 standard leaves casting from "void *" to a function pointer undefined.
* The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround;
*/
*(void **) (&p_shmget) = dlsym(handle, "shmget");
GTM_WHITE_BOX_TEST(WBTEST_HUGETLB_DLSYM, p_shmget, NULL);
if (NULL != p_shmget) /* NULL value for shmget() necessarily means it was not found */
Expand Down
19 changes: 19 additions & 0 deletions sr_port/dlopen_handle_array.h
@@ -0,0 +1,19 @@
/****************************************************************
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/

#ifndef DLOPEN_HANDLE_ARRAY_included
#define DLOPEN_HANDLE_ARRAY_included

void dlopen_handle_array_add(void_ptr_t handle);
void dlopen_handle_array_close(void);

#endif /* DLOPEN_HANDLE_ARRAY_included */
46 changes: 46 additions & 0 deletions sr_port/dlopen_handle_array_add.c
@@ -0,0 +1,46 @@
/****************************************************************
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/

#include "mdef.h"

#include "gtm_string.h"

#include "dlopen_handle_array.h"

GBLREF void_ptr_t *dlopen_handle_array;
GBLREF uint4 dlopen_handle_array_len_alloc;
GBLREF uint4 dlopen_handle_array_len_used;

void dlopen_handle_array_add(void_ptr_t handle)
{
void_ptr_t *tmpArray;

assert(NULL != handle);
assert(dlopen_handle_array_len_used <= dlopen_handle_array_len_alloc);
if (dlopen_handle_array_len_alloc == dlopen_handle_array_len_used)
{ /* No space to hold input handle. Expand array. */
if (!dlopen_handle_array_len_alloc)
{ /* Nothing allocated till now. Start at 4. Is not too many and yet should avoid expansion in most cases */
dlopen_handle_array_len_alloc = 4;
} else
dlopen_handle_array_len_alloc *= 2; /* Array already exists. Allocate twice that size. */
tmpArray = malloc(SIZEOF(void_ptr_t) * dlopen_handle_array_len_alloc);
if (NULL != dlopen_handle_array)
{
assert(dlopen_handle_array_len_used);
memcpy(tmpArray, dlopen_handle_array, SIZEOF(void_ptr_t) * dlopen_handle_array_len_used);
free(dlopen_handle_array);
}
dlopen_handle_array = tmpArray;
}
dlopen_handle_array[dlopen_handle_array_len_used++] = handle;
}
45 changes: 45 additions & 0 deletions sr_port/dlopen_handle_array_close.c
@@ -0,0 +1,45 @@
/****************************************************************
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/

#include "mdef.h"

#include <dlfcn.h>

#include "dlopen_handle_array.h"

GBLREF void_ptr_t *dlopen_handle_array;
GBLREF uint4 dlopen_handle_array_len_alloc;
GBLREF uint4 dlopen_handle_array_len_used;

void dlopen_handle_array_close(void)
{
void_ptr_t handle;
int i, status;

assert(dlopen_handle_array_len_used <= dlopen_handle_array_len_alloc);
for (i = 0; i < dlopen_handle_array_len_used; i++)
{
handle = dlopen_handle_array[i];
assert(NULL != handle);
status = dlclose(handle);
assert(0 == status);
/* Not much we can do in case of an error in "dlclose" while we are already in "ydb_exit". Silently ignore. */
}
/* Reset globals so they can be used afresh in case another "ydb_init" happens in the same process. */
if (NULL != dlopen_handle_array)
{
free(dlopen_handle_array);
dlopen_handle_array = NULL;
}
dlopen_handle_array_len_alloc = 0;
dlopen_handle_array_len_used = 0;
}
5 changes: 5 additions & 0 deletions sr_port/gbldefs.c
Expand Up @@ -1235,3 +1235,8 @@ GBLDEF int4 tstart_gtmci_nested_level; /* TREF(gtmci_nested_level) at the time
GBLDEF uint4 deferred_signal_handling_needed; /* if non-zero, it means the DEFERRED_SIGNAL_HANDLING_CHECK
* macro needs to do some work.
*/
GBLDEF void_ptr_t *dlopen_handle_array; /* Array of handles returned from various "dlopen" calls done inside YottaDB.
* Used later to "dlclose" at "ydb_exit" time.
*/
GBLDEF uint4 dlopen_handle_array_len_alloc, dlopen_handle_array_len_used; /* Allocated and Used length of the array */

7 changes: 6 additions & 1 deletion sr_unix/gtm_env_translate.c
@@ -1,6 +1,9 @@
/****************************************************************
* *
* Copyright 2006, 2011 Fidelity Information Services, Inc *
* Copyright 2006, 2011 Fidelity Information Services, Inc *
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
Expand All @@ -18,6 +21,7 @@
#include "lv_val.h" /* needed for "fgncal.h" */
#include "fgncal.h"
#include "gtm_env_xlate_init.h"
#include "dlopen_handle_array.h"

GBLREF mstr env_gtm_env_xlate;
GBLREF mval dollar_zdir;
Expand Down Expand Up @@ -46,6 +50,7 @@ mval* gtm_env_translate(mval* val1, mval* val2, mval* val_xlated)
memcpy(pakname, env_gtm_env_xlate.addr, env_gtm_env_xlate.len);
pakname[env_gtm_env_xlate.len]='\0';
pakhandle = fgn_getpak(pakname, ERROR);
dlopen_handle_array_add(pakhandle);
SFPTR(gtm_env_xlate_entry, (fgnfnc)fgn_getrtn(pakhandle, &routine_name, ERROR));
/* With Unicode mstr changes, xc_string_t is no longer compatible with mstr
* so explicit copy of len/addr fields required */
Expand Down
7 changes: 7 additions & 0 deletions sr_unix/gtm_icu.c
Expand Up @@ -383,6 +383,13 @@ void gtm_icu_init(void)
handle = dlopen(NULL, ICU_LIBFLAGS);
assertpro(handle);
# endif
/* Note that a call to "dlopen_handle_array_add(handle)" should normally have been placed here but
* if "dlopen_handle_array_close()" happens on this handle (corresponding to libicuio.so) later and
* any type of error occurs (e.g. CALLINAFTEREXIT etc.), it is very likely we would end up invoking
* "gtm_wcwidth" as part of displaying/logging the error and that would SIG-11 because a "dlclose"
* has already been done on libicuio.so. Since this library is so much tied with YottaDB error handling,
* we skip the "dlopen_handle_array_add" (and in turn "dlopen_handle_array_close" at "ydb_exit" time).
*/
DEBUG_ONLY(symbols_renamed = -1;)
for (findx = 0; findx < icu_func_n; ++findx)
{
Expand Down
2 changes: 2 additions & 0 deletions sr_unix/gtm_tls_loadlibrary.c
Expand Up @@ -25,6 +25,7 @@
#include "fgncal.h" /* needed for COPY_DLLERR_MSG() */
#include "gtmmsg.h"
#include "gtmcrypt.h"
#include "dlopen_handle_array.h"

typedef void (*gtm_tls_func_t)(); /* A generic pointer type to the TLS functions exposed by the plugin */

Expand Down Expand Up @@ -86,6 +87,7 @@ int gtm_tls_loadlibrary()
COPY_DLLERR_MSG(err_str, dl_err);
return -1;
}
dlopen_handle_array_add(handle);
for (findx = 0; findx < gtm_tls_func_n; ++findx)
{
fptr = (gtm_tls_func_t)dlsym(handle, gtm_tls_fname[findx]);
Expand Down
2 changes: 2 additions & 0 deletions sr_unix/gtm_zlib.c
Expand Up @@ -23,6 +23,7 @@
#include "fgncal.h" /* needed for COPY_DLLERR_MSG() */
#include "gtm_zlib.h"
#include "gtmmsg.h"
#include "dlopen_handle_array.h"

error_def(ERR_DLLNOOPEN);
error_def(ERR_TEXT);
Expand Down Expand Up @@ -73,6 +74,7 @@ void gtm_zlib_init(void)
#ifdef _AIX
}
#endif
dlopen_handle_array_add(handle);
for (findx = 0; findx < ZLIB_NUM_DLSYMS; ++findx)
{
fptr = (void *)dlsym(handle, zlib_fname[findx]);
Expand Down
3 changes: 3 additions & 0 deletions sr_unix/gtmci.c
Expand Up @@ -88,6 +88,7 @@ GBLREF u_casemap_t gtm_strToTitle_ptr; /* Function pointer for gtm_strToTitle
#include "hashtab_int4.h" /* needed for tp.h and cws_insert.h */
#include "tp.h"
#include "ydb_getenv.h"
#include "dlopen_handle_array.h"

GBLREF stack_frame *frame_pointer;
GBLREF unsigned char *msp;
Expand Down Expand Up @@ -1336,6 +1337,8 @@ int ydb_exit()
# endif
REVERT;
gtm_startup_active = FALSE;
/* We might have opened one or more shlib handles using "dlopen". Do a "dlclose" of them now. */
dlopen_handle_array_close();
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions sr_unix/gtmcrypt_entry.c
Expand Up @@ -30,6 +30,7 @@
#include "ydb_trans_log_name.h"
#include "gdsroot.h"
#include "is_file_identical.h"
#include "dlopen_handle_array.h"

#define GTMCRYPT_LIBNAME "libgtmcrypt.so"
#define MAX_GTMCRYPT_PLUGIN_STR_LEN (SIZEOF(GTMCRYPT_LIBNAME) * 4)
Expand Down Expand Up @@ -126,6 +127,7 @@ uint4 gtmcrypt_entry()
COPY_DLLERR_MSG(err_str, dl_err);
return ERR_CRYPTDLNOOPEN;
}
dlopen_handle_array_add(handle);
for (findx = 0; findx < gtmcrypt_func_n; ++findx)
{
fptr = (gtmcrypt_func_t)dlsym(handle, gtmcrypt_fname[findx]);
Expand Down
2 changes: 2 additions & 0 deletions sr_unix/map_sym.c
Expand Up @@ -24,6 +24,7 @@
#include "error.h"
#include "gtmmsg.h"
#include "ydb_getenv.h"
#include "dlopen_handle_array.h"

#define ERR_FGNSYM \
{ \
Expand Down Expand Up @@ -66,6 +67,7 @@ boolean_t map_collseq(int act, collseq *ret_collseq)
return FALSE;
if (NULL == (handle = fgn_getpak(envptr, INFO)))
return FALSE;
dlopen_handle_array_add(handle);
if ((ret_collseq->xform = fgn_getrtn(handle, &xform_sym_1, SUCCESS)))
{
if ((ret_collseq->xback = fgn_getrtn(handle, &xback_sym_1, SUCCESS)))
Expand Down

0 comments on commit 1327c9d

Please sign in to comment.