bugGNUstep - Bugs: bug #43454, Problem with Continuous Spell...


You are not allowed to post comments on this tracker with your current authentification level.

bug #43454: Problem with Continuous Spell Checking

Submitted by:  Germán Arias <espectador>
Submitted on:  Tue Oct 21 18:25:17 2014  
Category: Gui/AppKitSeverity: 3 - Normal
Item Group: BugStatus: None
Privacy: PublicAssigned to: Fred Kiefer <FredKiefer>
Open/Closed: Open

(Jump to the original submission Jump to the original submission)

Sun Nov 16 17:12:36 2014, comment #11:

I finally managed to reproduce the descriped behaviour with a slight variation of my code:

[text insertText: @"Hola program"];
NSLog(@"inserting text");
[text setSelectedRange: NSMakeRange(5, 7)];
[textStorage beginEditing];
[text replaceCharactersInRange: NSMakeRange(5, 7) withString: @"programa"];
//[lm glyphAtIndex: 13 isValidIndex: &valid];
[lm _generateRunsToCharacter: 13];
[textStorage endEditing];
[text didChangeText];
NSLog(@"inserted text");

With this I get an ifinit loop and the glyph dump just looks like yours:

--- dumping runs
0x22014d0 13 chars, 13 glyphs, 1 complete, prev 0x206dea0 next 0x222a268
level 0, continued 0
0 0048 u0048 1 006f u006f 2 006c u006c 3 0061 u0061 4 0020 u0020 5 0070 u0070 6 0072 u0072 7 006f u006f 8 0067 u0067 9 0072 u0072 10 0061 u0061 11 006d u006d 12 0061 u0061
0x222a268 1 chars, 0 glyphs, 0 complete, prev 0x22014d0 next (nil)
level 1, continued 0
- structure
head: 0x22014d0 1 0 0|0x222a250 1 13 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13| (nil) 0 14 13|
0x22014d0: 0x222a268 1 13 13|
0x222a268: (nil) 0 1 0| (nil) 0 1 0|
--- done

With the commented out line,
[lm glyphAtIndex: 13 isValidIndex: &valid];
I get no glyph dumps and the following message:

Problem posting notification: <NSException: 0x20c2640> NAME:NSGenericException REASON:Glyph generation was triggered for a layout manager while the text storage it was attached to had unprocessed editing. This is not allowed. Glyph generation may be triggered only at points where calls to -beginEditing and -endEditing are balanced. INFO:(null)

Now with this in place I should be finally able to track down what is going wrong.

Fred Kiefer <FredKiefer>
Project MemberIn charge of this item.
Wed Nov 12 05:29:55 2014, comment #10:

The problem should be in _textCheckingTimerFired: or _checkTextInRange:, which are called after the text has been edited. If I add:

[self setContinuousSpellCheckingEnabled: NO];

In _acceptGuess: before [_textStorage beginEditing]. The word is inserted without problem.

Germán Arias <espectador>
Tue Nov 11 22:58:29 2014, comment #9:

I am a bit confused that a break point at line 756 could still result in a loop. As there is no loop inside of _generateGlyphsUpToCharacter: this would mean that the loop is in _generateGlyphs_char_r:
Which again would mean that you only get the glyph dump before the change not after. But in your picuture I see that "Hole program" has been replaced by "Hola programa".
What is also strange is that the glyph skip list internaly referes to the index 14, although there should always have been 13 characters at most.

I tried to reproduce the behaviour with this bit of code:

NSTextView *text = [[NSTextView alloc] initWithFrame: NSMakeRect(0,0,200,200)];

[text insertText: @"Hola program"];
NSLog(@"generateGlyphsUpToGlyph 0");
NSLayoutManager *lm = [text layoutManager];
NSTextStorage *textStorage = [text textStorage];
NSLog(@"inserting text");
[textStorage beginEditing];
[text replaceCharactersInRange: NSMakeRange(5, 7) withString: @"programa"];
[textStorage endEditing];
[text didChangeText];
NSLog(@"inserted text");

which should match what happens inside of _acceptGuess:, but this seems to work and never gives invalid glyph indexes.
I also tried to add calls to
[lm glyphAtIndex: 13 isValidIndex: &valid];
with different indexes, but none of that resulted in a loop.

Fred Kiefer <FredKiefer>
Project MemberIn charge of this item.
Tue Nov 11 01:58:46 2014, comment #8:

Letting execute one time the line 756 goes into infinite loop. So is hard catch the output. But I send you this screenshot (attached) when the gdb hangs.

