diff options
author | Steve Bennett <steveb@workware.net.au> | 2023-05-04 12:20:59 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2023-05-06 12:43:47 +1000 |
commit | 4e0e776b2b722302c9e3d622340599ea1f9e4fe0 (patch) | |
tree | f1db98efef0ed9e3cca4ce6fbc9f28ed4d608cfd /jim.c | |
parent | fcbb4499a6b46ef69e7a95da53e30796e20817f0 (diff) | |
download | jimtcl-4e0e776b2b722302c9e3d622340599ea1f9e4fe0.zip jimtcl-4e0e776b2b722302c9e3d622340599ea1f9e4fe0.tar.gz jimtcl-4e0e776b2b722302c9e3d622340599ea1f9e4fe0.tar.bz2 |
jim: info frame improvements
always include 'proc' even if introspection disabled
correctly set 'proc' at the eval frame level that is currently running
in the given proc. This makes it easier to produce an accurate level stacktrace
even across uplevel, etc.
Update stacktrace to use the new info frame.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim.c')
-rw-r--r-- | jim.c | 41 |
1 files changed, 31 insertions, 10 deletions
@@ -12017,23 +12017,44 @@ static int JimInfoFrame(Jim_Interp *interp, Jim_Obj *levelObjPtr, Jim_Obj **objP } #ifndef JIM_NO_INTROSPECTION { - Jim_Obj *cmdObj; - /* Omit the command and proc */ - cmdObj = Jim_NewListObj(interp, targetEvalFrame->argv, targetEvalFrame->argc); + Jim_Obj *cmdObj = Jim_NewListObj(interp, targetEvalFrame->argv, targetEvalFrame->argc); Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "cmd", -1)); Jim_ListAppendElement(interp, listObj, cmdObj); - /* Look in parent frames for a proc name */ - Jim_EvalFrame *p; - for (p = targetEvalFrame->parent; p ; p = p->parent) { - if (p->cmd && p->cmd->isproc) { - Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "proc", -1)); - Jim_ListAppendElement(interp, listObj, p->cmd->cmdNameObj); + } +#endif + /* Now determine if this eval frame has a proc caller */ + { + /* If the target eval frame has proc call frame level >= the previous one + * we don't set 'proc' (it will be set on the previous one) + * So first determine if this needs 'proc' + */ + Jim_EvalFrame *e, *p = NULL; + for (e = interp->evalFrame; e; e = e->parent) { + if (e == targetEvalFrame) { break; } + if (!p || e->callFrameLevel != p->callFrameLevel) { + p = e; + } + else { + p = NULL; + } + } + if (!p || e->callFrameLevel < p->callFrameLevel) { + /* Find the first proc above this level */ + for (e = targetEvalFrame->parent; e; e = e->parent) { + if (e->cmd && e->cmd->isproc) { + /* apply and namespace eval won't provide cmdNameObj */ + if (e->cmd->cmdNameObj) { + Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "proc", -1)); + Jim_ListAppendElement(interp, listObj, e->cmd->cmdNameObj); + } + break; + } + } } } -#endif Jim_ListAppendElement(interp, listObj, Jim_NewStringObj(interp, "level", -1)); Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, interp->framePtr->level - targetEvalFrame->callFrameLevel)); |