Closed trunkmaster closed 5 years ago
FWIW, we saw what I think might have been a similar crash (SIGBUS / BUS_ADRALN) when assigning certain Objective C member variables in some of our classes, but this was only when using the 2.0 ABI (1.9 worked fine). However the libs-gui issue seems to be using the 1.8 ABI.
Unfortunately I was unable to reproduce the issue with a reduced test class outside our app, and we ultimately switched to the 1.9 ABI due to #90.
Maybe... But I've patched my clang as David suggested in #90. And yes, libs-gui and applications was built with -fobjc-runtime=gnustep-1.8
option. -fobjc-runtime=gnustep-2.0
doesn't work for me - it's a subject for separate issue.
Moreover, libs-gui applications stops segfaulting if BOOL
type (unsigned char) changed to int
without moving ivars declarations.
Is this still an issue with the latest clang? There was an issue related to bool ivars having their metadata incorrectly initialised. If there's a test case, I can try to debug it.
Do you mean clang 8.0? I've just built 7.0 and no 8.0 yet.
Test case is simple: if you have libs-gui and some application with GUI, set GSX11HandlesWindowDecorations
to NO
and run it. For example, application named "TextEdit":
$ defaults write TextEdit GSX11HandlesWindowDecorations NO
$ openapp TextEdit
zsh: segmentation fault openapp TextEdit
$ gdb /Applications/TextEdit.app/TextEdit
(gdb) r
Starting program: /Applications/TextEdit.app/TextEdit
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff710dae6 in -[GSStandardWindowDecorationView updateRects] (self=0xfeff18,
_cmd=0x7ffff75d2980 <.objc_selector_list+832>) at GSStandardWindowDecorationView.m:98
98 if (hasTitleBar)
(gdb) bt
#0 0x00007ffff710dae6 in -[GSStandardWindowDecorationView updateRects] (self=0xfeff18, _cmd=0x7ffff75d2980 <.objc_selector_list+832>) at GSStandardWindowDecorationView.m:98
#1 0x00007ffff710e8cd in -[GSStandardWindowDecorationView initWithFrame:window:] (self=0xfeff18, _cmd=0x7ffff75d5490 <.objc_selector_list>, frame=..., w=0xff2198) at GSStandardWindowDecorationView.m:167
#2 0x00007ffff71109a2 in +[GSWindowDecorationView newWindowDecorationViewWithFrame:window:] (self=0x99bc70, _cmd=0x7ffff7563eb0 <.objc_selector_list+1424>, frame=..., aWindow=0xff2198)
at GSWindowDecorationView.m:77
#3 0x00007ffff7061b34 in -[NSWindow initWithContentRect:styleMask:backing:defer:] (self=0xff2198, _cmd=0x7ffff7565410 <.objc_selector_list+6896>, contentRect=..., aStyle=64, bufferingType=0, flag=0 '\000') at NSWindow.m:1077
#4 0x00007ffff7061f0c in -[NSWindow initWithContentRect:styleMask:backing:defer:screen:] (self=0xff2198, _cmd=0x7ffff74116d8 <.objc_selector_list+672>, contentRect=..., aStyle=64, bufferingType=0, flag=0 '\000', aScreen=0x0) at NSWindow.m:1140
#5 0x00007ffff6e313b0 in -[NSApplication(Private) _appIconInit] (self=0xcb2ff8, _cmd=0x7ffff7411a58 <.objc_selector_list+1568>) at NSApplication.m:3856
#6 0x00007ffff6e27e41 in -[NSApplication _init] (self=0xcb2ff8, _cmd=0x7ffff7412108 <.objc_selector_list+3280>) at NSApplication.m:925
#7 0x00007ffff62bd98b in -[NSObject performSelector:withObject:] (self=0xcb2ff8, _cmd=0x7ffff6808f28 <.objc_selector_list+112>, aSelector=0x7ffff7412108 <.objc_selector_list+3280>, anObject=0xcb2ff8)
at NSObject.m:2020
#8 0x00007ffff63454f4 in -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] (self=0xcb2ff8, _cmd=0x7ffff6809238 <.objc_selector_list+896>, aSelector=0x7ffff7412108 <.objc_selector_list+3280>, aThread=0xaf5a58, anObject=0xcb2ff8, aFlag=1 '\001', anArray=0xdb48c8)
at NSThread.m:2139
#9 0x00007ffff6345206 in -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:modes:] (self=0xcb2ff8, _cmd=0x7ffff6809268 <.objc_selector_list+944>, aSelector=0x7ffff7412108 <.objc_selector_list+3280>, anObject=0xcb2ff8, aFlag=1 '\001', anArray=0xdb48c8)
at NSThread.m:2094
#10 0x00007ffff6345281 in -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] (self=0xcb2ff8, _cmd=0x7ffff74125e8 <.objc_selector_list+4528>, aSelector=0x7ffff7412108 <.objc_selector_list+3280>, anObject=0xcb2ff8, aFlag=1 '\001') at NSThread.m:2105
#11 0x00007ffff6e281b0 in -[NSApplication init] (self=0xcb2ff8, _cmd=0x7ffff7411d08 <.objc_selector_list+2256>) at NSApplication.m:979
#12 0x00007ffff6e27a20 in +[NSApplication sharedApplication] (self=0x7be760, _cmd=0x7ffff73fe298 <.objc_selector_list+192>) at NSApplication.m:851
#13 0x00007ffff6dff9d0 in NSApplicationMain (argc=1, argv=0x7fffffffe1a8) at Functions.m:78
#14 0x000000000041e6a2 in main (argc=1, argv=0x7fffffffe1a8) at Edit_main.m:4
(gdb) break GSStandardWindowDecorationView.m:98
Breakpoint 1 at 0x7ffff710dadf: file GSStandardWindowDecorationView.m, line 98.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /Applications/TextEdit.app/TextEdit
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Breakpoint 1, -[GSStandardWindowDecorationView updateRects] (self=0xff0dc8,
_cmd=0x7ffff75d2980 <.objc_selector_list+832>) at GSStandardWindowDecorationView.m:98
98 if (hasTitleBar)
(gdb) print hasTitleBar
$1 = 112 'p'
(gdb) print hasResizeBar
$2 = 112 'p'
(gdb) print hasCloseButton
$3 = 112 'p'
(gdb) print hasMiniaturizeButton
$4 = 112 'p'
(gdb)
Thanks, I can reproduce that. If you've got a smaller test case, that would be helpful...
Note that gdb doesn't know about non-fragile instance variables, so anything that it prints for ivar accesses is likely to be nonsense...
It appears as if the runtime is initialising the offset of hasTitleBar to -1, which is obviously wrong.
Do you still need and a smaller test case? BTW, what would you recommend as a debugger? lldb?
LLDB also doesn't know about the new ABI, though would probably be easier to fix. When debugging, unfortunately, you have to fall back to the runtime's introspection APIs.
Great work, David! Thank you!
@davidchisnall unfortunately this latest change crashes for us here: https://github.com/gnustep/libobjc2/blob/8dd9c9a0ae5e198149fba0c5a7a3b3ec6f7b624d/ivar.c#L81
It crashes with i == 1
and *ivar->offset == -3
. The first two ivars of the affected class are of type BOOL. This is with ABI 1.9 using clang from the latest Android NDK.
Let me know if I can provide any further info.
Hmm, I can see how that would happen. The assert is, unfortunately, firing because the code surrounding it is wrong. If we start with 3 chars in a class then the offsets will be -3, -2, and -1, so we need to handle that case. Unfortunately, we also need to handle the case that we have a bitfield of ints, in which case the offsets will be -4, -4, and -4. I will try to add a test for both of these cases.
Should be fixed in afee197c67c4ad4e80da1e92c93800b67ca083a1
Works great now. Thanks for the quick fix!
It looks like this GNUstep GUI pull request https://github.com/gnustep/libs-gui/pull/23 try to solve problem that lays out of GNUstep source code. It can be the sign of some clang/libobjc2 problem. Can you check it, please?