Hello!
I have been playing around with Embedded Swift for a couple weeks now, and one of the things I've been trying out is the debugger support. In the embedded world, coredumps, gdb, and C are king - I wanted to see how lldb + embedded swift compares.
However, I've run into a lot of problems, and searching both the Swift forums and Google has yielded shockingly few results.
As a minimal example, I have this very simple Embedded Swift program, designed to test our ability to inspect structs in the debugger.
struct Greeting {
var greeting: String
}
struct StaticGreeting {
var greeting: StaticString
}
struct Rect {
var x: Int32
var y: Int32
var w: Int32
var h: Int32
}
@_cdecl("swift_bp")
public func swift_bp() {}
@_cdecl("swift_say_hello")
public func swift_say_hello() {
let localNum = 1337
let structWithNums = Rect(x: 31, y: 7, w: 32, h: 64)
let localStaticString = StaticString("Static string test")
let structWithStaticString = StaticGreeting(greeting: "StaticHowdy")
let localString = String("This is a test")
let structWithString = Greeting(greeting: "Howdy")
swift_bp()
}
I run the debugger like
lldb --arch arm out/hello_world.elf \
--one-line "gdb-remote 1234"
(lldb) target create --arch=arm "out/hello_world.elf"
Current executable set to '[...]/out/hello_world.elf' (arm).
(lldb) gdb-remote 1234
Process 1 stopped
* thread #1, stop reason = signal SIGTRAP
frame #0: 0x00000044 hello_world.elf`_start at startup.c:10
7 }
8 }
9
-> 10 void _start() {
11 main();
12 _hang();
13 }
Target 0: (hello_world.elf) stopped.
(lldb) version
lldb version 21.0.0 (https://github.com/swiftlang/llvm-project.git revision bff1370bd79c9833d255e3837c77e8d2dff1901f)
Apple Swift version 6.3-dev (LLVM bff1370bd79c983, Swift 57cf4ce563f700b)
(lldb) b swift_bp
Breakpoint 1: 2 locations.
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, stop reason = breakpoint 1.2
frame #0: 0x00000568 hello_world.elf`swift_bp() at app_main.swift:17:25
14 }
15
16 @_cdecl("swift_bp")
-> 17 public func swift_bp() {}
18
19 @_cdecl("swift_say_hello")
20 public func swift_say_hello() {
Target 0: (hello_world.elf) stopped.
(lldb) s
Process 1 stopped
* thread #1, stop reason = step in
frame #0: 0x00000690 hello_world.elf`swift_say_hello() at app_main.swift:27:3
24 let structWithStaticString = StaticGreeting(greeting: "StaticHowdy")
25 let localString = String("This is a test")
26 let structWithString = Greeting(greeting: "Howdy")
-> 27 swift_bp()
28 }
Target 0: (hello_world.elf) stopped.
(lldb) p localNum
(Int) 1337
(lldb) p structWithNums
(app_main.Rect) (x = 31, y = 7, w = 32, h = 64)
(lldb) p localStaticString
(StaticString) "Static string test"
(lldb) p structWithStaticString
(app_main.StaticGreeting) (greeting = "StaticHowdy")
(lldb) p localString
(String) <cannot decode string: unexpected layout (count)>
warning: (arm) [...]/out/hello_world.elf '/var/folders/6m/zv5t5r411zj0m_k7vplhr1p40000gn/C/clang/ModuleCache/2FESEAI5PZZ60/SwiftShims-3UQX09UC1O02Q.pcm' does not exist
warning: (arm) [...]/out/hello_world.elf Unable to locate module needed for external types.
Debugging will be degraded due to missing types. Rebuilding the project will regenerate the needed module files.
warning: TypeSystemSwiftTypeRef::operator(): had to engage SwiftASTContext fallback for type $eSSD
(lldb) p structWithString
Assertion failed: (m_initialized_search_path_options && m_initialized_clang_importer_options && "search path options must be initialized before ClangImporter"), function GetASTContext, file SwiftASTContext.cpp, line 3658.
LLDB diagnostics will be written to /var/folders/6m/zv5t5r411zj0m_k7vplhr1p40000gn/T/diagnostics-064863
Please include the directory content when filing a bug report
make: *** [debug-lldb] Abort trap: 6
As you can see, it's very easy to crash the debugger, and we cannot print any strings.
It also fails if you try and have any expression as part of the print, with the same error.
(lldb) p localStaticString.print()
Assertion failed: (m_initialized_search_path_options && m_initialized_clang_importer_options && "search path options must be initialized before ClangImporter"), function GetASTContext, file SwiftASTContext.cpp, line 3658.
LLDB diagnostics will be written to /var/folders/6m/zv5t5r411zj0m_k7vplhr1p40000gn/T/diagnostics-f0f318
Please include the directory content when filing a bug report
make: *** [debug-lldb] Abort trap: 6
I tried with a number of different versions of Swift (via Swiftly), and we hit the same assert on all versions I tested - except on 6.1, where we exit with a clean error message (but are still unable to print the string).
A couple questions for folks here working with embedded swift:
- Is this the expected behaviour?
- Is this being actively worked on?
Thanks so much!