(file #32410)

Germán Arias <espectador>
Sun Nov 9 22:53:47 2014, comment #7:

I now seem to have an idea what might cause the problem. With the selection not properly adjusted the text view tries to highlight behind the end of the text. This results in a glyoh past the end of the text being requested and this somehow leads to an infinit loop.

This will require two fixes. One for the calling method (_acceptGuess:), which is fairly simple. But we also need to fix the low level glyph code. It should never go into a loop, even when wrong numbers are given. What should happen is that "complete" gets set to 1 on the top level glyph run. But this doesn't happen and to understand why I need some more information.

In GSLayoutManager.m you see the commented out lines 732 and 734. Could you please activate them and run your example again? It will result in loads of output. What I am interested in is the first output after your last breakpoint. I think it is best to set another breakpoint on line 756 and have it execute exactly once.

Sorry to make it so complicated. I will add the simple fix after we understand what is going on here.

Fred Kiefer <FredKiefer>
Project MemberIn charge of this item.
Thu Nov 6 07:26:18 2014, comment #6:

Here the backtrace I get with (using Ink):

break NSTextView.m:5822

when stop:

break GSLayoutManager.m:755

Tha backtrace:

#0 -[GSLayoutManager(GlyphsHelpers) _generateGlyphsUpToGlyph:] ()
at GSLayoutManager.m:745
#1 0x003a0960 in -[GSLayoutManager(glyphs) glyphAtIndex:isValidIndex:] ()
at GSLayoutManager.m:861
#2 0x003a7724 in -[GSHorizontalTypesetter _cacheGlyphs:] ()
at GSHorizontalTypesetter.m:218
#3 0x003a8c1b in -[GSHorizontalTypesetter layoutLineNewParagraph:] ()
at GSHorizontalTypesetter.m:562
#4 0x003a91ae in -[GSHorizontalTypesetter layoutGlyphsInLayoutManager:inTextContainer:startingAtGlyphIndex:previousLineFragmentRect:nextGlyphIndex:numberOfLineFragments:] () at GSHorizontalTypesetter.m:1281
#5 0x003a3354 in -[GSLayoutManager(LayoutHelpers) _doLayoutToContainer:] ()
at GSLayoutManager.m:2000
#6 0x003a0b70 in -[GSLayoutManager(LayoutHelpers) _doLayout] ()
at GSLayoutManager.m:1888
#7 0x00296ddf in -[NSLayoutManager(layout) _insertionPointRectForCharacterIndex:textContainer:] () at NSLayoutManager.m:871
#8 0x002953da in -[NSLayoutManager(layout) insertionPointRectForCharacterIndex:inTextContainer:] () at NSLayoutManager.m:975
#9 0x00000001 in ?? ()
#10 0x0033fa09 in -[NSTextView(leftovers) updateInsertionPointStateAndRestartTimer:] () at NSTextView.m:4224

As you can see, there isn't too much information. Aside that this hangs GDB and I need restart GNUstep services.

Germán Arias <espectador>
Fri Oct 31 14:16:27 2014, comment #5:

I submitted a patch for the specific issue of the last stack trace. This wont fix the whole issue reported here, but should reduce the visible symptoms.

It would be great if you could send me a stack trace of the other issue as well. Of course reduced to a managable size.

Fred Kiefer <FredKiefer>
Project MemberIn charge of this item.
Sun Oct 26 22:39:44 2014, comment #4:

I think this two problems are related.

Backtrace when app crash:

Open Ink, select at menu Check Spelling Automatically and then write, notice the last space, "Hello programme " (without quotes). Then in contextual menu select "programmer". The app crash. Here the backtrace:

Program received signal SIGSEGV, Segmentation fault.
-[NSLayoutManager(drawing) drawBackgroundForGlyphRange:atPoint:] ()
at NSLayoutManager.m:1413
1413 NSRange r = NSMakeRange(glyph_pos + i, glyph_run->head.glyph_length - i);
(gdb) backtrace
#0 -[NSLayoutManager(drawing) drawBackgroundForGlyphRange:atPoint:] ()
at NSLayoutManager.m:1413
#1 0x0033b934 in -[NSTextView(leftovers) drawRect:] () at NSTextView.m:4003
#2 0x00360eda in -[NSView displayRectIgnoringOpacity:inContext:] ()
at NSView.m:2570
#3 0x00355e3b in -[NSView displayRectIgnoringOpacity:] () at NSView.m:2519
#4 0x00360acf in -[NSView displayIfNeededInRectIgnoringOpacity:] ()
at NSView.m:2450
#5 0x00360d01 in -[NSView displayIfNeededInRectIgnoringOpacity:] ()
at NSView.m:2476
#6 0x00360d01 in -[NSView displayIfNeededInRectIgnoringOpacity:] ()
at NSView.m:2476
#7 0x00360d01 in -[NSView displayIfNeededInRectIgnoringOpacity:] ()
at NSView.m:2476
#8 0x00360d01 in -[NSView displayIfNeededInRectIgnoringOpacity:] ()
at NSView.m:2476
#9 0x00355d06 in -[NSView displayIfNeededInRect:] () at NSView.m:2428
#10 0x00355b77 in -[NSView displayIfNeeded] () at NSView.m:2410
#11 0x00367b2f in -[NSWindow displayIfNeeded] () at NSWindow.m:2431
#12 0x00366478 in -[NSWindow(GNUstepPrivate) _handleAutodisplay] ()
at NSWindow.m:189
#13 0x003716ab in +[NSWindow(GNUstepPrivate) _handleAutodisplay:] ()
at NSWindow.m:218
#14 0x0080a5ba in -[NSObject performSelector:withObject:] () at NSObject.m:2046
---Type <return> to continue, or q <return> to quit--
#15 0x0083f989 in -[GSRunLoopPerformer fire] () at NSRunLoop.m:110
#16 0x00842631 in -[NSRunLoop(Private) _checkPerformers:] () at NSRunLoop.m:493
#17 0x008413a5 in -[NSRunLoop runMode:beforeDate:] () at NSRunLoop.m:1265
#18 0x00383885 in -[GSDisplayServer(EventOps) getEventMatchingMask:beforeDate:inMode:dequeue:] () at GSDisplayServer.m:1040
#19 0x0291c4b7 in -[XGServer(X11Ops) getEventMatchingMask:beforeDate:inMode:dequeue:] () at XGServerEvent.m:2571
#20 0x00202bf7 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] () at ../Headers/Additions/GNUstepGUI/GSDisplayServer.h:207
#21 0x0020109d in -[NSApplication run] () at NSApplication.m:1553
#22 0x001e3aeb in NSApplicationMain () at Functions.m:91
#23 0x08048e57 in main () at main.m:33

The other problem:

Open Ink, select at menu Check Spelling Automatically and then write "Hello programme" this time without space at the end (without quotes). Then in contextual menu select "programmer", the app hangs. This doesn't occurs if you write only one word, for example "programm". Only if you write two or more words. The odd thing here, is that auto complete also use -replaceCharactersInRange:withString: and works OK. For example, open Gemas, create a new Objective-C document, select at menu "Check Spelling Automatically", and then write something like "#import NSMutabl" (without quotes) and press Control-p to open the auto complete list, now select something like NSMutableDictionary and this is inserted without problem.

Germán Arias <espectador>
Sun Oct 26 16:23:25 2014, comment #3:

Could you please provide a stack trace of the issue?

You seem to be describing two different situations. In one case you talk about a crash and in the other about an indefinitely running loop. What are the different ways to trigger these behaviours?

I looked over the code in NSTextView and in GSLayoutManager and the only obvious problem I could see is that the insertion of a spelling correction via insertText: wont change the selected range. And this also doesn't call beginEditing/endEditing, but as far as I remember this shouldn't be needed for just one single change.

It really would help to see whether the problem occures directly from _acceptGuess: or changeSpelling: or happens later on.

Fred Kiefer <FredKiefer>
Project MemberIn charge of this item.
Sun Oct 26 06:36:25 2014, comment #2:

More info.

If you add one space after the last word (the wrong word). And then try to spell the word with the contextual menu, the app crash with the message:

run_for_glyph_index failed for 0

Germán Arias <espectador>
Thu Oct 23 17:27:41 2014, comment #1:

The problem is the while loop in _generateGlyphsUpToGlyph: (NSLayoutManager), which run indefinitely. However I need further investigation to find why this happen.

Germán Arias <espectador>
Tue Oct 21 18:25:17 2014, original submission:

The problem occurs when the last word in the container is wrong and the user selects a guess word, in the contextual menu, with a length greater that the selected word at textview. In this case the app hangs. To reproduce:

1) Open Ink.
2) Write some words and put the last word wrong.
3) Open contextual menu and select a word with a length greater than the selected word in textview.
4) The app hangs.

Maybe this is a problem with replaceCharactersInRange:withString:. But I don't found documentation about how this method works.

Germán Arias <espectador>


Attached Files
file #32410:  bug.jpg added by espectador (117kB - image/jpeg - Screenshot of the bug.)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -unavailable- added by FredKiefer (Posted a comment)
  • -unavailable- added by espectador (Submitted the item)

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.


    Please enter the title of George Orwell's famous dystopian book (it's a date):



    Follow 2 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Tue Nov 11 01:58:46 2014espectadorAttached File-=>Added bug.jpg, #32410
    Sun Oct 26 16:23:25 2014FredKieferAssigned toNone=>FredKiefer

    Back to the top

    Powered by Savane 3.1-cleanup1