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

[SR-404] Loading Foundation protocol conformances fails #43021

Closed
lhoward opened this issue Dec 29, 2015 · 13 comments
Closed

[SR-404] Loading Foundation protocol conformances fails #43021

lhoward opened this issue Dec 29, 2015 · 13 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself non-optimized only Flag: An issue whose reproduction requires non-optimized compilation

Comments

@lhoward
Copy link
Contributor

lhoward commented Dec 29, 2015

Previous ID SR-404
Radar None
Original Reporter @lhoward
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, NotOptimizedOnly
Assignee @lhoward
Priority Medium

md5: 51dd469c08298ef01774de06da791016

blocks:

  • SR-377 Implement NSKeyed[Un]Archiver

duplicates:

  • SR-310 Int fails to convert to protocol adopted values on linux

Issue Description:

The following code

    let foo = (NSMutableArray() as? AnyObject) as? NSCoding

whilst warned at compile-time to always succeed, fails at runtime, both within Foundation and within a program that links to Foundation. The failure appears to be within_dynamicCastToExistential()’s check for _conformsToProtocols().

Similarly, if I try "NSMutableArray() is NSCoding", it is warned to be true at compile time but aborts at runtime with:

Could not cast value of type 'Foundation.NSMutableArray' (0x7fc8498acb68) to 'Foundation.NSCoding' (0x7fc84a364050).

If I replace NSMutableArray() with a class that is defined in my program that links to Foundation, these tests work. Casting directly to NSCoding without going via AnyObject also works.

@lhoward
Copy link
Contributor Author

lhoward commented Dec 29, 2015

NSKeyedArchiver needs this fixed to work on Linux.

@lhoward
Copy link
Contributor Author

lhoward commented Dec 29, 2015

This may be the same as SR-310.

@gottesmm
Copy link
Member

This might be related to cast optimization code. I don't remember if our cast optimizations are guaranteed though. Does this happen with optimization?

@lhoward
Copy link
Contributor Author

lhoward commented Dec 29, 2015

debug build of everything if that helps (and Linux only)

@gottesmm
Copy link
Member

Thanks!

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

Not sure if this is helpful: if I call ProtocolConformanceRecord::dump() from swift::swift_conformsToProtocol(), I'm not seeing any Foundation types. Still investigating.

  for (; sectionIdx < endSectionIdx; ++sectionIdx) {
    auto &section = C.SectionsToScan[sectionIdx];
    // Eagerly pull records for nondependent witnesses into our cache.
    for (const auto &record : section) {
        record.dump();

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

Another datapoint: in _addImageProtocolConformances() for libFoundation.so, conformancesSize is zero.

(lldb) x conformances-8
0x7ffff685e330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x7ffff685e340: 01 00 00 00 00 00 00 00 75 00 00 00 00 00 00 00  ........u.......

(-8 as dump was after conformances += 8)

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

Is _addImageProtocolConformances() right? .swift2_protocol_conformances_start is a section not a symbol? I don't know if you can use dlsym() here...

Edit: sorry, my bad, dlsym("swift2_protocol_conformances_start") does work, the problem is elsewhere.

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

lukeh@ubuntu:~/CVSRoot/apple/swift$ readelf -x .swift2_protocol_conformances ../build/Ninja-DebugAssert/foundation-linux-x86_64/Foundation/libFoundation.so 

Hex dump of section '.swift2_protocol_conformances':
0x008dba38 7142fdff 5442fdff 00000000 01000000 qB..TB..........
0x008dba48 00000000 743bfeff 00000000 0f000000 ....t;..........
...

vs

lukeh@ubuntu:~/CVSRoot/apple/swift$ readelf -x .swift2_protocol_conformances ../build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/libswiftCore.so

Hex dump of section '.swift2_protocol_conformances':
  0x0083a578 20300000 00000000 00000000 00000000  0..............
  0x0083a588 00000000 04000000 00000000 00000000 ................

with the latter under the debugger:

(lldb) x conformances conformances+1024
0x7ffff7da6578: 20 30 00 00 00 00 00 00 10 c1 00 00 54 49 02 00   0..........TI..
0x7ffff7da6588: 48 17 01 00 04 00 00 00 b0 6e 00 00 44 49 02 00  H........n..DI..
0x7ffff7da6598: 48 17 01 00 04 00 00 00 a0 6e 00 00 cc 4a 02 00  H........n...J..
0x7ffff7da65a8: c0 17 01 00 04 00 00 00 48 b4 00 00 64 4c 02 00  ........H...dL..

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

More investigation, this program enumerates linked libraries with conformance sections and prints the first 32 bytes of them – also it prints the filename as returned by dladdr().

file: /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/foundation-linux-x86_64/Foundation/libFoundation.so
dladdr(/home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/foundation-linux-x86_64/Foundation/libFoundation.so): /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so .swift2_protocol_conformances_start
00000000000000000000000000000000
01000000000000007500000000000000
file: /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so
dladdr(/home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so): /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so .swift2_protocol_conformances_start
00000000000000000000000000000000
01000000000000007500000000000000
file: /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so
dladdr(/home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so): /home/lukeh/CVSRoot/apple/build/Ninja-DebugAssert/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so .swift2_protocol_conformances_start
203000000000000010c1000054490200

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

OK, the problem seems to be that the .swift2_protocol_conformances_start symbol created by the linker script is only there for libSwiftCore, not for libFoundation. Perhaps the linker script is not being invoked when building Foundation on Linux.

@lhoward
Copy link
Contributor Author

lhoward commented Dec 30, 2015

@lhoward
Copy link
Contributor Author

lhoward commented Dec 31, 2015

integrated in 576e6d9

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself non-optimized only Flag: An issue whose reproduction requires non-optimized compilation
Projects
None yet
Development

No branches or pull requests

2 participants