Tk Source Code

Ticket Change Details
Login
Overview

Artifact ID: 6d32dfd391aa661018e36fbf6227f6d559607a23d70f037ac393b9a5ec6b6fbd
Ticket: 2d3a81c0ecd1ccbc8c5d3063dfa6630e70b88266
Read segmentation fault on Menu when destroyed in command and console output
User & Date: oehhar 2024-07-08 16:47:43
Changes

  1. assignee changed to: "nobody"
  2. closer changed to: "nobody"
  3. cmimetype changed to: "text/x-fossil-wiki"
  4. comment changed to:
    For me, the following script crashes with segmentation fault, when the menubutton is opened and the checkbutton is selected.
    
    <verbatim>
    pack [ttk::menubutton .b -text "Button"]
    menu .b.s -tearoff 0
    .b.s add checkbutton -label Selected -command selected
    .b configure -menu .b.s
    
    proc selected {} {
        destroy .b
        puts .
    }
    </verbatim>
    
    The crash does not happen, if one of the commands of the selected routine are removed.
    
    Environment:
    
       *   current tcl/tk branch core-8-6-branch or 8.6.14 release
       *   Compiled by VisualStudio 2015 in x86 (32bit) mode
       *   platform: MS_Windows 10 64 bit
    
    The last call in Tk is in generic\tkMenu.c proc DestroyMenuEntry line 1450:
    <verbatim>
    	Tcl_UntraceVar2(menuPtr->interp, varName, NULL,
    		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
    		MenuVarProc, mePtr);
    </verbatim>
    
    The variable contents are:
    <verbatim>
    menuPtr->interp : looks like arbitrary memory.
    varName: String "fStop"
    MenuVarProc -> pointer to a function
    mePtr: current Menu entry
    </verbatim>
    
    The menuPtr does not look good. It is the menu entry structure TkMenuEntry "menuPtr" element.
    
    I suppose, that the destroy of the widget has already destroyed the menu.
    The menu item is preserved and its destruction fails, as the menu is already freed.
    
    ---
    
    With "Tcl_UntraceVar2", TCL is called. The segmentation fault happens in the function
    "TclLookupSimpleVar()" in file "generic\tclVar.c" line 866:
    
    <verbatim>
        if ((cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)
    	    && !(flags & TCL_AVOID_RESOLVERS)) {
    </verbatim>
    
    The invalid read access is in "cxtNsPtr->varResProc", which comes from "cxtNsPtr = iPtr->globalNsPtr;".
    "iPtr" is probably the current interpreter pointer and looks like invalid data.
    
    This invalid data makes all the chain and is already present in the upper tk call.
    
    The call stack is as follows:
    <verbatim>
    >	tcl86tg.dll!TclLookupSimpleVar(Tcl_Interp * interp, Tcl_Obj * varNamePtr, int flags, int create, const char * * errMsgPtr, int * indexPtr) Zeile 866	C
     	tcl86tg.dll!TclObjLookupVarEx(Tcl_Interp * interp, Tcl_Obj * part1Ptr, Tcl_Obj * part2Ptr, int flags, const char * msg, int createPart1, int createPart2, Var * * arrayPtrPtr) Zeile 710	C
     	tcl86tg.dll!TclObjLookupVar(Tcl_Interp * interp, Tcl_Obj * part1Ptr, const char * part2, int flags, const char * msg, int createPart1, int createPart2, Var * * arrayPtrPtr) Zeile 520	C
     	tcl86tg.dll!TclLookupVar(Tcl_Interp * interp, const char * part1, const char * part2, int flags, const char * msg, int createPart1, int createPart2, Var * * arrayPtrPtr) Zeile 437	C
     	tcl86tg.dll!Tcl_UntraceVar2(Tcl_Interp * interp, const char * part1, const char * part2, int flags, char *(*)(void *, Tcl_Interp *, const char *, const char *, int) proc, void * clientData) Zeile 2919	C
     	tk86tg.dll!DestroyMenuEntry(char * memPtr) Zeile 1450	C
     	tcl86tg.dll!Tcl_Release(void * clientData) Zeile 229	C
     	tk86tg.dll!TkInvokeMenu(Tcl_Interp * interp, TkMenu * menuPtr, int index) Zeile 1064	C
     	tk86tg.dll!TkWinHandleMenuEvent(HWND__ * * dummy1141, unsigned int * pMessage, unsigned int * pwParam, long * plParam, long * plResult) Zeile 1243	C
     	tk86tg.dll!TkWinMenuProc(HWND__ * hwnd, unsigned int message, unsigned int wParam, long lParam) Zeile 1013	C
     	user32.dll!__InternalCallWinProc@20()	Unbekannt
     	user32.dll!UserCallWinProcCheckWow()	Unbekannt
     	user32.dll!_DispatchMessageWorker@8()	Unbekannt
     	user32.dll!_DispatchMessageW@4()	Unbekannt
     	tcl86tg.dll!Tcl_WaitForEvent(const Tcl_Time * timePtr) Zeile 518	C
     	tcl86tg.dll!Tcl_DoOneEvent(int flags) Zeile 946	C
     	tk86tg.dll!Tk_MainLoop() Zeile 2109	C
     	tk86tg.dll!Tk_MainExW(int argc, wchar_t * * argv, int(*)(Tcl_Interp *) appInitProc, Tcl_Interp * interp) Zeile 385	C
     	wish86tg.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpszCmdLine, int nCmdShow) Zeile 176	C
     	wish86tg.exe!invoke_main() Zeile 118	C++
     	wish86tg.exe!__scrt_common_main_seh() Zeile 253	C++
     	wish86tg.exe!__scrt_common_main() Zeile 296	C++
     	wish86tg.exe!wWinMainCRTStartup() Zeile 17	C++
     	kernel32.dll!@BaseThreadInitThunk@12()	Unbekannt
     	ntdll.dll!__RtlUserThreadStart()	Unbekannt
     	ntdll.dll!__RtlUserThreadStart@8()	Unbekannt
    </verbatim>
    
    Please come back to me in case of any questions.
    
    Thank you for any help,
    Harald
    
  5. foundin changed to: "core-8-6-branch"
  6. is_private changed to: "0"
  7. login: "oehhar"
  8. priority changed to: "5 Medium"
  9. private_contact changed to: "0f366eb3e9e2fcab52b8ebacd197db9047186a5f"
  10. resolution changed to: "None"
  11. severity changed to: "Minor"
  12. status changed to: "Open"
  13. submitter changed to: "oehhar"
  14. subsystem changed to: "13. Win Menus"
  15. title changed to:
    Read segmentation fault on Menu when destroyed in command and console output
    
  16. type changed to: "Bug"