Commit 983c956b authored by frtabu's avatar frtabu Committed by laurent

Fix config module memory leaks

parent 65b399fc
...@@ -11,10 +11,16 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init ...@@ -11,10 +11,16 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init
* if the bit CONFIG_ENABLECMDLINEONLY is set in `initflags` then the module allows parameters to be set only via the command line. This is used for the oai UE. * if the bit CONFIG_ENABLECMDLINEONLY is set in `initflags` then the module allows parameters to be set only via the command line. This is used for the oai UE.
```c ```c
void End_configmodule(void) void end_configmodule(void)
``` ```
* Free memory which has been allocated by the configuration module since its initialization. * Free memory which has been allocated by the configuration module for storing parameters values, when `PARAMFLAG_NOFREE` flag is not specified in the parameter definition.
* Possibly calls the `config_<config source>_end` function * Possibly calls the `config_<config source>_end` function
This call should be used when all configurations have been read. The program will still be able to use parameter values allocated by the config module WHEN THE `PARAMFLAG_NOFREE` flag has been specified in the parameter definition. The config module can be reloaded later in the program (not fully tested as not used today)
```c
void free_configmodule(void)
```
This call should be used to definitely free all resources allocated by the config module. All parameters values allocated by the config module become unavailable and no further reload of the config module are allowed.
## Retrieving parameter's values ## Retrieving parameter's values
......
...@@ -250,46 +250,46 @@ configmodule_interface_t *load_configmodule(int argc, ...@@ -250,46 +250,46 @@ configmodule_interface_t *load_configmodule(int argc,
modeparams=cfgmode; modeparams=cfgmode;
cfgmode=strdup(CONFIG_LIBCONFIGFILE); cfgmode=strdup(CONFIG_LIBCONFIGFILE);
} }
if (cfgptr == NULL) {
cfgptr = calloc(sizeof(configmodule_interface_t),1); cfgptr = calloc(sizeof(configmodule_interface_t),1);
/* argv_info is used to memorize command line options which have been recognized */ /* argv_info is used to memorize command line options which have been recognized */
/* and to detect unrecognized command line options which might have been specified */ /* and to detect unrecognized command line options which might have been specified */
cfgptr->argv_info = calloc(sizeof(int32_t), argc+10); cfgptr->argv_info = calloc(sizeof(int32_t), argc+10);
/* argv[0] is the exec name, always Ok */ /* argv[0] is the exec name, always Ok */
cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED;
/* when OoptIdx is >0, -O option has been detected at position OoptIdx /* when OoptIdx is >0, -O option has been detected at position OoptIdx
* we must memorize arv[OoptIdx is Ok */ * we must memorize arv[OoptIdx is Ok */
if (OoptIdx >= 0) { if (OoptIdx >= 0) {
cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED;
cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED;
} }
cfgptr->rtflags = cfgptr->rtflags | tmpflags; cfgptr->rtflags = cfgptr->rtflags | tmpflags;
cfgptr->argc = argc; cfgptr->argc = argc;
cfgptr->argv = argv; cfgptr->argv = argv;
cfgptr->cfgmode=strdup(cfgmode); cfgptr->cfgmode=strdup(cfgmode);
cfgptr->num_cfgP=0; cfgptr->num_cfgP=0;
atoken=strtok_r(modeparams,":",&strtokctx); atoken=strtok_r(modeparams,":",&strtokctx);
while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) {
/* look for debug level in the config parameters, it is common to all config mode /* look for debug level in the config parameters, it is common to all config mode
and will be removed from the parameter array passed to the shared module */ and will be removed from the parameter array passed to the shared module */
char *aptr; char *aptr;
aptr=strcasestr(atoken,"dbgl"); aptr=strcasestr(atoken,"dbgl");
if (aptr != NULL) {
cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);
} else {
cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
cfgptr->num_cfgP++;
}
if (aptr != NULL) { atoken = strtok_r(NULL,":",&strtokctx);
cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);
} else {
cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
cfgptr->num_cfgP++;
} }
atoken = strtok_r(NULL,":",&strtokctx); printf("[CONFIG] get parameters from %s ",cfgmode);
} }
printf("[CONFIG] get parameters from %s ",cfgmode);
for (i=0; i<cfgptr->num_cfgP; i++) { for (i=0; i<cfgptr->num_cfgP; i++) {
printf("%s ",cfgptr->cfgP[i]); printf("%s ",cfgptr->cfgP[i]);
} }
...@@ -339,6 +339,7 @@ void end_configmodule(void) { ...@@ -339,6 +339,7 @@ void end_configmodule(void) {
pthread_mutex_lock(&cfgptr->memBlocks_mutex); pthread_mutex_lock(&cfgptr->memBlocks_mutex);
printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs);
int n=0;
for(int i=0; i<cfgptr->numptrs ; i++) { for(int i=0; i<cfgptr->numptrs ; i++) {
if (cfgptr->oneBlock[i].ptrs != NULL && cfgptr->oneBlock[i].ptrsAllocated== true && cfgptr->oneBlock[i].toFree) { if (cfgptr->oneBlock[i].ptrs != NULL && cfgptr->oneBlock[i].ptrsAllocated== true && cfgptr->oneBlock[i].toFree) {
free(cfgptr->oneBlock[i].ptrs); free(cfgptr->oneBlock[i].ptrs);
...@@ -358,13 +359,23 @@ void free_configmodule(void) { ...@@ -358,13 +359,23 @@ void free_configmodule(void) {
end_configmodule(); end_configmodule();
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
int n=0;
printf ("[CONFIG] free %i config parameter pointers\n",cfgptr->num_cfgP); for(int i=0; i<cfgptr->numptrs ; i++) {
if (cfgptr->ptrs[i] != NULL) {
free(cfgptr->ptrs[i]);
cfgptr->ptrs[i]=NULL;
cfgptr->ptrsAllocated[i] = false;
n++;
}
}
printf ("[CONFIG] %u/%u persistent config value pointers have been released\n",n,cfgptr->numptrs);
cfgptr->numptrs=0;
printf ("[CONFIG] free %i config module parameter pointers\n",cfgptr->num_cfgP);
for (int i=0; i<cfgptr->num_cfgP; i++) { for (int i=0; i<cfgptr->num_cfgP; i++) {
if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
} }
free(cfgptr->argv_info);
free(cfgptr); free(cfgptr);
cfgptr=NULL; cfgptr=NULL;
} }
......
...@@ -120,7 +120,15 @@ extern configmodule_interface_t *cfgptr; ...@@ -120,7 +120,15 @@ extern configmodule_interface_t *cfgptr;
#define CONFIG_ENABLECMDLINEONLY (1<<1) #define CONFIG_ENABLECMDLINEONLY (1<<1)
extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags); extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags);
/* free ressources used to read parameters, keep memory
* allocated for parameters values which has been defined with the PARAMFLAG_NOFREE flag
* should be used as soon as there is no need to read parameters but doesn't prevent
* a new config module init
*/
extern void end_configmodule(void); extern void end_configmodule(void);
/* free all config module memory, to be used at end of program as
* it will free parameters values even those specified with the PARAMFLAG_NOFREE flag */
extern void free_configmodule(void);
#define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n"); #define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n");
......
...@@ -658,10 +658,15 @@ int main(int argc, char **argv) ...@@ -658,10 +658,15 @@ int main(int argc, char **argv)
if (ouput_vcd) if (ouput_vcd)
vcd_signal_dumper_close(); vcd_signal_dumper_close();
end_configmodule();
loader_reset(); if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
logTerm(); exit_fun("[NR_DLSCHSIM] Error, configuration module init 2 failed\n");
}
return (n_errors); logInit();
loader_reset();
logTerm();
free_configmodule();
return (n_errors);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment