From 36ae487ed04b0e072ff68c70a6775ec6aa6c1725 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Mar 2021 13:10:07 +0100 Subject: [PATCH] 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 Reported-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6130 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Oleksij Rempel Reviewed-by: Jonathan McDowell --- src/helper/command.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/helper/command.c b/src/helper/command.c index 0a711e514..e2726f258 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -117,6 +117,40 @@ static void command_log_capture_finish(struct log_capture_state *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) { int *return_retval = Jim_GetAssocData(interp, "retval");