Ticket UUID: | b189559e4fe0eb639d2dab6a1ea7b8f90af86d64 | |||
Title: | Crash with menus and -postcommand option | |||
Type: | Bug | Version: | trunk | |
Submitter: | emiliano | Created on: | 2023-10-12 16:14:59 | |
Subsystem: | 12. Unix Menus | Assigned To: | jan.nijtmans | |
Priority: | 5 Medium | Severity: | Critical | |
Status: | Closed | Last Modified: | 2023-10-13 07:24:51 | |
Resolution: | Fixed | Closed By: | jan.nijtmans | |
Closed on: | 2023-10-13 07:24:51 | |||
Description: |
This script crashes Tk trunk with Tcl 8.7 (both updated as of 12/10/2023), on Linux 64bits. $ cat menubug.tcl package require Tk proc noop args {} pack [menubutton .mb -text "Press"] -padx 10 -pady 10 menu .mb.menu -postcommand noop .mb configure -menu .mb.menu Running under gdb with symbols enabled and pressing the menubutton $ gdb tclsh8.7 GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from tclsh8.7... (gdb) run menubug.tcl Starting program: /usr/local/bin/tclsh8.7 menubug.tcl [Depuración de hilo usando libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [Detaching after vfork from child process 14064] [Detaching after vfork from child process 14065] [Detaching after vfork from child process 14066] [Detaching after vfork from child process 14071] [Detaching after vfork from child process 14074] Program received signal SIGSEGV, Segmentation fault. 0x00007ffff687f7a8 in MenuWidgetObjCmd (clientData=0x555555c2aad8, interp=0x555555561ab8, objc=3, objv=0x555555564b98) at /home/emiliano/src/tk/unix/../generic/tkMenu.c:646 646 if ((index != TCL_INDEX_NONE) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY) (gdb) p index $1 = -2147483648 (gdb) | |||
User Comments: |
jan.nijtmans added on 2023-10-13 07:24:51:
@emiliano, understood. The disadvantage of your patch is that if the menu-index if of type "integer", a string representation will be generated if it wasn't there yet. The original code arrangement was meant to prevent that. The advantage of TIP #660 is that all negative values are considered to have the same meaning as value -1. It reduces the possible output range to half, but that's not a problem for menu's: No menu has 2**31 entries .... A side-effect of TIP #660 is that you cannot compare entries for equality with TCL_INDEX_NONE any more; you have to decide what the range -2**31 .. -2 means. Before TIP #660, that simply wasn't possible. Many thanks! emiliano added on 2023-10-12 23:51:18: Jan, many thanks for taking care. Please note that a simpler fix (patch attached) can be done by simply rearranging some code from GetMenuIndex() in file generic/tkMenu.c . It fixes the segfault and introduces no errors in the test suite. However, I'm still worried about the value returned by TkGetIntForIndex() from generic/tkObj.c jan.nijtmans added on 2023-10-12 21:10:56: Thanks for the report! Fixed [cbc3a0fe4f2dcbc3|here] emiliano added on 2023-10-12 17:38:58: Further analysis shows that the bug fires when a menu with no entries calls the "activate" method with an empty string $ wish8.7 % menu .m .m % .m activate "" Violación de segmento (`core' generado) This leads to generic/tkObj.c, line 238 234 if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) { 235 const char *value = Tcl_GetString(indexObj); 236 if (!*value) { 237 /* empty string */ 238 *indexPtr = (end == -1) ? -1 - TCL_SIZE_MAX : TCL_INDEX_NONE; 239 return TCL_OK; 240 } 241 return TCL_ERROR; 242 } called from generic/tkMenu.c, line 2158 (function GetMenuIndex) 2158 if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) { This explain the -2147483648 value for index shown in the first post |
Attachments:
- tkmenu.patch [download] added by emiliano on 2023-10-12 23:52:33. [details]