chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

Swiftをコマンドラインから起動する->実行できたがハングした

UPDのテストプログラム等をXCodeからビルドするのは手間なので、コマンドラインでさくっと動かせると楽。
普通に実行させると以下のようなエラーになる。

$ swift test.swift 
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),
 missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

調べると、設定が必要なようであった。

sudo xcode-select -s /Applications/Xcode.app
sudo xcode-select --install

結果、以下のようにコマンドラインから実行可能となった。

$ cat test.swift
#!/usr/bin/swift

print("Hello World")

$ swift test.swift
Hello World

$ ./test.swift 
Hello World

他人のサンプルを少し編集して実行(文法的におかしなところはあるにせよ)

import Network

//let host = NWEndpoint.Host(ipFamily.ssdpGroupName)
let multicastGroup = try NWMulticastGroup(for: [.hostPort(host: "192.168.10.120", port: .ssdp)])
let ssdpGroup = NWConnectionGroup(with: multicastGroup, using: .udp)
ssdpGroup.stateUpdateHandler = { newState in
                             print("Reached new state: \(newState)")
}
ssdpGroup.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: false, handler: {[weak\
 self] (message, content, isComplete) in
                                        	print("SSDP message received, do something here...")
})

let queue = DispatchQueue(label: "ExampleNetwork")
ssdpGroup.start(queue: queue)

NWMulticastGroup等が不明と言って怒られる。なぜだ?

$ swift UDP_mul_sample.swift 
UDP_mul_sample.swift:4:26: error: use of unresolved identifier 'NWMulticastGroup'
let multicastGroup = try NWMulticastGroup(for: [.hostPort(host: "192.168.10.120", port: .ssdp)])
                         ^~~~~~~~~~~~~~~~
UDP_mul_sample.swift:5:17: error: use of unresolved identifier 'NWConnectionGroup'
let ssdpGroup = NWConnectionGroup(with: multicastGroup, using: .udp)
                ^~~~~~~~~~~~~~~~~
UDP_mul_sample.swift:9:104: error: use of unresolved identifier 'self'

コマンドラインから実行しているのが悪いのか?それとも、実行しているOSのバージョンがMojaveだから?? catalinaに上げないとUDP Multicastは使えない?? 自分のMACに入っているFrameworkが古いせい??

少し調べた結果、iOSのバージョンを14.0、 XCodeのバージョンを12.0以上に上げる必要があるようだった。幸い、新しいOSのMacBookを借りられたので実行してみた。以下はソースコード(Swiftの細かい仕様は不勉強でわからんです)

import Network

//let host = NWEndpoint.Host(ipFamily.ssdpGroupName)
let multicastGroup = try NWMulticastGroup(for: [.hostPort(host: "192.168.10.120", port: 1234)])
let ssdpGroup = NWConnectionGroup(with: multicastGroup, using: .udp)
ssdpGroup.stateUpdateHandler = { newState in
                             print("Reached new state: \(newState)")
}
ssdpGroup.setReceiveHandler(maximumMessageSize: 16384, rejectOversizedMessages: false, handler: {
(message, content, isComplete) in
         	print("SSDP message received, do something here...")
})

let queue = DispatchQueue(label: "ExampleNetwork")
ssdpGroup.start(queue: queue)

エラーは発生しなかったが、思いっきりハングした。Exceptionすら吐いてないのでは?? SwiftはExceptionを吐かずにダンプするのか。。命令違反と怒られてもな。。SwiftはLLVM上で動いているのか。。XCodeのPlayGroundで走らせるとどうなるんだろう。。やっぱりダンプを吐くのだろうか。。

 % swift test2.swift
Stack dump:
0.	Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret test2.swift -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -color-diagnostics -target-sdk-version 11.0 -module-name test2 
1.	Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8)
2.	While running user code "test2.swift"
0  swift                    0x000000010f555c15 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1  swift                    0x000000010f556332 SignalHandler(int) + 610
2  libsystem_platform.dylib 0x00007fff20363d7d _sigtramp + 29
3  libsystem_platform.dylib 0x00007f855ff0ffff _sigtramp + 18446743550792745631
4  libswiftNetwork.dylib    0x00007fff54fcde07 $s7Network17NWConnectionGroupC4with5usingAcA17NWGroupDescriptor_p_AA12NWParametersCtcfC + 55
5  libswiftNetwork.dylib    0x000000011432120f $s7Network17NWConnectionGroupC4with5usingAcA17NWGroupDescriptor_p_AA12NWParametersCtcfC + 18446603343724098623
6  swift                    0x000000010adb4605 llvm::orc::runAsMain(int (*)(int, char**), llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, llvm::Optional<llvm::StringRef>) + 1221
7  swift                    0x000000010ad91ebb swift::RunImmediately(swift::CompilerInstance&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, swift::IRGenOptions const&, swift::SILOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >&&) + 6763
8  swift                    0x000000010ad6d5ce performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 2446
9  swift                    0x000000010ad5d7ba swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 21802
10 swift                    0x000000010acde2c1 main + 1265
11 libdyld.dylib            0x00007fff2033a631 start + 1
zsh: illegal hardware instruction  swift test2.swift

今後の取り組み
(1)どこでハングしているのかもわからないので、ソースコードを減らしながら落ちている原因のコードを探す
(2)Apppleから手取り足取りでNetwork FrameworkのUDPサンプルコードが出ているのでそっちのコードを打ち込んでみる


■参考URL
コマンドラインから実行するためのセットアップ
https://qiita.com/KanikaniYou/items/9829eef54b2e0d300de1