Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for issue [e39cb3f462631a99], namespace is removed from other namespace paths before deletion is complete |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | bug-e39cb3f462631a99 |
Files: | files | file ages | folders |
SHA3-256: |
bdd005f3301eec51c26b4e49a28022d9 |
User & Date: | pooryorick 2021-05-18 22:09:41.057 |
References
2021-05-19
| ||
07:16 | • Ticket [e39cb3f462] namespace is removed from other namespace paths before deletion is complete status still Open with 3 other changes artifact: a7f70676da user: pooryorick | |
Context
2021-05-19
| ||
07:15 | new test for issue [e39cb3f462631a99], namespace is removed from other namespace paths before deleti... check-in: b0e2b4520c user: pooryorick tags: bug-e39cb3f462631a99 | |
2021-05-18
| ||
22:09 | Fix for issue [e39cb3f462631a99], namespace is removed from other namespace paths before deletion is... check-in: bdd005f330 user: pooryorick tags: bug-e39cb3f462631a99 | |
12:23 | Make pkgua package thread-safe check-in: 2e5531f5f8 user: jan.nijtmans tags: core-8-branch | |
Changes
Changes to generic/tclBasic.c.
︙ | ︙ | |||
3501 3502 3503 3504 3505 3506 3507 | * declares that a delete is in progress and that recursive deletes should * be ignored. */ cmdPtr->flags |= CMD_DYING; /* | | < | | 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 | * declares that a delete is in progress and that recursive deletes should * be ignored. */ cmdPtr->flags |= CMD_DYING; /* * Call each functions and then delete the trace. */ cmdPtr->nsPtr->refCount++; if (cmdPtr->tracePtr != NULL) { CommandTrace *tracePtr; /* CallCommandTraces() does not cmdPtr, that's * done just before Tcl_DeleteCommandFromToken() returns */ CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE); /* * Now delete these traces. */ |
︙ | ︙ |
Changes to generic/tclEnsemble.c.
︙ | ︙ | |||
161 162 163 164 165 166 167 | *foundNsPtr, *altFoundNsPtr, *actualCxtPtr; Tcl_Command token; Tcl_DictSearch search; Tcl_Obj *listObj; const char *simpleName; int index, done; | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | *foundNsPtr, *altFoundNsPtr, *actualCxtPtr; Tcl_Command token; Tcl_DictSearch search; Tcl_Obj *listObj; const char *simpleName; int index, done; if (nsPtr == NULL || nsPtr->flags & NS_DEAD) { if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "tried to manipulate ensemble of deleted namespace", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL); } return TCL_ERROR; |
︙ | ︙ | |||
1726 1727 1728 1729 1730 1731 1732 | TclDStringAppendLiteral(&buf, "subcommand ?arg ...?"); Tcl_WrongNumArgs(interp, 1, objv, Tcl_DStringValue(&buf)); Tcl_DStringFree(&buf); return TCL_ERROR; } | | | 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 | TclDStringAppendLiteral(&buf, "subcommand ?arg ...?"); Tcl_WrongNumArgs(interp, 1, objv, Tcl_DStringValue(&buf)); Tcl_DStringFree(&buf); return TCL_ERROR; } if (ensemblePtr->nsPtr->flags & NS_DEAD) { /* * Don't know how we got here, but make things give up quickly. */ if (!Tcl_InterpDeleted(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "ensemble activated for deleted namespace", -1)); |
︙ | ︙ |
Changes to generic/tclNamesp.c.
︙ | ︙ | |||
2636 2637 2638 2639 2640 2641 2642 | Namespace *pathNsPtr, *realNsPtr, *dummyNsPtr; (void) TclGetNamespaceForQualName(interp, name, cxtNsPtr, TCL_NAMESPACE_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr, &simpleName); if ((realNsPtr != NULL) && (simpleName != NULL)) { if ((cxtNsPtr == realNsPtr) | | | | | | 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 | Namespace *pathNsPtr, *realNsPtr, *dummyNsPtr; (void) TclGetNamespaceForQualName(interp, name, cxtNsPtr, TCL_NAMESPACE_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr, &simpleName); if ((realNsPtr != NULL) && (simpleName != NULL)) { if ((cxtNsPtr == realNsPtr) || !(realNsPtr->flags & NS_DEAD)) { entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName); if (entryPtr != NULL) { cmdPtr = (Command *)Tcl_GetHashValue(entryPtr); } } } /* * Next, check along the path. */ for (i=0 ; (cmdPtr == NULL) && i<cxtNsPtr->commandPathLength ; i++) { pathNsPtr = cxtNsPtr->commandPathArray[i].nsPtr; if (pathNsPtr == NULL) { continue; } (void) TclGetNamespaceForQualName(interp, name, pathNsPtr, TCL_NAMESPACE_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr, &simpleName); if ((realNsPtr != NULL) && (simpleName != NULL) && !(realNsPtr->flags & NS_DEAD)) { entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName); if (entryPtr != NULL) { cmdPtr = (Command *)Tcl_GetHashValue(entryPtr); } } } /* * If we've still not found the command, look in the global namespace * as a last resort. */ if (cmdPtr == NULL) { (void) TclGetNamespaceForQualName(interp, name, NULL, TCL_GLOBAL_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr, &simpleName); if ((realNsPtr != NULL) && (simpleName != NULL) && !(realNsPtr->flags & NS_DEAD)) { entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName); if (entryPtr != NULL) { cmdPtr = (Command *)Tcl_GetHashValue(entryPtr); } } } } else { |
︙ | ︙ |
Changes to tests/namespace.test.
︙ | ︙ | |||
178 179 180 181 182 183 184 | proc x {} {} trace add command x delete "namespace delete [namespace current];#" } namespace delete test_ns_2 } {} test namespace-7.7 {Bug 1655305} -setup { interp create child | | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | proc x {} {} trace add command x delete "namespace delete [namespace current];#" } namespace delete test_ns_2 } {} test namespace-7.7 {Bug 1655305} -setup { interp create child # Can't invoke through the ensemble, since deleting ::tcl # (indirectly, via deleting the global namespace) deletes the ensemble. child eval {rename ::tcl::info::commands ::infocommands} child hide infocommands child eval { proc foo {} { namespace delete :: } } |
︙ | ︙ | |||
203 204 205 206 207 208 209 | namespace ensemble create } trace add command ns1 delete { namespace delete ns1 } } -body { | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | namespace ensemble create } trace add command ns1 delete { namespace delete ns1 } } -body { # No segmentation fault given --enable-symbols. namespace delete ns1 } -result {} test namespace-8.1 {TclTeardownNamespace, delete global namespace} { catch {interp delete test_interp} interp create test_interp interp eval test_interp { |
︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 | } } -result {2 {} 2} -cleanup { catch {namespace delete ::test_ns_1} catch {namespace delete ::test_ns_2} catch {namespace delete ::test_ns_3} catch {namespace delete ::test_ns_4} } | | > > > > | 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 | } } -result {2 {} 2} -cleanup { catch {namespace delete ::test_ns_1} catch {namespace delete ::test_ns_2} catch {namespace delete ::test_ns_3} catch {namespace delete ::test_ns_4} } test namespace-51.13 { name resolution path control when the trace fires, ns_2 is being deleted but isn't gone yet, and is still visible for the trace } -body { set ::result {} namespace eval ::test_ns_1 { proc foo {} {lappend ::result 1} } namespace eval ::test_ns_2 { proc foo {} {lappend ::result 2} trace add command foo delete "namespace eval ::test_ns_3 foo;#" |
︙ | ︙ | |||
2742 2743 2744 2745 2746 2747 2748 | namespace eval ::test_ns_4 { namespace path {::test_ns_2 ::test_ns_3 ::test_ns_1} proc bar {} { list [foo] [namespace delete ::test_ns_2] [foo] } bar } | < | | 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 | namespace eval ::test_ns_4 { namespace path {::test_ns_2 ::test_ns_3 ::test_ns_1} proc bar {} { list [foo] [namespace delete ::test_ns_2] [foo] } bar } } -result {2 {} {2 3 2 1}} -cleanup { catch {namespace delete ::test_ns_1} catch {namespace delete ::test_ns_2} catch {namespace delete ::test_ns_3} catch {namespace delete ::test_ns_4} } test namespace-51.14 {name resolution path control} -setup { foreach cmd [info commands foo*] { |
︙ | ︙ | |||
3340 3341 3342 3343 3344 3345 3346 | } -result 1 test namespace-56.6 { Namespace deletion traces on both the original routine and the imported routine should run without any memory error under a debug build. } -body { | | > | > > > | > | | 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 | } -result 1 test namespace-56.6 { Namespace deletion traces on both the original routine and the imported routine should run without any memory error under a debug build. } -body { variable res {} proc ondelete {old new op} { variable res set tail [namespace tail $old] set up [namespace tail [namespace qualifiers $old]] lappend res [list $up $tail] } namespace eval ns1 {} { namespace export * proc p1 {} { namespace upvar [namespace parent] res res incr res } trace add command p1 delete ondelete } namespace eval ns2 {} { namespace import [namespace parent]::ns1::p1 trace add command p1 delete ondelete } namespace delete ns1 namespace delete ns2 after 1 return $res } -cleanup { unset res rename ondelete {} } -result {{ns1 p1} {ns2 p1}} test namespace-57.0 { an imported alias should be usable in the deletion trace for the alias see 29e8848eb976 } -body { |
︙ | ︙ |