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

fatalError when trying to send a message using URLSessionWebSocketTask #4730

Closed
LosFarmosCTL opened this issue Mar 30, 2023 · 7 comments · Fixed by #5128
Closed

fatalError when trying to send a message using URLSessionWebSocketTask #4730

LosFarmosCTL opened this issue Mar 30, 2023 · 7 comments · Fixed by #5128
Assignees

Comments

@LosFarmosCTL
Copy link

LosFarmosCTL commented Mar 30, 2023

Hey, I am trying to get a WebSocket connection running on Linux using FoundationNetworking, I am using the nightly-5.8-jammy docker image inside of a devcontainer:

Swift version 5.8-dev (LLVM f0fb631dd1a3a29, Swift ef7a6b85c8f7360)
Target: x86_64-unknown-linux-gnu

Everything compiles correctly but when I try to actually send a message (UPDATE: also happens when calling receive()), I get a fatalError, saying that the URL is invalid:

Swift/ErrorType.swift:200: Fatal error: Error raised at top level: Error Domain=NSURLErrorDomain Code=-1002 "(null)"
Current stack trace:
0    libswiftCore.so                    0x00007fda5194db10 _swift_stdlib_reportFatalErrorInFile + 112
1    libswiftCore.so                    0x00007fda5163f40f <unavailable> + 1442831
2    libswiftCore.so                    0x00007fda5163f227 <unavailable> + 1442343
3    libswiftCore.so                    0x00007fda5163e030 _assertionFailure(_:_:file:line:flags:) + 364
4    libswiftCore.so                    0x00007fda5169ce96 <unavailable> + 1826454
5    Test                               0x000055df55764eed <unavailable> + 57069
6    libswift_Concurrency.so            0x00007fda51b5d0ee <unavailable> + 274670
7    libswift_Concurrency.so            0x00007fda51b5d860 swift_job_run + 92
8    libdispatch.so                     0x00007fda51d9bf45 <unavailable> + 192325
9    libdispatch.so                     0x00007fda51d9cbbd <unavailable> + 195517
10   libdispatch.so                     0x00007fda51da4002 <unavailable> + 225282
11   libc.so.6                          0x00007fda5130ab43 <unavailable> + 609091
12   libc.so.6                          0x00007fda5139ca00 <unavailable> + 1206784
Illegal instruction (core dumped)

I attempt to connect to Twitch Chat, I've made a very simple test that just tries to send a single message to their server:

import Foundation

#if canImport(FoundationNetworking)
  import FoundationNetworking
#endif

@main public struct Test {
  public static func main() async throws {
    let url = URL(string: "wss://irc-ws.chat.twitch.tv:443")!

    let ws = URLSession.shared.webSocketTask(with: url)

    ws.resume()

    try await ws.send(.string("CAP REQ :twitch.tv/tags"))
  }
}

That code runs perfectly fine under macOS (using Swift 5.7), but as soon as it's run on Linux I get the error from above.

I've tried using different WebSocket URLs, but everything yields the same result.

@monsieurjonees
Copy link

I'm having this same problem

@monsieurjonees
Copy link

monsieurjonees commented Mar 30, 2023

I've been having issues with receive(): I'm using Swift 5.8-dev on Ubuntu 22.04 LTS

import Foundation

// Import URL Session on Linux:
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

@main
public struct Test {
    public private(set) var text = "Hello, World!"

    public static func main() async throws {
        let ws = URLSession.shared.webSocketTask(with: URL(string: "wss://gateway.discord.gg/?v=10&encoding=json")!)
        ws.resume()
        
        _ = try await ws.receive()
    }
}

And:

Swift/ErrorType.swift:200: Fatal error: Error raised at top level: Error Domain=NSURLErrorDomain Code=-1002 "(null)"
Current stack trace:
0    libswiftCore.so                    0x00007fc021177b10 _swift_stdlib_reportFatalErrorInFile + 112
1    libswiftCore.so                    0x00007fc020e6940f <unavailable> + 1442831
2    libswiftCore.so                    0x00007fc020e69227 <unavailable> + 1442343
3    libswiftCore.so                    0x00007fc020e68030 _assertionFailure(_:_:file:line:flags:) + 364
4    libswiftCore.so                    0x00007fc020ec6e96 <unavailable> + 1826454
5    PhloydBot                          0x000055901c4322cd <unavailable> + 123597
6    libswift_Concurrency.so            0x00007fc0213870ee <unavailable> + 274670
7    libswift_Concurrency.so            0x00007fc021387860 swift_job_run + 92
8    libdispatch.so                     0x00007fc021715f45 <unavailable> + 192325
9    libdispatch.so                     0x00007fc021716bbd <unavailable> + 195517
10   libdispatch.so                     0x00007fc02171e002 <unavailable> + 225282
11   libc.so.6                          0x00007fc020b34b43 <unavailable> + 609091
12   libc.so.6                          0x00007fc020bc6a00 <unavailable> + 1206784
Illegal instruction (core dumped)

Specifically on Linux--no errors if run from Xcode/on macOS.

@LosFarmosCTL
Copy link
Author

I've been having issues with receive()

Yup, I didn't even think to test receive() since Twitch doesn't send anything without the client authenticating explicitly with NICK + PASS, but I can confirm this is also the case for me.

Updated the main issue as well to reflect that.

Only an issue on Linux, using macOS everything works as expected.

@LosFarmosCTL
Copy link
Author

This is still happening on the official swift:5.8 release image.

@tkrajacic
Copy link

