Skip to content

[lldb] Allow SwiftASTContext fallbacks for types from expressions #10059

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

Merged

Conversation

adrian-prantl
Copy link

Generally, it would be feasible to rely on DWARF and reflectio metadata for JIT-compiled images, but in practice, not everything that an expression returns may be anchored by a variable, which makes having debug info for expression-defined types hit and miss. If an expression type is involved, LLDB will have done the costly SwiftASTContext initialization already, so there isn't much saved by avoiding the fallback in this case.

@adrian-prantl
Copy link
Author

@swift-ci test

@augusto2112
Copy link

Generally, it would be feasible to rely on DWARF and reflectio metadata for JIT-compiled images, but in practice, not everything that an expression returns may be anchored by a variable

Hmm, could you give an example of something that an expression returns that is not anchored by a variable?

@adrian-prantl
Copy link
Author

Generally, it would be feasible to rely on DWARF and reflectio metadata for JIT-compiled images, but in practice, not everything that an expression returns may be anchored by a variable

Hmm, could you give an example of something that an expression returns that is not anchored by a variable?

Totally! This is from TestSwiftExpr.py:

struct StructTest {
  func foo() {
    print("Stop here in method \(m_var)") //% self.expect("expr self", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["StructTest"])
                                          //% self.expect("expr typealias foo = StructTest; self as foo", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["foo"]) 
  }
  let m_var = 234
}

There is nothing holding on to foo so there is no DWARF being generated for it.

Copy link

@augusto2112 augusto2112 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this if we legitimately can't use DWARF and reflection metadata for certain use-cases.

@augusto2112
Copy link

augusto2112 commented Feb 19, 2025

struct StructTest {
  func foo() {
    print("Stop here in method \(m_var)") //% self.expect("expr self", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["StructTest"])
                                          //% self.expect("expr typealias foo = StructTest; self as foo", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["foo"]) 
  }
  let m_var = 234
}

You mean the type alias foo right? $__lldb_result should be holding on to foo, no?

With the expression log enabled:

 Variables:
   [name=$__lldb_injected_self, type = t.StructTest]
   [name=$__lldb_result, type = __lldb_expr_3.foo, is_result]
   [name=$__lldb_error_result, type = any Swift.Error, is_error]

Is it because $__lldb_result is special in some way it's not enough to make DWARF hold on to the type?

@adrian-prantl
Copy link
Author

Good question! I only looked at the expression log to see what DITypes are generated and there was no DILocalVariable for the result:

extension $__lldb_context {
  @LLDBDebuggerFunction @available(macOS 15.3.0, *)
  mutating func $__lldb_user_expr_1(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
    
do {
/*__LLDB_USER_START__*/
#sourceLocation(file: "/var/folders/n4/dh4jjrps5mz1wbw_thlvls940000gn/T/expr3-631fed..cpp", line: 1)
typealias foo = StructTest; self as foo

/*__LLDB_USER_END__*/
} catch (let __lldb_tmp_error) {
  var $__lldb_error_result = __lldb_tmp_error
}

  }
}
@LLDBDebuggerFunction @available(macOS 15.3.0, *)
func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
  do {
    $__lldb_injected_self.$__lldb_user_expr_1(
      $__lldb_arg
    )
  }
}

@adrian-prantl
Copy link
Author

define hidden swiftcc void @"$s1a10StructTestV13__lldb_expr_4E03$__c6_user_D2_1yySpyypGF"(ptr %0, ptr nocapture swiftself dereferenceable(8) %1) #0 !dbg !35 {
  %3 = alloca ptr, align 8
  call void @llvm.memset.p0.i64(ptr align 8 %3, i8 0, i64 8, i1 false)
  %4 = alloca ptr, align 8
  call void @llvm.memset.p0.i64(ptr align 8 %4, i8 0, i64 8, i1 false)
  store ptr %0, ptr %3, align 8, !dbg !53
    #dbg_value(ptr %3, !50, !DIExpression(DW_OP_deref), !54)
  store ptr %1, ptr %4, align 8, !dbg !53
    #dbg_value(ptr %4, !52, !DIExpression(DW_OP_deref, DW_OP_deref), !55)
  %5 = getelementptr inbounds i8, ptr %0, i64 32, !dbg !56
  %6 = load ptr, ptr %5, align 8, !dbg !56
  %7 = getelementptr inbounds i8, ptr %0, i64 24, !dbg !56
  %8 = load ptr, ptr %7, align 8, !dbg !56
  %9 = getelementptr inbounds i8, ptr %0, i64 8, !dbg !56
  %10 = load ptr, ptr %9, align 8, !dbg !56
  %11 = getelementptr inbounds i8, ptr %0, i64 16, !dbg !56
  %12 = load ptr, ptr %11, align 8, !dbg !56
  %13 = getelementptr inbounds %T1a10StructTestV, ptr %1, i32 0, i32 0, !dbg !59
  %14 = getelementptr inbounds %TSi, ptr %13, i32 0, i32 0, !dbg !59
  %15 = load i64, ptr %14, align 8, !dbg !59
  %16 = getelementptr inbounds %T1a10StructTestV, ptr %8, i32 0, i32 0, !dbg !59
  %17 = getelementptr inbounds %TSi, ptr %16, i32 0, i32 0, !dbg !59
  store i64 %15, ptr %17, align 8, !dbg !59
  ret void, !dbg !64
}

!50 = !DILocalVariable(name: "$__lldb_arg", arg: 1, scope: !35, file: !13, line: 4, type: !51)
!51 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !39)
!52 = !DILocalVariable(name: "self", arg: 2, scope: !35, file: !13, line: 4, type: !47, flags: DIFlagArtificial)

Generally, it would be feasible to rely on DWARF and reflectio
metadata for JIT-compiled images, but in practice, not everything that
an expression returns may be anchored by a variable, which makes
having debug info for expression-defined types hit and miss. If an
expression type is involved, LLDB will have done the costly
SwiftASTContext initialization already, so there isn't much saved by
avoiding the fallback in this case.
@adrian-prantl
Copy link
Author

@swift-ci test

@adrian-prantl adrian-prantl merged commit bd66d7d into swiftlang:stable/20240723 Feb 20, 2025
3 checks passed
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 this pull request may close these issues.

2 participants