Closed CodingMeSwiftly closed 4 years ago
Curious thing I found while trying to resolve the issue: If I clone the repo and build the lib on my machine, the resulting .dylib file is 1.6MB. The .dylib downloaded from the release page linked above is 1.3MB.
Nevertheless, the issue is still there when I try the lib built on my machine.
It's not that surprising that the .dylib's are different sizes. The release one is targeting an older MacOS and is built by a CI, using whatever dependencies the CI pulls in.
FYI, when you create a stream info, that doesn't create the stream, just the metadata. The stream isn't created until you create the outlet. So I don't know if it's what you were expecting, but you wouldn't be able to find "Foo".
Regardless, that shouldn't prevent lsl_resolve_all
from returning with no streams found after a timeout.
Just so we can isolate the issue, can you try using lsl_resolve_all
in a simple C/C++ app and see if that works for you? If yes then I really don't know what the issue is. I have zero experience with Swift. If no, then there's some more digging we can do together.
Thank you for the quick response!
Yes the stream info and library info prints are just to verify that the Swift-C interop is working. I'm aware lsl_streaminfo is just the data model for an actual connection point :)
I can verify that the simplest of C / C++ implementations (call lsl_resolve_all in main) work without issues.
I have tried to make more sense out of the cpu overload and captured some backtraces / callstacks of the thread running at 100% cpu usage:
It seems to me that the call to _lslboost::asio::detail::socketops::bind is the culprit. Whatever the reason might be is beyond me :/
Is it possible that the underlying networking for outlet discovery is using some exotic socket config? I am not really sure if Apple locked some multi- / broadcast or other socket functionality for macOS and iOS apps for "security" reasons :( That could be the reason why a C++ command line tool works, when a signed Cocoa application doesn't :/
I will build a separate macOS App using Objective-C to make sure the issue is not caused by Swift. I don’t know if it’s appropriate to mention this in this thread (If you want me to open another issue or feature request please let me know): is there any chance the library might get iOS support in the future? I think it should be possible to build for iOS since macOS works, but unfortunately I am very inexperienced with CMake and don’t really know where to start on that. Thanks for your help.
Is it possible that the underlying networking for outlet discovery is using some exotic socket config?
Not really, the service discovery uses plain UDP sockets + multicast.
I am not really sure if Apple locked some multi- / broadcast or other socket functionality for macOS and iOS apps for "security" reasons.
That's what I suspect, we've had some problems with Macs (#28, #36) but nothing we've been able to reproduce on our local Macs (i.e. Chad's Mac and a spare Macbook I can use from time to time).
In theory, it shouldn't matter what language you call the functions from, except when the Swift runtime somehow restricts the OS functions the C library can call.
There are two things you might try: I've reworked some of the multicast handling to be hopefully more reliable (#31, OS X binaries), maybe it also fixes your problem.
If not, you could capture the actual network packets (sudo tcpdump -i any -n -w test.pcap port 16571 or igmp or icmp6 or icmp or ip6 multicast
or so) for the both the working C++ example and an equivalent Swift example.
Thank you for your answer. I did some more tests and found the following:
Cocoa App in Swift >> 100% CPU Cocoa App in ObjC >> 100% CPU CommandLineTool in C >> Works CommandLineTool in C++ >> Works CommandLineTool in ObjC >> Works CommandLineTool in Swift >> Works
So the issue is definitely not Swift, but rather some quirks within the Cocoa application.
I tried to capture the tcpdump. It works fine for CommandLineTool applications. For Cocoa Apps, the resulting .pcap file is Zero KB. No idea what that could mean.
Further, I have verified that App Transport Security - https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity - which is the only networking constraint for macOS and iOS apps I can think of from the top of my head, is not causing the issue. I.e.: If I turn it off, the issue is still there.
Well, this is a bit embarrassing...
The "quirk within the Cocoa application" was a checkbox in the Capabilities section of the Xcode project.
I had to enable Outgoing Connections for the App Sandbox. For whatever reason Xcode did not produce and error and inform me about the missing capability, but rather choked the CPU ...
Well it's working now. Thank you for your time and help.
I don’t know if it’s appropriate to mention this in this thread (If you want me to open another issue or feature request please let me know): is there any chance the library might get iOS support in the future? I think it should be possible to build for iOS since macOS works, but unfortunately I am very inexperienced with CMake and don’t really know where to start on that. Thanks for your help.
Is there any chance this might get addressed in the future? :)
is there any chance the library might get iOS support in the future?
Sure, and I don't mean that someone buys me a fancy Macbook Pro) :-)
CMake can cross-compile if it's told which compiler + settings to use. For iOS, there's a toolchain configuration that should suffice, but so far no-one has tested it yet. If that's not working, you should get a more or less helpful error message to create a new issue with.
Ok thanks for the info and all the help. Very much appreciate it :) I'll close the issue.
Just for the record: the current implementation has an infinite loop in case no port can be bound to so I fixed it (cdce3aaf2044fa823beb7cac0e3ec376f1c7d78c).
I'm using the latest release https://github.com/sccn/liblsl/releases/tag/1.13.0-b13 and include the .dylib in my Xcode project as an embedded framework.
I created a bridging header in oder to be able to use the c library from Swift code.
I can use the library and invoke lsl_* functions so I assume the lib is linked and included properly in my app target.
However, when I invoke lsl_resolve_all the function does not return and the app consumes 100% cpu.
I understand that the latest release is targeting macOS 10.12. I'm running 10.15(.1). Is that the problem? If so, why are some functions of the lib working just fine but lsl_resolve_all hangs the app? Any idea on how to resolve this?