Search code examples
swiftlldb

error: use of undeclared type '$__lldb_context' in NSAttributedString extension


Given the following Swift code, saved in bug.swift, and using Xcode 8.2.1 or Xcode 8.3 beta 2:

import Foundation

protocol MyProtocol {
    func foo() -> String
}

extension MyProtocol {
    func foo() -> String {
        return "\(self)"
    }
}

extension String: MyProtocol {}
extension NSAttributedString: MyProtocol {}

let normal = "normal".foo()
let attributed = NSAttributedString(string: "attributed", attributes: [:]).foo()

Run the following commands:

swiftc -g bug.swift
lldb bug

LLDB launches. Now, run these commands, and observe the output. Where I pass 9, pass the line in your bug.swift that contains return "\(self)":

(lldb) target create "bug"
Current executable set to 'bug' (x86_64).
(lldb) b 9
Breakpoint 1: where = bug`(extension in bug):bug.MyProtocol.foo () -> Swift.String + 19 at bug.swift:9, address = 0x0000000100001e53
(lldb) run
Process 16370 launched: '/Users/zev/Desktop/bug' (x86_64)
Process 16370 stopped
* thread #1: tid = 0x31730e, 0x0000000100001e53 bug`MyProtocol.foo(self="normal") -> String + 19 at bug.swift:9, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100001e53 bug`MyProtocol.foo(self="normal") -> String + 19 at bug.swift:9
   6    
   7    extension MyProtocol {
   8        func foo() -> String {
-> 9            return "\(self)"
   10       }
   11   }
   12   
(lldb) po self
"normal"


(lldb) c
Process 16370 resuming
Process 16370 stopped
* thread #1: tid = 0x31730e, 0x0000000100001e53 bug`MyProtocol.foo(self=0x00007fff5fbff480) -> String + 19 at bug.swift:9, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100001e53 bug`MyProtocol.foo(self=0x00007fff5fbff480) -> String + 19 at bug.swift:9
   6    
   7    extension MyProtocol {
   8        func foo() -> String {
-> 9            return "\(self)"
   10       }
   11   }
   12   
(lldb) po self
error: <EXPR>:1:11: error: use of undeclared type '$__lldb_context'
extension $__lldb_context {                            
          ^~~~~~~~~~~~~~~

error: <EXPR>:18:5: error: use of unresolved identifier '$__lldb_injected_self'
    $__lldb_injected_self.$__lldb_wrapped_expr_2(     
    ^~~~~~~~~~~~~~~~~~~~~

The first time we hit the breakpoint, we're in String's conformance to MyProtocol, and we can successfully po self.

However, the second time we hit the breakpoint, we're in NSAttributedString's conformance to MyProtocol, and LLDB prints gibberish instead of the expected output from po self.

Why does LLDB sometimes fail to print anything useful? This is a contrived example, but I run into this all the time in my day-to-day use of LLDB.


Solution

  • According to this answer on the Swift bug reporter, the bug was fixed at some point. I tested in Swift 5.2, and confirmed that it's fixed 🎉