Fix shlib loaded: free memory, handle lib reload
- introduce loader_reset() that frees all memory - resolve memory leak in loader_format_shlibpath() - correctly handle library reload: check if a function has been retrieved already. Don't leak memory (strdup()), and handle multiple reloads of different functions from the same SO
This commit is contained in:
@@ -69,7 +69,6 @@ char *loader_format_shlibpath(char *modname, char *version)
|
|||||||
char *tmpstr;
|
char *tmpstr;
|
||||||
char *shlibpath =NULL;
|
char *shlibpath =NULL;
|
||||||
char *shlibversion=NULL;
|
char *shlibversion=NULL;
|
||||||
char *cfgprefix;
|
|
||||||
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL},
|
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL},
|
||||||
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}};
|
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}};
|
||||||
|
|
||||||
@@ -81,16 +80,11 @@ int ret;
|
|||||||
/* looks for specific path for this module in the config file */
|
/* looks for specific path for this module in the config file */
|
||||||
/* specific value for a module path and version is located in a modname subsection of the loader section */
|
/* specific value for a module path and version is located in a modname subsection of the loader section */
|
||||||
/* shared lib name is formatted as lib<module name><module version>.so */
|
/* shared lib name is formatted as lib<module name><module version>.so */
|
||||||
cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16);
|
char cfgprefix[sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16];
|
||||||
if (cfgprefix == NULL) {
|
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
|
||||||
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
|
ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
|
||||||
exit_fun("[LOADER] unrecoverable error");
|
if (ret <0) {
|
||||||
} else {
|
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
|
||||||
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
|
|
||||||
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
|
|
||||||
if (ret <0) {
|
|
||||||
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* no specific path, use loader default shared lib path */
|
/* no specific path, use loader default shared lib path */
|
||||||
if (shlibpath == NULL) {
|
if (shlibpath == NULL) {
|
||||||
@@ -142,6 +136,7 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
shlib_path = loader_format_shlibpath(modname, version);
|
shlib_path = loader_format_shlibpath(modname, version);
|
||||||
|
printf("shlib_path %s\n", shlib_path);
|
||||||
|
|
||||||
for (int i = 0; i < loader_data.numshlibs; i++) {
|
for (int i = 0; i < loader_data.numshlibs; i++) {
|
||||||
if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
|
if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
|
||||||
@@ -198,15 +193,17 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (farray) {
|
if (farray) {
|
||||||
if (!loader_data.shlibs[lib_idx].funcarray) {
|
loader_shlibdesc_t *shlib = &loader_data.shlibs[lib_idx];
|
||||||
loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t));
|
if (!shlib->funcarray) {
|
||||||
if (!loader_data.shlibs[lib_idx].funcarray) {
|
shlib->funcarray = calloc(numf, sizeof(loader_shlibfunc_t));
|
||||||
|
if (!shlib->funcarray) {
|
||||||
fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n");
|
fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto load_module_shlib_exit;
|
goto load_module_shlib_exit;
|
||||||
}
|
}
|
||||||
|
shlib->len_funcarray = numf;
|
||||||
|
shlib->numfunc = 0;
|
||||||
}
|
}
|
||||||
loader_data.shlibs[lib_idx].numfunc = 0;
|
|
||||||
for (int i = 0; i < numf; i++) {
|
for (int i = 0; i < numf; i++) {
|
||||||
farray[i].fptr = dlsym(lib_handle,farray[i].fname);
|
farray[i].fptr = dlsym(lib_handle,farray[i].fname);
|
||||||
if (!farray[i].fptr) {
|
if (!farray[i].fptr) {
|
||||||
@@ -215,9 +212,32 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
goto load_module_shlib_exit;
|
goto load_module_shlib_exit;
|
||||||
}
|
}
|
||||||
loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname);
|
/* check whether this function has been loaded before */
|
||||||
loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr;
|
int j = 0;
|
||||||
loader_data.shlibs[lib_idx].numfunc++;
|
for (; j < shlib->numfunc; ++j) {
|
||||||
|
if (shlib->funcarray[j].fptr == farray[i].fptr) {
|
||||||
|
int rc = strcmp(shlib->funcarray[i].fname, farray[i].fname);
|
||||||
|
AssertFatal(rc == 0,
|
||||||
|
"reloading the same fptr with different fnames (%s, %s)\n",
|
||||||
|
shlib->funcarray[i].fname, farray[i].fname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == shlib->numfunc) {
|
||||||
|
if (shlib->numfunc == shlib->len_funcarray) {
|
||||||
|
loader_shlibfunc_t *n = reallocarray(shlib->funcarray, shlib->numfunc * 2, sizeof(loader_shlibfunc_t));
|
||||||
|
if (!n) {
|
||||||
|
fprintf(stderr, "[LOADER] %s(): unable to allocate memory\n", __func__);
|
||||||
|
ret = -1;
|
||||||
|
goto load_module_shlib_exit;
|
||||||
|
}
|
||||||
|
shlib->funcarray = n;
|
||||||
|
shlib->len_funcarray = shlib->numfunc * 2;
|
||||||
|
}
|
||||||
|
shlib->funcarray[j].fname = strdup(farray[i].fname);
|
||||||
|
shlib->funcarray[j].fptr = farray[i].fptr;
|
||||||
|
shlib->numfunc++;
|
||||||
|
}
|
||||||
} /* for int i... */
|
} /* for int i... */
|
||||||
} else { /* farray ! NULL */
|
} else { /* farray ! NULL */
|
||||||
sprintf(afname,"%s_getfarray",modname);
|
sprintf(afname,"%s_getfarray",modname);
|
||||||
@@ -248,3 +268,18 @@ void * get_shlibmodule_fptr(char *modname, char *fname)
|
|||||||
} /* for i loop on modules */
|
} /* for i loop on modules */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loader_reset()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) {
|
||||||
|
loader_shlibdesc_t *shlib = &loader_data.shlibs[i];
|
||||||
|
free(shlib->name);
|
||||||
|
free(shlib->thisshlib_path);
|
||||||
|
for (int j = 0; j < shlib->numfunc; ++j)
|
||||||
|
free(shlib->funcarray[j].fname);
|
||||||
|
free(shlib->funcarray);
|
||||||
|
shlib->numfunc = 0;
|
||||||
|
shlib->len_funcarray = 0;
|
||||||
|
}
|
||||||
|
free(loader_data.shlibs);
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
char *thisshlib_path;
|
char *thisshlib_path;
|
||||||
uint32_t numfunc;
|
uint32_t numfunc;
|
||||||
loader_shlibfunc_t *funcarray;
|
loader_shlibfunc_t *funcarray;
|
||||||
|
uint32_t len_funcarray;
|
||||||
}loader_shlibdesc_t;
|
}loader_shlibdesc_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -90,5 +91,6 @@ extern void * get_shlibmodule_fptr(char *modname, char *fname);
|
|||||||
extern loader_data_t loader_data;
|
extern loader_data_t loader_data;
|
||||||
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
||||||
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
|
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
|
||||||
|
void loader_reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "common/config/config_userapi.h"
|
#include "common/config/config_userapi.h"
|
||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
#include "common/utils/load_module_shlib.h"
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
#include "PHY/defs_nr_common.h"
|
#include "PHY/defs_nr_common.h"
|
||||||
@@ -671,6 +672,8 @@ int main(int argc, char **argv)
|
|||||||
if (ouput_vcd)
|
if (ouput_vcd)
|
||||||
vcd_signal_dumper_close();
|
vcd_signal_dumper_close();
|
||||||
|
|
||||||
|
loader_reset();
|
||||||
|
|
||||||
return (n_errors);
|
return (n_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user