Index: generic/nsf.c =================================================================== diff -u -r21686b86d06844eca86086b9f9391d77d54dbc06 -rc39e939183732462f9b41cf988c01b69b9faace5 --- generic/nsf.c (.../nsf.c) (revision 21686b86d06844eca86086b9f9391d77d54dbc06) +++ generic/nsf.c (.../nsf.c) (revision c39e939183732462f9b41cf988c01b69b9faace5) @@ -16479,6 +16479,11 @@ DECR_REF_COUNT2("procNameObj", tcd->procName); if (tcd->cmd != NULL) { + /* Re-wire the original namespace into the shadowed cmd, to prevent + namespace references from becoming dangling and to keep the involved + namespaces' refcount books balanced. */ + ((Command *)tcd->cmd)->nsPtr = (Namespace *)tcd->origNsPtr; + NSNamespaceRelease(tcd->origNsPtr); NsfCommandRelease(tcd->cmd); } /* tcd->paramDefs is freed by NsfProcDeleteProc() */ @@ -16898,6 +16903,10 @@ Tcl_Command procCmd = Tcl_GetCommandFromObj(interp, procNameObj); assert(procCmd != NULL); + /* Preserve the shadowed cmd's original namespace (::nsf::procs::*) for + later re-wiring in NsfProcStubDeleteProc() */ + tcd->origNsPtr = Tcl_Command_nsPtr(procCmd); + NSNamespacePreserve(tcd->origNsPtr); ((Command *)procCmd)->nsPtr = (Namespace *)cmdNsPtr; tcd->cmd = procCmd; NsfCommandPreserve(tcd->cmd); Index: generic/nsfInt.h =================================================================== diff -u -r546f8ddb033b81b5a4f9836d4f5541c9f68ac306 -rc39e939183732462f9b41cf988c01b69b9faace5 --- generic/nsfInt.h (.../nsfInt.h) (revision 546f8ddb033b81b5a4f9836d4f5541c9f68ac306) +++ generic/nsfInt.h (.../nsfInt.h) (revision c39e939183732462f9b41cf988c01b69b9faace5) @@ -625,6 +625,7 @@ Tcl_Command wrapperCmd; NsfParamDefs *paramDefs; unsigned int flags; + Tcl_Namespace *origNsPtr; } NsfProcClientData; typedef enum SystemMethodsIdx {