Index: generic/nsf.c =================================================================== diff -u -rad24a87ea5581cd818fd8cc5f17668d1a63db97d -r8c8969ab850d118f76305689bd95e980b8f4543f --- generic/nsf.c (.../nsf.c) (revision ad24a87ea5581cd818fd8cc5f17668d1a63db97d) +++ generic/nsf.c (.../nsf.c) (revision 8c8969ab850d118f76305689bd95e980b8f4543f) @@ -9943,6 +9943,24 @@ assert (object->teardown); assert (cmd); + +#if defined(NSF_STACKCHECK) + { int somevar; + NsfRuntimeState *rst = RUNTIME_STATE(interp); + + if (rst->exitHandlerDestroyRound == NSF_EXITHANDLER_OFF) { + if ((void *)&somevar > rst->bottomOfStack) { + NsfLog(interp, NSF_LOG_WARN, "Stack adjust bottom %ld", + rst->bottomOfStack - (void *)&somevar); + rst->bottomOfStack = (void *)&somevar; + } else if ((void *)&somevar < rst->maxStack) { + NsfLog(interp, NSF_LOG_WARN, "Stack adjust top %ld %s", + rst->bottomOfStack - (void *)&somevar, methodName); + rst->maxStack = (void *)&somevar; + } + } + } +#endif /*fprintf(stderr, "MethodDispatch method '%s.%s' objc %d flags %.6x\n", ObjectName(object), methodName, objc, flags); */ @@ -12404,6 +12422,9 @@ Tcl_Obj *CONST *objv = pcPtr->full_objv; int objc = pcPtr->objc+1; int result; + CONST char *fullMethodName = ObjStr(procNameObj); + Tcl_CallFrame *framePtr; + Proc *procPtr; #if defined(NSF_PROFILE) struct timeval trt; @@ -12414,14 +12435,30 @@ } #endif +#if defined(NSF_STACKCHECK) + { int somevar; + NsfRuntimeState *rst = RUNTIME_STATE(interp); + + if (rst->exitHandlerDestroyRound == NSF_EXITHANDLER_OFF) { + if ((void *)&somevar > rst->bottomOfStack) { + NsfLog(interp, NSF_LOG_WARN, "Stack adjust bottom %ld - nsfProc %s", + rst->bottomOfStack - (void *)&somevar, fullMethodName); + rst->bottomOfStack = (void *)&somevar; + } else if ((void *)&somevar < rst->maxStack) { + NsfLog(interp, NSF_LOG_WARN, "Stack adjust top %ld - nsfProc %s", + rst->bottomOfStack - (void *)&somevar, fullMethodName); + rst->maxStack = (void *)&somevar; + } + } + } +#endif + /* * The code below is derived from the scripted method dispatch and just * slightly adapted to remove object dependencies. */ - CONST char *fullMethodName = ObjStr(procNameObj); - Tcl_CallFrame *framePtr; - Proc *procPtr; + /*fprintf(stderr, "fullMethodName %s epoch %d\n", fullMethodName, Tcl_Command_cmdEpoch(cmd));*/ if (Tcl_Command_cmdEpoch(cmd)) { @@ -18755,6 +18792,14 @@ NsfFinalizeCmd(Tcl_Interp *interp, int withKeepvars) { int result; +#if defined(NSF_STACKCHECK) + {NsfRuntimeState *rst = RUNTIME_STATE(interp); + + NsfLog(interp, NSF_LOG_WARN, "Stack max usage %ld", + labs(rst->maxStack - rst->bottomOfStack)); + } +#endif + /*fprintf(stderr, "+++ call tcl-defined exit handler\n"); */ /* @@ -24379,7 +24424,6 @@ sizeof(Namespace), sizeof(Command), sizeof(Tcl_HashTable)); */ - #if defined(NSF_PROFILE) NsfProfileInit(interp); #endif @@ -24388,6 +24432,18 @@ rst->doCheckResults = 1; rst->doCheckArguments = 1; +#if defined(NSF_STACKCHECK) + { int someVar; + /* + * Note that Nsf_Init() is called typically via a package require, which + * is therefore not really the bottom of the stack, but just a first + * approximization. + */ + rst->bottomOfStack = &someVar; + rst->maxStack = rst->bottomOfStack; + } +#endif + /* * Check, if the namespace exists, otherwise create it. */