jimtcl: add temporary workaround for memory leak in jimtcl 0.80

The API Jim_CreateCommand() in latest version of jimtcl leaks the
memory allocated internally by jimtcl when it converts the string
command-name to a Jim_Obj.
The fix is already merged upstream and would be available in next
jimtcl 0.81, expected in ~6 months, hopefully before the next tag
for OpenOCD v0.12.0.
OpenOCD v0.11.0 is distributed with jimtcl 0.79.
Debian distributes jimtcl as a separate library package and today
it's still on 0.79.

It make sense to keep using jimtcl 0.80 in current development
cycle to test it further. But having this background memory leak
noise hides the eventual new memory leaks that could come from the
development activity.

This patch uses the internal jimtcl API Jim_CreateCommandObj() and
correctly free the internal object, avoiding the memory leak.
Being an internal API, it is not accessible if OpenOCD is linked
with an external jimtcl library. Nevertheless, building jimtcl as
a submodule of OpenOCD makes the trick effective.

The scope of this patch is thus limited at developers that build
OpenOCD with jimtcl submodule and need to control and debug memory
leaks.
This patch is supposed to be removed as soon as jimtcl 0.81 gets
available.

The added code is located, on purpose, in an area of the file that
hopefully will not conflict other patches pending in gerrit.

Change-Id: I4d300ad21bdb6c616c3f0f14b429b4fdf360900d
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reported-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: http://openocd.zylin.com/6130
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
Reviewed-by: Jonathan McDowell <noodles-openocd@earth.li>
This commit is contained in:
Antonio Borneo 2021-03-26 13:10:07 +01:00
parent a5b5907506
commit 36ae487ed0
1 changed files with 34 additions and 0 deletions

View File

@ -117,6 +117,40 @@ static void command_log_capture_finish(struct log_capture_state *state)
free(state); free(state);
} }
/*
* FIXME: workaround for memory leak in jimtcl 0.80
* Jim API Jim_CreateCommand() converts the command name in a Jim object and
* does not free the object. Fixed for jimtcl 0.81 by e4416cf86f0b
* Use the internal jimtcl API Jim_CreateCommandObj, not exported by jim.h,
* and override the bugged API through preprocessor's macro.
* This workaround works only when jimtcl is compiled as OpenOCD submodule.
* If jimtcl is linked-in from a precompiled library, either static or dynamic,
* the symbol Jim_CreateCommandObj is not exported and the build will use the
* bugged API.
* To be removed when OpenOCD will switch to jimtcl 0.81
*/
#if JIM_VERSION == 80
static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc);
int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj,
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
__attribute__((weak, alias("workaround_createcommand")));
static int workaround_createcommand(Jim_Interp *interp, const char *cmdName,
Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc)
{
if ((void *)Jim_CreateCommandObj == (void *)workaround_createcommand)
return Jim_CreateCommand(interp, cmdName, cmdProc, privData, delProc);
Jim_Obj *cmd_name = Jim_NewStringObj(interp, cmdName, -1);
Jim_IncrRefCount(cmd_name);
int retval = Jim_CreateCommandObj(interp, cmd_name, cmdProc, privData, delProc);
Jim_DecrRefCount(interp, cmd_name);
return retval;
}
#define Jim_CreateCommand workaround_createcommand
#endif /* JIM_VERSION == 80 */
/* FIXME: end of workaround for memory leak in jimtcl 0.80 */
static int command_retval_set(Jim_Interp *interp, int retval) static int command_retval_set(Jim_Interp *interp, int retval)
{ {
int *return_retval = Jim_GetAssocData(interp, "retval"); int *return_retval = Jim_GetAssocData(interp, "retval");