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

Segfault in SparseArrayLookup; CAAction's protocol version is invalid #283

Open
ethanc8 opened this issue Mar 6, 2024 · 63 comments · May be fixed by #294
Open

Segfault in SparseArrayLookup; CAAction's protocol version is invalid #283

ethanc8 opened this issue Mar 6, 2024 · 63 comments · May be fixed by #294

Comments

@ethanc8
Copy link

ethanc8 commented Mar 6, 2024

Hello 👋, I have encountered a segfault in SparseArrayLookup during the initialization of my port of the application GitY. Here is the backtrace from GDB:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff79c8a15 in SparseArrayLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
(gdb) bt
#0  0x00007ffff79c8a15 in SparseArrayLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#1  0x00007ffff79c9369 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#2  0x00007ffff79c9103 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#3  0x00007ffff79d2039 in slowMsgLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#4  0x00007ffff79d77dc in objc_msgSend_fpret () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#5  0x00007ffff5f2f63a in +[CGImageDestinationTIFF load] (self=0x7ffff5f5b778 <._OBJC_CLASS_CGImageDestinationTIFF>, _cmd=0x7ffff7fab000)
    at image/OPImageCodecTIFF.m:323
#6  0x00007ffff79c552b in objc_send_load_message () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#7  0x00007ffff79c60e8 in objc_resolve_class () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#8  0x00007ffff79c628d in objc_resolve_class_links () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#9  0x00007ffff79cc28c in __objc_load () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#10 0x00007ffff5f0be8d in objcv2_load_function () from /usr/GNUstep/Local/Library/Libraries/libopal.so.0
#11 0x00007ffff7fc947e in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd3d8, env=env@entry=0x7fffffffd3e8)
    at ./elf/dl-init.c:70
#12 0x00007ffff7fc9568 in call_init (env=0x7fffffffd3e8, argv=0x7fffffffd3d8, argc=1, l=<optimized out>) at ./elf/dl-init.c:33
#13 _dl_init (main_map=0x7ffff7ffe2e0, argc=1, argv=0x7fffffffd3d8, env=0x7fffffffd3e8) at ./elf/dl-init.c:117
#14 0x00007ffff7fe32ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#15 0x0000000000000001 in ?? ()
#16 0x00007fffffffd8a2 in ?? ()
#17 0x0000000000000000 in ?? ()

Interestingly, I have not encountered this when running any of the libs-opal tests, such as images. I have confirmed with GDB that images calls +[CGImageDestinationTIFF load] without segfaulting. Therefore, I don't know in which component this came from.

The Objective-C components that are linked to by GitY are:

It's possible that one of those has messed something up in their +load methods, but I'm not exactly sure. If needed, I can send you binaries of my GNUstep installation, compile libobjc2 with different flags, peek around in GDB, or whatever else would be needed.

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

@gcasa Is this the right way to file this, or should I move this to a different repo or to discuss-gnustep?

@davidchisnall
Copy link
Member

Do you have a reduced test case (ideally linking nothing but the runtime)?

It looks as if it may be trying to send a message in +load to a class that is not yet loaded.

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

I think I might have forgotten to link something. I don't have a minimal test case -- as I said, I have no idea where this came from.

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

I looked and it seems like I have linked everything.

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

Do you have a reduced test case (ideally linking nothing but the runtime)?

It looks as if it may be trying to send a message in +load to a class that is not yet loaded.

Is the order of the +load messages defined? It doesn't occur in the libs-opal testcases, so if this is the reason for the segfault, then the load message order is different.

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

@davidchisnall I believe this is the problem...
+[CGImageDestinationTIFF load] calls [CGImageDestination registerDestinationClass: self];. I believe this might be UB, so should this call be moved to +initialize?

+ (void)load
{
  [CGImageDestination registerDestinationClass: self];
}

@ethanc8
Copy link
Author

ethanc8 commented Mar 9, 2024

I changed those to +initialize and it now segfaults in objc_msgSend_fpret in a call to +[NSString load].

@davidchisnall
Copy link
Member

Sending a message to a superclass in +load should be fine. Sending one to any other class that’s defined in the same library should also be fine.

I wonder if somehow the selector for the message being sent is not resolved. That could result in an out of bounds access in the uninitialised stable.

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

I have changed +load to +initialize and disabled UTILoad(), which results in:

Unknown protocol version
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737260606656) at ./nptl/pthread_kill.c:44
44      ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737260606656) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737260606656) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737260606656, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff6c42476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff6c287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007ffff79ccc77 in init_protocols () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#6  0x00007ffff79ccafa in objc_init_protocols () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#7  0x00007ffff79c648d in objc_load_class () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#8  0x00007ffff79cc201 in __objc_load () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#9  0x00007ffff7fc947e in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd398, env=env@entry=0x7fffffffd3a8)
    at ./elf/dl-init.c:70
#10 0x00007ffff7fc9568 in call_init (env=0x7fffffffd3a8, argv=0x7fffffffd398, argc=1, l=<optimized out>) at ./elf/dl-init.c:33
#11 _dl_init (main_map=0x7ffff7ffe2e0, argc=1, argv=0x7fffffffd398, env=0x7fffffffd3a8) at ./elf/dl-init.c:117
#12 0x00007ffff7fe32ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#13 0x0000000000000001 in ?? ()
#14 0x00007fffffffd88b in ?? ()
--Type <RET> for more, q to quit, c to continue without paging--
#15 0x0000000000000000 in ?? ()

@davidchisnall Might this be related? The abort appears in pthreads in objc_init_protocols().

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

Does Apple objc4 work on Linux? If it does, it might be possible to test on objc4 to see if the issue is in libobjc2.

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

@davidchisnall How can I compile libobjc2 with debug symbols included?

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

I passed -DCMAKE_BUILD_TYPE=Debug to CMake

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

I'm kinda busy, but here's my last GDB session if anyone wants to take a look:

Program stopped.
0x00007ffff7fe3290 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) b protocol.c:224
No source file named protocol.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (protocol.c:224) pending.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/ethan/Projects/GNUstep/Porting/GitUp/Examples/GitY/GitY.app/GitY 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, init_protocols (protocols=0x7ffff5ecb020 <objc_protocol_list>) at /home/ethan/Projects/GNUstep/plaurent2/GNUstep-build/libobjc2/protocol.c:224
224                                     fprintf(stderr, "Unknown protocol version");
(gdb) p version
$1 = 0
(gdb) p aProto
$2 = (struct objc_protocol *) 0x7ffff5ed4a50 <._OBJC_PROTOCOL_CAAction>
(gdb) p *aProto
$3 = {isa = 0x0, name = 0x7ffff5ebdfa8 "CAAction", protocol_list = 0x7ffff5ed4b50 <objc_protocol_list>, 
  instance_methods = 0x7ffff5ecad40 <objc_protocol_method_list>, class_methods = 0x7ffff5ecad60 <objc_protocol_method_list>, 
  optional_instance_methods = 0x7ffff5ecad58 <objc_protocol_method_list>, optional_class_methods = 0x7ffff5ecad68 <objc_protocol_method_list>, 
  properties = 0x0, optional_properties = 0x0, class_properties = 0x0, optional_class_properties = 0x0}
(gdb) 

@ethanc8
Copy link
Author

ethanc8 commented Mar 20, 2024

@davidchisnall The issue appears to be that the isa of CAAction is 0x0, which is not a valid protocol version. I don't know why it ended up this way.

@davidchisnall
Copy link
Member

What is the -fobjc-runtime= flag that you’re passing to clang?

@ethanc8
Copy link
Author

ethanc8 commented Mar 24, 2024

@davidchisnall gnustep-config says that I'm using -fobjc-runtime=2.1:

$ gnustep-config --gui-libs
-fuse-ld=/usr/bin/ld.gold -L/usr/local/lib -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.1 -fblocks -L/home/ethan/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries -lgnustep-gui -lgnustep-base -lpthread -lobjc -lm

@ethanc8
Copy link
Author

ethanc8 commented Mar 24, 2024

I can try switching to the newly released v2.2.1

@ethanc8
Copy link
Author

ethanc8 commented Mar 24, 2024

I'm building like:

export CC=clang-14
export CXX=clang++-14
export CXXFLAGS="-std=c++11"
export RUNTIME_VERSION=gnustep-2.1
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export LD=/usr/bin/ld.gold
export LDFLAGS="-fuse-ld=/usr/bin/ld.gold -L/usr/local/lib"

rm -Rf build
mkdir build && cd build
cmake ../ \
  -DCMAKE_C_COMPILER=${CC} \
  -DCMAKE_CXX_COMPILER=${CXX} \
  -DCMAKE_ASM_COMPILER=${CC} \
  -DCMAKE_LINKER=${LD} \
  -DUSE_GOLD_LINKER=YES \
  -DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}" \
  -DTESTS=OFF \
  -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=1
cmake --build .
sudo -E make install
sudo ldconfig

@ethanc8
Copy link
Author

ethanc8 commented Mar 24, 2024

The issue still appears in v2.2.1.

@davidchisnall
Copy link
Member

clang 14 is pretty old, but should be fine. There are a few fixes for the v2 ABI after that, but I think they matter only on Windows.

I wonder if the +load is somehow being called before we've loaded the Protocol class. The Protocol class should be linked into the runtime and the runtime's own constructors should be called before anything that links to it, but it's possible that this isn't happening on your platform. That shouldn't be the case, because if init_protocol_classes returns NO then we don't reach the link that's failing for you.

@ethanc8
Copy link
Author

ethanc8 commented Mar 27, 2024

@davidchisnall Is there anything that I should run in gdb to look into your suspicions? Also, is there anyone else we should get to look at this? Should I post this to discuss-gnustep?

I wonder if the +load is somehow being called before we've loaded the Protocol class.

I think this issue is unrelated to the +load issue. Here's the backtrace from protocol.c:224:

#0  init_protocols (protocols=0x7ffff5ecb020 <objc_protocol_list>) at /home/ethan/Projects/GNUstep/plaurent2/GNUstep-build/libobjc2/protocol.c:224
#1  0x00007ffff79ccafa in objc_init_protocols (protocols=0x7ffff726c238 <objc_protocol_list>)
    at /home/ethan/Projects/GNUstep/plaurent2/GNUstep-build/libobjc2/protocol.c:271
#2  0x00007ffff79c648d in objc_load_class (class=0x7ffff726c300 <._OBJC_CLASS_GCGitObject>)
    at /home/ethan/Projects/GNUstep/plaurent2/GNUstep-build/libobjc2/class_table.c:465
#3  0x00007ffff79cc201 in __objc_load (init=0x7ffff7266c58 <objc_init>) at /home/ethan/Projects/GNUstep/plaurent2/GNUstep-build/libobjc2/loader.c:268
#4  0x00007ffff7fc947e in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd398, env=env@entry=0x7fffffffd3a8)
    at ./elf/dl-init.c:70
#5  0x00007ffff7fc9568 in call_init (env=0x7fffffffd3a8, argv=0x7fffffffd398, argc=1, l=<optimized out>) at ./elf/dl-init.c:33
#6  _dl_init (main_map=0x7ffff7ffe2e0, argc=1, argv=0x7fffffffd398, env=0x7fffffffd3a8) at ./elf/dl-init.c:117
#7  0x00007ffff7fe32ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#8  0x0000000000000001 in ?? ()
#9  0x00007fffffffd88b in ?? ()
#10 0x0000000000000000 in ?? ()

@ethanc8
Copy link
Author

ethanc8 commented Mar 27, 2024

