Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabview crash fix #261

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

williameveretteggplant
Copy link
Contributor

I'm seeing a crash from _original_nextKeyView in NSTabView becoming deallocated and becoming a zombie pointer.

The problem is that setNextKeyView: keeps a pointer to the nextKeyView without retaining it. So the view could become deallocated but the pointer is still there. And then when selectTabViewItem: is called it tries to use this pointer and crashes.

When a View becomes deallocated it sets the keyView of its previousKeyView to nil, which would take care of this, except for NSTabView the setNextKeyView: method sometimes calls setNextKeyView: on its _selected view rather than itself, so it will not be the previousKeyView.

This change retains the _original_nextKeyView as long as the pointer value is still being used. Note that the NSView dealloc calls [self setNextKeyView: nil] which has the effect of releasing this object, so it is not necessary to RELEASE _original_nextKeyView in the dealloc method of NSTabView.

@williameveretteggplant
Copy link
Contributor Author

Would it be possible for you to look at this, @fredkiefer ?

@fredkiefer
Copy link
Member

I do understand what problem you are trying to address here. And accessing an object after it was released is not just annoying but also very dangerous. On the other hand is the solution not ideal. Adding a retain to the key view loop is also dangerous. It might result in some sort of retain loop and views never being properly cleaned up. This surely would fix your issue and definitely won't that easily break a program. If possible I would prefer another solution.
I have been thinking about removing this variable completely. The idea there would be to instead use the next key view from the super implementation. Before proposing this idea I wanted more time to think about it in detail and maybe experiment with it a little. But somehow the time for this never materialized. I am sorry, so all I have is this untested idea. Maybe you could think it over and perhaps come up with something working?

@williameveretteggplant
Copy link
Contributor Author

I understand your concern. I can tell you in the branch we have been using, NSTabView.m : 288
[self setNextKeyView: firstResponder];
has been replaced with
[super setNextKeyView: firstResponder];
This does seem to prevent the crash, but I hesitate to suggest it as a solution because I don't understand the full ramifications of such a change. Fundamentally, I don't really get the complexity of the next/previous key view logic and don't really know what changes to make that will preserve the functionality while eliminating the problem from the unretained pointer.

@gcasa
Copy link
Member

gcasa commented May 8, 2024

I understand your concern. I can tell you in the branch we have been using, NSTabView.m : 288 [self setNextKeyView: firstResponder]; has been replaced with [super setNextKeyView: firstResponder]; This does seem to prevent the crash, but I hesitate to suggest it as a solution because I don't understand the full ramifications of such a change. Fundamentally, I don't really get the complexity of the next/previous key view logic and don't really know what changes to make that will preserve the functionality while eliminating the problem from the unretained pointer.

Apologies for putting in my $0.02 here, but I am wondering...

Is the issue you are running into here in the application code? Several other apps also use NSTabView in the way you describe and don't have any issues. Gorm, is one example, as well as GWorkspace, Preferences, etc. As we have both witnessed there are instances where GNUstep is a bit stricter (and more correct) than macOS. One example of this is XML parsing. The other is the handling of NSLock. Is this one of those instances?

Are there any places in the code of the application where there is an extraneous release or autorelease?

@fredkiefer
Copy link
Member

I would not put the blame on application code, although this is always an option. There are cases where I could see that the current GNUstep code for NSTab might get us into trouble. This involves complicated operations that are not that easy to reproduce. We will need multiple views in the NSTabView, switch between these views and then somehow release the view that is the next in the key view loop after the NSTabView. Doing these operations in the right order might trigger the issue.

My idea to address this would be to replace the value _original_nextKeyView line 286 in NSTabView.m with something like [super nextKeyView] . Of course this might require some other adjustments in the file and the variable could then be removed completely. The hard bit is to test many possible scenarios whether this results in the expected behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants