Index: generic/nsf.c =================================================================== diff -u -r472a3c5f359bb9b2d0aeadc7937ba2bc6aecdbc9 -r152c1d303323553b9eb8a0a04459ba952941ae64 --- generic/nsf.c (.../nsf.c) (revision 472a3c5f359bb9b2d0aeadc7937ba2bc6aecdbc9) +++ generic/nsf.c (.../nsf.c) (revision 152c1d303323553b9eb8a0a04459ba952941ae64) @@ -606,9 +606,10 @@ nonnull_assert(fmt != NULL); if (requiredLevel >= RUNTIME_STATE(interp)->logSeverity) { - Tcl_DString cmdString, ds; - const char *level; - va_list ap; + int destroyRound = RUNTIME_STATE(interp)->exitHandlerDestroyRound; + Tcl_DString cmdString, ds; + const char *level; + va_list ap; switch (requiredLevel) { case NSF_LOG_DEBUG: level = "Debug"; break; @@ -625,7 +626,16 @@ Tcl_DStringAppendElement(&cmdString, "::nsf::log"); Tcl_DStringAppendElement(&cmdString, level); Tcl_DStringAppendElement(&cmdString, Tcl_DStringValue(&ds)); - NsfDStringEval(interp, &cmdString, "log command", (NSF_EVAL_LOG|NSF_EVAL_NOPROFILE)); + + if (destroyRound != NSF_EXITHANDLER_ON_PHYSICAL_DESTROY) { + NsfDStringEval(interp, &cmdString, "log command", (NSF_EVAL_LOG|NSF_EVAL_NOPROFILE)); + } else { + /* + * On physical destroy, we can't rely on NsfDStringEval() working + * proplerly. + */ + fprintf(stderr, "%s", cmdString.string); + } Tcl_DStringFree(&cmdString); Tcl_DStringFree(&ds); } @@ -31333,12 +31343,13 @@ #endif #if !defined(NDEBUG) - if (unlikely(object->activationCount != 0)) { - fprintf(stderr, "FinalObjectDeletion obj %p activationcount %d\n", - (void *)object, object->activationCount); + if (RUNTIME_STATE(interp)->exitHandlerDestroyRound != NSF_EXITHANDLER_ON_PHYSICAL_DESTROY) { + assert(object->activationCount == 0); + } else if (object->activationCount != 0) { + NsfLog(interp, NSF_LOG_WARN, "FinalObjectDeletion obj %p activationcount %d\n", + (void *)object, object->activationCount); } #endif - assert(object->activationCount == 0); if (likely(object->id != NULL)) { /*fprintf(stderr, " ... cmd dealloc %p final delete refCount %d\n",