To be honest it seems the WebSocket implementation can never work, as libcurl4 doesn't report supporting the protocols. At least in all of my experiments with even the most recent versions, curl-config --protocols never lists ws or wss.

And if I am not mistaken, that's what is checked here in CFURLSessionInterface.c

Boolean CFURLSessionWebSocketsSupported(void) {
    curl_version_info_data *info = curl_version_info(CURLVERSION_NOW);
    for (int i = 0; ; i++) {
        const char * const protocol = info->protocols[i];
        if (protocol == NULL) {
            break;
        }
        if ((0 == strncmp(protocol, "ws", 2)) ||
            (0 == strncmp(protocol, "wss", 3))) {
            return true;
        }
    }
    return false;
}

But maybe I am just holding it wrong™ 🤷‍♂️

@rojvv
Copy link

rojvv commented Jun 29, 2023

You are holding it right :(

image]

Image Source

@kevinrpb
Copy link

Just for reference: Even when compiling libcurl from source with websocket support, WebSocketURLProtocol throws a fatal error (this is Swift 6.0).

FoundationNetworking/WebSocketURLProtocol.swift:134: Fatal error: WebSocket internal invariant violated

*** Signal 5: Backtracing from 0xaaaab72d80cc... done ***

*** Program crashed: System trap at 0x0000aaaab72d80cc ***

Thread 0 crashed:

 0              0x0000aaaab72d80cc _assertionFailure(_:_:file:line:flags:) + 252 in libcurl-websocket-testapp
 1 [ra]         0x0000aaaab77c3354 _WebSocketURLProtocol.notifyTask(aboutReceivedData:flags:) + 3635 in libcurl-websocket-testapp
 2 [ra]         0x0000aaaab77c2254 _WebSocketURLProtocol.didReceive(data:) + 731 in libcurl-websocket-testapp
 3 [ra]         0x0000aaaab7800048 _EasyHandle.didReceive(data:size:nmemb:) + 95 in libcurl-websocket-testapp
 4 [ra]         0x0000aaaab78001c4 @objc closure #1 in _EasyHandle.setupCallbacks() + 67 in libcurl-websocket-testapp
 5 [ra]         0x0000ffff8903cfa8 cw_out_ptr_flush + 263 in libcurl.so.4.8.0
 6 [ra]         0x0000ffff8903d630 cw_out_do_write + 239 in libcurl.so.4.8.0
 7 [ra]         0x0000ffff8903d748 cw_out_write + 119 in libcurl.so.4.8.0
 8 [ra]         0x0000ffff89093020 ws_cw_dec_next + 299 in libcurl.so.4.8.0
 9 [ra]         0x0000ffff89091c68 ws_dec_pass + 515 in libcurl.so.4.8.0
10 [ra]         0x0000ffff89091fec ws_cw_write + 155 in libcurl.so.4.8.0
11 [ra]         0x0000ffff8907818c cw_download_write + 199 in libcurl.so.4.8.0
12 [ra]         0x0000ffff890795cc Curl_client_write + 71 in libcurl.so.4.8.0
13 [ra]         0x0000ffff89088a84 Curl_xfer_write_resp + 51 in libcurl.so.4.8.0
14 [ra]         0x0000ffff89088d94 Curl_sendrecv + 591 in libcurl.so.4.8.0
15 [ra]         0x0000ffff8906c348 multi_runsingle + 1831 in libcurl.so.4.8.0
16 [ra]         0x0000ffff8906d070 multi_run_expired + 191 in libcurl.so.4.8.0
17 [ra]         0x0000ffff8906dfbc multi_socket + 171 in libcurl.so.4.8.0
18 [ra]         0x0000aaaab780291c URLSession._MultiHandle.readAndWriteAvailableData(on:) + 67 in libcurl-websocket-testapp
19 [ra]         0x0000aaaab7802170 closure #1 in URLSession._MultiHandle.register(socket:for:what:socketSourcePtr:) + 75 in libcurl-websocket-testapp
20 [ra] [thunk] 0x0000aaaab5aedc94 thunk for @escaping @callee_guaranteed () -> () + 47 in libcurl-websocket-testapp at //<compiler-generated>
21 [ra]         0x0000aaaab760f80c _dispatch_block_async_invoke2 + 103 in libcurl-websocket-testapp
22 [ra]         0x0000aaaab7606b18 _dispatch_continuation_pop + 235 in libcurl-websocket-testapp
23 [ra]         0x0000aaaab7614474 _dispatch_source_invoke + 1679 in libcurl-websocket-testapp
24 [ra]         0x0000aaaab760a420 _dispatch_lane_serial_drain + 315 in libcurl-websocket-testapp
25 [ra]         0x0000aaaab760b1c8 _dispatch_lane_invoke + 999 in libcurl-websocket-testapp
26 [ra]         0x0000aaaab760a420 _dispatch_lane_serial_drain + 315 in libcurl-websocket-testapp
27 [ra]         0x0000aaaab760b1c8 _dispatch_lane_invoke + 999 in libcurl-websocket-testapp
28 [ra]         0x0000aaaab760a420 _dispatch_lane_serial_drain + 315 in libcurl-websocket-testapp
29 [ra]         0x0000aaaab760b1c8 _dispatch_lane_invoke + 999 in libcurl-websocket-testapp
30 [ra]         0x0000aaaab7611a00 _dispatch_worker_thread + 431 in libcurl-websocket-testapp
31 [ra]         0x0000ffff889a597c <unknown> in libc.so.6

Even if the support is experimental in curl, this is maybe actionable by the team here?

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

Successfully merging a pull request may close this issue.

7 participants