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

[SR-8938] Protocol extension with a generic parameter cannot be debugged #4486

Closed
swift-ci opened this issue Oct 7, 2018 · 18 comments
Closed
Assignees
Labels
bug Something isn't working LLDB for Swift

Comments

@swift-ci
Copy link

swift-ci commented Oct 7, 2018

Previous ID SR-8938
Radar rdar://problem/45216847
Original Reporter Milenkovic (JIRA User)
Type Bug
Status Closed
Resolution Done

Attachment: Download

Additional Detail from JIRA
Votes 0
Component/s LLDB for Swift
Labels Bug
Assignee @dcci
Priority Medium

md5: bbca8bfc45bc56b0ee325f92112b7837

Issue Description:

Attached file should demonstrate issues with using a generic parameter in protocol extension.
Steps:
1: put a breakpoint on line 21 and notice you can't know anything about "param"
2: put a breakpoint on line 40 and notice you can know everything about "param"

("anotherParam" visible in both places)

Part 2:
Put a breakpoint on line 23 and 42 and notice that now you also can't know anything about "anotherParam".

@AnnaZaks
Copy link
Mannequin

AnnaZaks mannequin commented Oct 12, 2018

CC friss (JIRA User)@dcci

@AnnaZaks
Copy link
Mannequin

AnnaZaks mannequin commented Oct 12, 2018

@swift-ci create

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 12, 2018

I'll take a look at this.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 12, 2018

OK, there are several bugs here. Thanks for the excellent report, I'll fix them one by one!

@swift-ci
Copy link
Author

Comment by Jovan (JIRA)

Cool, if needed feel free to alter name and description since this one is limited by my knowledge and time. It could improve searches/known issues and possibly your work tracking as an assignee.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 12, 2018

Your bug report is perfectly fine, as it describes the situation accurately. It's just an unfortunate series of events I'll fix on my side.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

Milenkovic (JIRA User) I submitted a pull request that should hopefully fix the first half
apple/swift-lldb#973

About the lack of visibility of the variables on line 23 and 42, I do suspect we kinda emit wrong debug info here (it's just a wild guess at this point, I need to verify and I'll do it later tonight).

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

I think the second problem you report might be a general problem (or design choice, if you will, with closures). you don't need the full generality of your example to show this.
A simpler test case looks like:

func main() -> Int {
  let x : Int = 23
  let names = ["pata", "tino", "uccio"]
  let reversedNames = names.sorted(by: { 
    (s1: String, s2: String) -> Bool in return s1 > s2 } // patatino 
  )
  return 0
}

_ = main()
(lldb) br set -p patatino
Breakpoint 1: where = pat`closure #​1 (Swift.String, Swift.String) -> Swift.Bool in pat.main() -> Swift.Int + 37 at pat.swift:5:48, address = 0x0000000100000c85
(lldb) r
Process 15423 launched: '/Users/davide/work/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64/bin/pat' (x86_64)
[...]

(lldb) frame var
(String) s1 = "tino"
(String) s2 = "pata"
(lldb) frame var x
error: no variable named 'x' found in this frame
(lldb) frame var y
error: no variable named 'y' found in this frame

I think closures are basically a new context, hence if you don't capture bindings explicitly, they're not visible in the closure (and so, the debugger can't see them).

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

If you use `x` explicitly in the closure, then it's visible to the debugger.

* thread #​1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #​0: 0x0000000100000ba2 pat`closure #​1 in main(s1="tino", s2="pata", x=23) at pat.swift:6:12
   3      let names = ["pata", "tino", "uccio"]
   4      let reversedNames = names.sorted(by: {
   5        (s1: String, s2: String) -> Bool in print(x);
-> 6        return s1 > s2 } // patatino 
   7      )
   8      return 0
   9    }
Target 0: (pat) stopped.
(lldb) frame var 
(String) s1 = "tino"
(String) s2 = "pata"

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

@adrian-prantl ^ is a design choice that, inside a closure, we don't make variables of the surrouding function visible unless explicitly used or captured? If so, this rdar can be closed, otherwise we might need to play with DI scopes to get this right.

@adrian-prantl
Copy link
Member

I'm probably misunderstanding something here: If the variable isn't explicitly captured, it physically doesn't exist in the closure.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

Nah, you're correct, that's my understanding as well. We can close this now.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

Fixed.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

Link to the commit for future archeologists:
apple/swift-lldb@4fe7fec

@swift-ci
Copy link
Author

Comment by Jovan (JIRA)

Nice! About the visibility of surrounding function/class... Very often closures are used and are referring to something outside of their local scope. Adding all of them to the capture list would greatly impact the code for the worse. I'm under the impression that implementing this visibility would bring great value to the debugging of all async code (i'm not sure how much it would bring in simple cases similar to the one @dcci provided). Could this potentially be a feature request, or is that a decision that previously had to be made and it will now stay like that?

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

The real issue here is that as also @adrian-prantl pointed out the variables don't exist inside the closure unless you reference to them (they don't get to SILGen, or IRGen). So, if you use a variable in the closure, it will be visible to the debugger.
Otherwise, it won't. This is the main difference between nested functions and closure (from a debuggability perspective). Closure are de-facto different functions, so they don't inherit the variables of the outer functions unless you capture them explicitly.

Generating all the variables would be a sledgehammer and I think it wouldn't fly.

@dcci
Copy link
Mannequin

dcci mannequin commented Oct 15, 2018

That said, if you have a case where lldb doesn't find a variable in the closure that's explicitly referenced (although defined in the outer function), you might want to consider reporting a bug.

@swift-ci
Copy link
Author

Comment by Jovan (JIRA)

Oh I see, you just need to reference them in the closure, not actually put them in the capture list. This helps a lot in knowing exactly where to put the breakpoints and why there so I can access the variables. Well that pretty much also solves the second use case since I was under the impression it randomly does or does not work. Thanks for the great info. Cheers!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 7, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working LLDB for Swift
Projects
None yet
Development

No branches or pull requests

2 participants