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 *shlibpath =NULL;
|
||||
char *shlibversion=NULL;
|
||||
char *cfgprefix;
|
||||
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, 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 */
|
||||
/* 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 */
|
||||
cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16);
|
||||
if (cfgprefix == NULL) {
|
||||
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
|
||||
exit_fun("[LOADER] unrecoverable error");
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
char cfgprefix[sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16];
|
||||
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
|
||||
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 */
|
||||
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);
|
||||
printf("shlib_path %s\n", shlib_path);
|
||||
|
||||
for (int i = 0; i < loader_data.numshlibs; i++) {
|
||||
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 (!loader_data.shlibs[lib_idx].funcarray) {
|
||||
loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t));
|
||||
if (!loader_data.shlibs[lib_idx].funcarray) {
|
||||
loader_shlibdesc_t *shlib = &loader_data.shlibs[lib_idx];
|
||||
if (!shlib->funcarray) {
|
||||
shlib->funcarray = calloc(numf, sizeof(loader_shlibfunc_t));
|
||||
if (!shlib->funcarray) {
|
||||
fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n");
|
||||
ret = -1;
|
||||
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++) {
|
||||
farray[i].fptr = dlsym(lib_handle,farray[i].fname);
|
||||
if (!farray[i].fptr) {
|
||||
@@ -215,9 +212,32 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
|
||||
ret = -1;
|
||||
goto load_module_shlib_exit;
|
||||
}
|
||||
loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname);
|
||||
loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr;
|
||||
loader_data.shlibs[lib_idx].numfunc++;
|
||||
/* check whether this function has been loaded before */
|
||||
int j = 0;
|
||||
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... */
|
||||
} else { /* farray ! NULL */
|
||||
sprintf(afname,"%s_getfarray",modname);
|
||||
@@ -248,3 +268,18 @@ void * get_shlibmodule_fptr(char *modname, char *fname)
|
||||
} /* for i loop on modules */
|
||||
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;
|
||||
uint32_t numfunc;
|
||||
loader_shlibfunc_t *funcarray;
|
||||
uint32_t len_funcarray;
|
||||
}loader_shlibdesc_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -90,5 +91,6 @@ extern void * get_shlibmodule_fptr(char *modname, char *fname);
|
||||
extern loader_data_t loader_data;
|
||||
#endif /* LOAD_MODULE_SHLIB_MAIN */
|
||||
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
|
||||
void loader_reset();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#include "T.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
@@ -671,6 +672,8 @@ int main(int argc, char **argv)
|
||||
if (ouput_vcd)
|
||||
vcd_signal_dumper_close();
|
||||
|
||||
loader_reset();
|
||||
|
||||
return (n_errors);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user