It runs into NSCopying (isa 0x4) and NSCoding (isa 0x4) with no issues before reaching CAAction (isa 0x0).

@ethanc8
Copy link
Author

ethanc8 commented Apr 5, 2024

@davidchisnall Are you available to look at this more or not? Should I post this to discuss-gnustep?

@davidchisnall
Copy link
Member

I’m completely confused by this. It looks as if your binary contains things that shouldn’t be possible.

@ethanc8
Copy link
Author

ethanc8 commented Jun 3, 2024

I have tested again with a new installation of GNUstep on the same computer with clang-18, which results in the same segfault in SparseArrayLookup. I'll go apply my patches to Opal and Boron and see what happens.

@ethanc8
Copy link
Author

ethanc8 commented Jun 3, 2024

I should also try to do this on a clean Debian system, but I currently don't have the disk space to do that.

@ethanc8
Copy link
Author

ethanc8 commented Jun 3, 2024

I get "Unknown protocol versionaborted" error again, with my Opal and Boron patches applied on clang-18.

@ethanc8
Copy link
Author

ethanc8 commented Jun 3, 2024

By the way, for most repositories that I haven't patched I'm on the latest commit to master as of May 31. I built it with tools-scripts this time around.

@ethanc8 ethanc8 changed the title Segfault in SparseArrayLookup Segfault in SparseArrayLookup; CAAction's protocol version is invalid Jun 3, 2024
@davidchisnall
Copy link
Member

Is there something unusual about CAAction's protocol definition? (Is it missing a definition?)

I can't usefully help debug this without a test case that doesn't depend on a big pile of other libraries.

I hadn't noticed previously that you were using gold. Does the same thing happen if you use lld?

@davidchisnall
Copy link
Member

There’s probably a compiler bug that is causing a non-adopted protocol to be emitted, but I’m not sure how it’s generated but not in the correct section. Can you send me the preprocessed source for the compilation unit that generates the .o file that contains the symbol for this protocol?

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

There’s probably a compiler bug that is causing a non-adopted protocol to be emitted, but I’m not sure how it’s generated but not in the correct section. Can you send me the preprocessed source for the compilation unit that generates the .o file that contains the symbol for this protocol?

Do you know how to find the associated compilation unit?

@davidchisnall
Copy link
Member

nm will dump the symbols for each .o file, you should be able to find the CAAction protocol in that list for one file. Once you know that, find the .m file that generated it and add -E and -o {some temp file} to the compile command.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

Ok, thanks.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

I found 0000000000000000 D ._OBJC_PROTOCOL_CAAction in CAAnimation.m.o.

I'll attach the output of -E at https://gist.github.com/ethanc8/46be627ad36326f9b32843fe6409d77d. I wanted to also try -rewrite-objc -fno-ms-extensions -fpermissive, but it looks like libs-quartzcore has a lot of obviously incorrect code (like assigning BOOLs to variables of type id) that only works in C, and not in C++. -rewrite-legacy-objc -fno-ms-extensions -fpermissive caused a compiler crash (which I reported at llvm/llvm-project#94380).

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

(for myself)

for file in *.o; do echo $file; nm $file; done | grep CAAction

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

This is especially perplexing because nothing in libs-quartzcore implements the protocol CAAction, there are just methods that take and return CAAction values (returned values are ones that the user previously provided to libs-quartzcore, so libs-quartzcore is not producing any id itself). Despite that, CAAnimation ends up with ._OBJC_PROTOCOL_CAAction, so maybe it gets it because it's the first file to be compiled that imports CAAction.h?

@davidchisnall
Copy link
Member

Does something in that file do @protocol(CAAction)? Can you attack the preprocessed source for CAAnimation.m and I'll take a look.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

Here is the preprocessed source (I posted it above, but might not have been clear): https://gist.github.com/ethanc8/46be627ad36326f9b32843fe6409d77d

The word CAAction appears nowhere in the un-preprocessed source.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

Wait, I didn't see this:

