aboutsummaryrefslogtreecommitdiff
path: root/jim.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2023-05-04 12:20:59 +1000
committerSteve Bennett <steveb@workware.net.au>2023-05-06 12:43:47 +1000
commit4e0e776b2b722302c9e3d622340599ea1f9e4fe0 (patch)
treef1db98efef0ed9e3cca4ce6fbc9f28ed4d608cfd /jim.c
parentfcbb4499a6b46ef69e7a95da53e30796e20817f0 (diff)
downloadjimtcl-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.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/jim.c b/jim.c
index 9059f48..c752312 100644
--- a/jim.c
+++ b/jim.c
@@ -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));