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
- 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>
- login: "fvogel"
- mimetype: "text/x-fossil-wiki"