@interface CAAnimation : NSObject <NSCoding, NSCopying, CAAction, CAMediaTiming>

@davidchisnall
Copy link
Member

Yup, looks like the protocol is adopted, so it is correct for it to be emitted in this file. But for some reason it's not initialised correctly. Looks like a compiler bug. If you can create a reduced test case that would be helpful (delete bits of the file, compile with -S -emit-llvm and see if the resulting file has 0 for the first field of _OBJC_PROTOCOL_CAAction), otherwise I'll try to look at it later in the week.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

Ok, thanks. I'm not sure whether it's a compiler bug, since it seems to be initialised correctly for my test case which creates classes and categories implementing CAAction and instantiates CAAnimation.

@ethanc8
Copy link
Author

ethanc8 commented Jun 4, 2024

The original CAAnimation.m gets CAAction compiled to:

$._OBJC_PROTOCOL_CAAction = comdat any
// a few hundred lines later
@52 = private unnamed_addr constant [9 x i8] c"CAAction\00", align 1
@._OBJC_PROTOCOL_CAAction = global { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { ptr inttoptr (i32 4 to ptr), ptr @52, ptr @.objc_protocol_list.10, ptr @.objc_protocol_method_list.11, ptr @.objc_protocol_method_list.13, ptr @.objc_protocol_method_list.12, ptr @.objc_protocol_method_list.14, ptr null, ptr null, ptr null, ptr null }, section "__objc_protocols", comdat, align 8
// a few lines later
@.objc_protocol_list.20 = internal global { ptr, i64, [4 x ptr] } { ptr null, i64 4, [4 x ptr] [ptr @._OBJC_PROTOCOL_NSCoding, ptr @._OBJC_PROTOCOL_NSCopying, ptr @._OBJC_PROTOCOL_CAAction, ptr @._OBJC_PROTOCOL_CAMediaTiming] }, align 8

I've attached the full LLVM IR to https://gist.github.com/ethanc8/d02ef13441e1eb58d372cf650fa3f63b

@davidchisnall
Copy link
Member

That looks correct. The isa pointer is that ptr inttoptr (i32 4 to ptr) one: we're initialising it to 4 in the compiler, so it should be a GNUstepV2 protocol. So now the question is: where does that become 0? Can you put a watchpoint on the load address and see if there are any writes to it?

@ethanc8
Copy link
Author

ethanc8 commented Jun 5, 2024

Can you put a watchpoint on the load address and see if there are any writes to it?

Which load address are you talking about?

@ethanc8
Copy link
Author

ethanc8 commented Jun 5, 2024

Ok, I set a watchpoint at 0x7ffff6ab3a60 (the address of CAAction).

Hardware watchpoint 1: *(int*)0x7ffff6ab3a60

Old value = 4
New value = 0
registerProtocol (proto=0x7ffff6ab3a60 <._OBJC_PROTOCOL_CAAction>) at /home/ethan/Projects/GNUstep/plaurent2/gnustep/libobjc2/protocol.c:608
608             if (protocol_for_name(proto->name) == NULL)
(gdb) 

@ethanc8
Copy link
Author

ethanc8 commented Jun 5, 2024

If I try to forcefully reset it back to 4, it does:

(gdb) set var proto->isa=0x4
(gdb) continue
Continuing.

Hardware watchpoint 1: *(int*)0x7ffff6ab3a60

Old value = 4
New value = -143207376
init_protocols (protocols=0x7ffff6aaa030 <objc_protocol_list>) at /home/ethan/Projects/GNUstep/plaurent2/gnustep/libobjc2/protocol.c:245
245                     if (NULL != aProto->protocol_list)
(gdb) 

and then fails with Unknown protocol version.

@davidchisnall
Copy link
Member

Okay, this looks like a load-order problem. The line above the one in your gdb session is proto->isa = protocol_class_gsv2;. If we haven’t yet loaded the protocol classes, this will be null, and that seems to be what you’re seeing.

Most of the paths that should be here are guarded on having loaded the runtime. Can you print a backtrace there? I suspect the simplest thing to do is treat the built-in classes as special and define them in C rather than relying on the normal load sequence.

Does the library defining this protocol explicitly link libobjc2? If it does, we should see the libobjc2 constructors run first (I think).

@ethanc8
Copy link
Author

ethanc8 commented Jun 5, 2024

Here's the backtrace:

Hardware watchpoint 1: *(int*)0x7ffff6ab3a60

Old value = 4
New value = 0
registerProtocol (proto=0x7ffff6ab3a60 <._OBJC_PROTOCOL_CAAction>) at /home/ethan/Projects/GNUstep/plaurent2/gnustep/libobjc2/protocol.c:608
608             if (protocol_for_name(proto->name) == NULL)
(gdb) bt
#0  registerProtocol (proto=0x7ffff6ab3a60 <._OBJC_PROTOCOL_CAAction>) at /home/ethan/Projects/GNUstep/plaurent2/gnustep/libobjc2/protocol.c:608
#1  0x00007ffff774b1a5 in __objc_load (init=0x7ffff6aa9638 <objc_init>) at /home/ethan/Projects/GNUstep/plaurent2/gnustep/libobjc2/loader.c:241
#2  0x00007ffff7fc947e in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffd398, env=env@entry=0x7fffffffd3a8) at ./elf/dl-init.c:70
#3  0x00007ffff7fc9568 in call_init (env=0x7fffffffd3a8, argv=0x7fffffffd398, argc=1, l=<optimized out>) at ./elf/dl-init.c:33
#4  _dl_init (main_map=0x7ffff7ffe2e0, argc=1, argv=0x7fffffffd398, env=0x7fffffffd3a8) at ./elf/dl-init.c:117
#5  0x00007ffff7fe32ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6  0x0000000000000001 in ?? ()
#7  0x00007fffffffd88b in ?? ()
#8  0x0000000000000000 in ?? ()
(gdb) p protocol_class_gsv2
$1 = (id) 0x0

@ethanc8
Copy link
Author

ethanc8 commented Jun 5, 2024

All of the libraries and apps should be linking libobjc2:

$ gnustep-config --objc-libs
-ldispatch -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.1 -fblocks -L/home/ethan/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries -lpthread -lobjc -lm

davidchisnall added a commit that referenced this issue Jun 6, 2024
Generate these classes using the structures that the runtime expects
internally, rather than relying on the Objective-C compiler.  This
change means that they can always be the latest version, even if the
runtime is compiled with an older compiler, and ensures that the
`Protocol` class is always available, independent of global constructor
ordering between libraries.

Fixes #283
@davidchisnall davidchisnall linked a pull request Jun 6, 2024 that will close this issue
@davidchisnall
Copy link
Member

Please can you test #294 and see if this fixes it for you?

@ethanc8
Copy link
Author

ethanc8 commented Jun 6, 2024

Please can you test #294 and see if this fixes it for you?

I will try to do so tonight, but I'm a bit busy today.

@ethanc8
Copy link
Author

ethanc8 commented Jun 8, 2024

Please can you test #294 and see if this fixes it for you?

Yes, it seems to be working now. Thanks! Do you want me to confirm anything in the debugger for you? I have just noticed that it no longer aborts with "Unknown protocol version".

@davidchisnall
Copy link
Member

No, that’s great. Thanks.

davidchisnall added a commit that referenced this issue Jun 8, 2024
Generate these classes using the structures that the runtime expects
internally, rather than relying on the Objective-C compiler.  This
change means that they can always be the latest version, even if the
runtime is compiled with an older compiler, and ensures that the
`Protocol` class is always available, independent of global constructor
ordering between libraries.

Fixes #283
@ethanc8
Copy link
Author

ethanc8 commented Jun 12, 2024

We still need to figure out what caused the segfault in SparseArrayLookup.

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

Successfully merging a pull request may close this issue.

2 participants