Closed davidchisnall closed 3 years ago
@rmottola, please can you see if this fixes it for NetBSD?
@rmottola, please can you see if this fixes it for NetBSD?
Thanks for the work... unfortunately, even if everything builds, test situation improves a little, but can't be said to be usable:
49% tests passed, 94 tests failed out of 186
(gdb) r
Starting program: /home/multix/code/libobjc2/Build/Test/objc_msgSend
Throwing 0x804c608, in flight exception: 0x0
Exception caught by C++: 0
[Inferior 1 (process 22227) exited normally]
(gdb) bt
No stack.
(gdb)
I'm puzzled, more test fails, but this exception with no stack looks worse?
Exited normally implies that the test passed. Is this definitely one of the failing ones?
Exited normally implies that the test passed. Is this definitely one of the failing ones?
When executing "make test" I see:
Start 125: objc_msgSend
125/186 Test #125: objc_msgSend ......................................Child aborted***Exception: 0.00 sec
Start 126: objc_msgSend_optimised
126/186 Test #126: objc_msgSend_optimised ............................Child aborted***Exception: 0.00 sec
Start 127: objc_msgSend_legacy
127/186 Test #127: objc_msgSend_legacy ............................... Passed 0.01 sec
Start 128: objc_msgSend_legacy_optimised
128/186 Test #128: objc_msgSend_legacy_optimised ..................... Passed 0.01 sec
It looks it is failing, if I execute it:
isengard$ Test/objc_msgSend
[1] Abort trap Test/objc_msgSend
(gdb) r
Starting program: /home/multix/code/libobjc2/Build/Test/objc_msgSend
Throwing 0x804c608, in flight exception: 0x0
Exception caught by C++: 0
[Inferior 1 (process 14267) exited normally]
Is it normal to throw an exception here? It looks that it gdb lying to us.
Yes, an exception is normal there. This test is checking that we can correctly unwind through objc_msgSend
when an exception is thrown out of a +initialize
method. I don't know why gdb is not seeing the abort trap though. Can you try a different debugger?
Yes, an exception is normal there. This test is checking that we can correctly unwind through
objc_msgSend
when an exception is thrown out of a+initialize
method. I don't know why gdb is not seeing the abort trap though. Can you try a different debugger?
I checked in packages and don't see other debuggers (just frontends to gdb). I thought of lldb, but it is not available. Others I don't know. I'm using gdb 8.3 . Is there perhaps a way to set a breakpoint or enable exception stopping? a bit like a breakpoint in "NSException raise" ?
You can try breaking in the cleanup function that's called in objc_send_initialize or in the personality function?
objc_send_initialize
I noticed that https://github.com/gnustep/libobjc2/blob/06da6a91c38deb69b3c6152c6fa960735b9ab5e5/eh_personality.c#L176 is completely commented out. I did thus put a breakpoint in: https://github.com/gnustep/libobjc2/blob/41808111aa0a58708daf66b2322940d4353e37d8/dtable.c#L773 You meant that cleanup? where is it defined - it has one parameter compared to the one mentioned above.
It will be invoked by the program just once.
(gdb) bt
#0 objc_send_initialize (object=0x804c620 <._OBJC_CLASS_MsgTest>) at /home/multix/code/libobjc2/dtable.c:774
#1 0xabc0b7b8 in objc_msg_lookup_internal (receiver=0xbfbcd190, selector=0x804ca94 <objc_selector_foo_>, version=0x0)
at /home/multix/code/libobjc2/sendmsg2.c:107
#2 slowMsgLookup (receiver=0xbfbcd190, cmd=0x804ca94 <objc_selector_foo_>)
at /home/multix/code/libobjc2/sendmsg2.c:161
#3 0xabc11b33 in objc_msgSend () at /home/multix/code/libobjc2/objc_msgSend.x86-32.S:121
#4 0x08049bae in main () at /home/multix/code/libobjc2/Test/objc_msgSend.m:183
(gdb) p remove_dtable
$1 = {void (InitializingDtable *)} 0xad478cc0 <remove_dtable>
(gdb) p class
$2 = (Class) 0x804c620 <._OBJC_CLASS_MsgTest>
(gdb) p temporary_dtables
$3 = (InitializingDtable *) 0x0
I tried very crudely continuing to step through the program to have a better idea where it ends, it took hundreds of "enter"... these are the last steps:
232 ex->unwindHeader.exception_cleanup = cleanup;
(gdb)
234 ex->object = object;
(gdb)
236 td->lastThrownObject = object;
(gdb)
237 td->cxxCaughtException = NO;
(gdb)
239 _Unwind_Reason_Code err = _Unwind_RaiseException(&ex->unwindHeader);
(gdb)
[Inferior 1 (process 10475) exited normally]
(gdb)
I wonder how it can stop at line 239... which would be before free and before abort. It never exits from _Unwind_RaiseException
Breakpoint 2, objc_exception_throw (object=0x804c620 <._OBJC_CLASS_MsgTest>)
at /home/multix/code/libobjc2/eh_personality.c:239
239 _Unwind_Reason_Code err = _Unwind_RaiseException(&ex->unwindHeader);
(gdb) p &ex->unwindHeader
$5 = (struct _Unwind_Exception *) 0xb5624010
(gdb) s
[Inferior 1 (process 1841) exited normally]
(gdb)
_Unwind_RaiseException
is the libunwind library function that should raise the exception. It isn't expected to unwind, it will call into the personality functions for each stack frame. It sounds as if the NetBSD unwind library is not happy, but I don't know why that would be.
Fixes #203