gnustep / libobjc2

Objective-C runtime library intended for use with Clang.
http://www.gnustep.org/
MIT License
426 stars 116 forks source link

Delete some dead code containing bugs. #205

Closed davidchisnall closed 3 years ago

davidchisnall commented 3 years ago

Fixes #203

davidchisnall commented 3 years ago

@rmottola, please can you see if this fixes it for NetBSD?

rmottola commented 3 years ago

@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?

davidchisnall commented 3 years ago

Exited normally implies that the test passed. Is this definitely one of the failing ones?

rmottola commented 3 years ago

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.

davidchisnall commented 3 years ago

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?

rmottola commented 3 years ago

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" ?

davidchisnall commented 3 years ago

You can try breaking in the cleanup function that's called in objc_send_initialize or in the personality function?

rmottola commented 3 years ago

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)
davidchisnall commented 3 years ago

_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.