Tk Source Code

Ticket Change Details
Login
Overview

Artifact ID: d714562cea764190a163c74a375e0121a7925d00
Ticket: 39e510f69e6e641894d24582c61ba0c99ab21799
Revised [text]: textDisp-27.7.2 segfaults on OS X
User & Date: fvogel 2017-05-24 21:55:28
Changes

  1. icomment:
    OK I understand now what you meant.
    
     1. I have:
    
      - compiled Tcl with "-g -00 -fstack-protector-all" 
    
      - compiled Tk with "-g -01 -fstack-protector-all"
    
    What I said below:
    <verbatim>
    Stepping further, everything seems to be OK until the call to: 
    	name = Tcl_GetHashKey(&sharedTextPtr->tagTable, hPtr);
    in TkTextCreateTag(). 
    </verbatim>
    is actually wrong. I was trapped by the fact the debugger does not show some variables, but this must rather be an artifact due to the optimization.
    
    Making further experiments with lldb, the segfault happens when returning from TkTextCreateTag(), on line 2010 just after the final return. Confirms stack corruption I guess since at this point we get a __stack_chk_fail.
    
    Looking at sharedTextPtr->tagTable, and comparing what's in there on OS X and on Windows, I didn't detect any issue. Same values (except specific pointer values, of course), from the first call when creating the text widget until the return point when creating the "big" tag, including before and after each call to Tk_CreateOptionTable().
    
    
     2. I also have:
    
      - compiled Tcl with "-g -00 -fstack-protector-all" 
    
      - compiled Tk with "-g -01"
    
    And making further tests without this stack protector for Tk, the backtrace in that case shows (this is from the attached "TkConfigureTag crash report 4.txt"):
    <verbatim>
    0   Tk                                  0x000000010d74ae8a Tk_AllocFontFromObj + 26 (tkFont.c:1092)
    1   Tk                                  0x000000010d7451ab DoObjConfig + 571 (tkConfig.c:716)
    2   Tk                                  0x000000010d7457da Tk_SetOptions + 314 (tkConfig.c:1299)
    3   Tk                                  0x000000010d7f2a24 TkConfigureTag + 164 (tkTextTag.c:1094)
    4   Tk                                  0x000000010d7f169b TkTextTagCmd + 2475 (tkTextTag.c:472)
    5   Tk                                  0x000000010d7b6c27 TextWidgetObjCmd + 2631 (tkText.c:2632)
    ...
    </verbatim>
    
    The EXC_BAD_ACCESS happens at the very beginning of Tk_AllocFontFromObj(), on line 1092:
    
    <verbatim>
    (lldb) n
    Process 88869 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x50)
        frame #0: 0x00000001000aae8a Tk`Tk_AllocFontFromObj(interp=0x000000010101b010, tkwin=0x0000000000000000, objPtr=0x0000000100839f10) at tkFont.c:1092 [opt]
       1089     Tcl_Obj *objPtr)            /* Object describing font, as: named font,
       1090                                  * native format, or parseable string. */
       1091 {
    -> 1092     TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr;
       1093     Tcl_HashEntry *cacheHashPtr, *namedHashPtr;
       1094     TkFont *fontPtr, *firstFontPtr, *oldFontPtr;
       1095     int isNew, descent;
    </verbatim>
    
    At this point:
    
    <verbatim>
    (lldb) p (TkWindow *) tkwin
    (TkWindow *) $15 = 0x0000000000000000
    </verbatim>
    
    Aha! tkwin is NULL when Tk_AllocFontFromObj() is entered.
    
    It is already NULL when entering DoObjConfig(), and when calling Tk_SetOptions() in TkConfigureTag().
    
    Actually, textPtr->tkwin becomes NULL exactly when returning from TkTextCreateTag() on tkTextTag.c:1076
    
    Watching textPtr->tkwin all along TkTextCreateTag(), it appears that up to the very end (the return point), it still has the correct non NULL value (the value does not change from the beginning to the end of TkTextCreateTag()). But when we're back in TkConfigureTag() then it's gone (it has switched to NULL):
    
    <verbatim>
    (lldb)
    Process 88918 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step over
        frame #0: 0x0000000100152303 Tk`TkTextCreateTag(textPtr=0x0000000100880810, tagName=<unavailable>, newTag=<unavailable>) at tkTextTag.c:2003 [opt]
       2000         TkBitSet(sharedTextPtr->selectionTags, index);
       2001         TkBitSet(sharedTextPtr->dontUndoTags, index);
       2002     } else {
    -> 2003         tagPtr->relief = TK_RELIEF_FLAT;
       2004         assert(hPtr);
       2005         Tcl_SetHashValue(hPtr, tagPtr);
       2006     }
    (lldb) p textPtr->tkwin
    (Tk_Window) $33 = 0x00000001011bf610
    (lldb) n
    Process 88918 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step over
        frame #0: 0x000000010015230e Tk`TkTextCreateTag(textPtr=0x0000000100880810, tagName=<unavailable>, newTag=<unavailable>) at tkTextTag.c:2005 [opt]
       2002     } else {
       2003         tagPtr->relief = TK_RELIEF_FLAT;
       2004         assert(hPtr);
    -> 2005         Tcl_SetHashValue(hPtr, tagPtr);
       2006     }
       2007
       2008     MarkIndex(sharedTextPtr, tagPtr, true);
    (lldb) p textPtr->tkwin
    (Tk_Window) $34 = 0x00000001011bf610
    (lldb) n
    Process 88918 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step over
        frame #0: 0x0000000100152381 Tk`TkTextCreateTag(textPtr=0x0000000100880810, tagName=<unavailable>, newTag=<unavailable>) at tkTextTag.c:2008 [opt]
       2005         Tcl_SetHashValue(hPtr, tagPtr);
       2006     }
       2007
    -> 2008     MarkIndex(sharedTextPtr, tagPtr, true);
       2009     return tagPtr;
       2010 }
       2011
    
    (lldb) p textPtr->tkwin
    (Tk_Window) $35 = 0x00000001011bf610
    (lldb) n
    Process 88918 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step over
        frame #0: 0x0000000100152391 Tk`TkTextCreateTag(textPtr=0x0000000100880810, tagName=<unavailable>, newTag=<unavailable>) at tkTextTag.c:2010 [opt]
       2007
       2008     MarkIndex(sharedTextPtr, tagPtr, true);
       2009     return tagPtr;
    -> 2010 }
       2011
    
       2012 /*
       2013  *----------------------------------------------------------------------
    (lldb) p textPtr->tkwin
    (Tk_Window) $36 = 0x00000001011bf610
    (lldb) n
    Process 88918 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = step over
        frame #0: 0x00000001001529bd Tk`TkConfigureTag(interp=0x0000000101024610, textPtr=0x0000000100000000, tagName=<unavailable>, objc=2, objv=0x00000001010286d0) at tkTextTag.c:1076 [opt]
       1073     int mask = 0;
       1074     bool newTag;
       1075     TkSharedText *sharedTextPtr = textPtr->sharedTextPtr;
    -> 1076     TkTextTag *tagPtr = TkTextCreateTag(textPtr, tagName, &newTag);
       1077     const char *elideString = tagPtr->elideString;
       1078     bool elide = tagPtr->elide;
       1079     bool undo = tagPtr->undo;
    (lldb) p textPtr->tkwin
    (Tk_Window) $37 = 0x0000000000000000
    (lldb)
    </verbatim>
    
  2. login: "fvogel"
  3. mimetype: "text/x-fossil-wiki"