[GsoC] Swift debugging support on Linux

Greetings,

I am a Computer Science student at National and Kapodistrian University of Athens, and I would like to be a part of this year's GsoC program.

During my academic career, I have only used Linux as my OS and on most of the projects I have completed I have used C Programming Language.

On my programs I used diffrent kinds of debuggers like gdb, valgrind.

Thus, the project idea " Swift debugging support on Linux" highly intrigued me and I would like to be a part of it.

I believe that I have the necessary background to live up to your expectations and I would like to leran more details about this project and ways I can contribute to its development.

Thanks in advance, Kostas.

5 Likes

Thank you for expressing interest.
I would recommend you trying to get your feet wet building swift-lldb and running the testuite. Don't hesitate to ping me back when you're done and I'll try to find a starter bug for you.

Hello,
I'm Gowtham and I am a Computer science student at The University of Texas. I would love to contribute to this open source project. I am proficient in Java and C++.
Currently I know a decent amount in shell scripting in Linux OS, working with GNU g++ compiler. I have extensively used the debugging tools in IDEs and in the bash terminal (gnu project debugger)
Even though lot of the projects seem highly technical to me, I believe I am qualified/or have minimum experience to work on this project and complete the deliverable.

Thank you!

Hello,

I have built Swift running Ninja and ran the Swift Test Suite as mentioned in swift/Testing.md

Στις Παρ, 28 Φεβ 2020 στις 11:36 μ.μ., ο/η Davide C. C. Italiano via Swift Forums swift@discoursemail.com έγραψε:

Hello once again,

I send this response to remind you of my initial email because it might have been lost among others.

Thanks for your time, I understand you receive hundreds of emails.

Let me find something you can start looking at.

I think you can start looking at either:

or [SR-12220] Swift.Substring doesn't have a built-in formatter · Issue #4430 · apple/llvm-project · GitHub

I recommend playing a little with them, they should be enough to get your feet wet. The former is about an error that doesn't get reported properly. Digging into SwiftASTContext.cpp should give you an idea of how modules are loaded in lldb -- and you can probably find the right place to plumb this correctly.

The latter is about a missing formatter. lldb takes raw input and performs post-processing to produce a human readable representation of the values it evaluates. You can look at all the formatters for swift, they live in https://github.com/apple/llvm-project/blob/swift/master/lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

If you have any questions don't hesitate to reply here. One between me and @Adrian_Prantl should be able to help you.

Hi @dcci and @Adrian_Prantl.

I'm a student from Brazil starting my master's on compilers, and I'd like to participate in GSOC improving the debugging support of swift on linuxe. Before I started my master's I was an iOS developer, and I really enjoy the Swift programming language as a user. Working on the language itself sounds like it could be really cool.

On the first issue Davide linked, I did some digging around, and it seems like if the module doesn't exist, it's built on the fly by function ClangImporter::Implementation::loadModuleDWARF in DwarfImporter. Is that supposed to happen and be handled later, or is this an error? The reason why I think it's an error is because later, SwiftASTContext checks if the module was found, and if not sets an appropriate error message (SwiftASTContext::GetModule).

I'd really like to participate in GSOC, but I'm a little overwhelmed with where and what to start looking so I can write a coherent proposal that is doable in 3 months. Do you have any suggestions of what I can look, or any other suggestions at all?

Thank you very much!

On the first issue Davide linked, I did some digging around, and it seems like if the module doesn't exist, it's built on the fly by function ClangImporter::Implementation::loadModuleDWARF in DwarfImporter. Is that supposed to happen and be handled later, or is this an error? The reason why I think it's an error is because later, SwiftASTContext checks if the module was found, and if not sets an appropriate error message (SwiftASTContext::GetModule).

The flow is currently like this:

  1. Try to import the Clang dependency using ClangImporter, which triggers a clang compiler invocation to compile and import the module or bridging header.

  2. If this fails we try to import the Clang types from DWARF. DWARFImporter will always claim to be able to load any module, which is why loadModuleDWARF is effectively a noop. Only once we receive a request for a type inside the Clang module LLDB will receive a request to DWARFImporterDelegate (in SwiftASTContext.cpp) and will then try to load it from DWARF and hand it back to the ClangImporter.

Which bug is it that you were investigating when you found this? It may just be something with your setup that prevented ClangImporter from finding the correct header files.

Which branch were you working on? (master is what I'd recommend for this).

-- adrian

Ah. Was this https://bugs.swift.org/browse/SR-11990? Then that's precisely what's happening and you correctly identified the bug :-)
Perhaps the right solution is to always disable DWARFImporter in the REPL. Try looking at where it is initialized in SwiftASTContext.cpp.

-- adrian

Hey Adrian, yes that's the bug exactly! I'll take a look and see where it's initialized, thanks for the reply :slight_smile:

Hi @Adrian_Prantl, so I found the place where I need to disable the DWARFImporter, in the GetASTContext function, there's a check for props.GetUseSwiftDWARFImporter(), and if that returns true we initialize the SwiftDwarfImporterDelegate

By forcing this to false I get the desired behavior, but I have a question on how to pass on the information we need to tell if the program is in a repl at this point of the program. Should GetUseSwiftDWARFImporter be the function responsible for checking we are in REPL mode? It seems like the right place to me, but all the ModuleListProperties methods only look up information on what seems to be a constant file (CoreProperties.inc), so I don't know if this is the right place or not (or even how to access it from there).

Method SetupASTContext on SwiftExpressionParser initializes the SwiftASTContext and knows if we are in the repl, so we could initialize some variable there as well?

Or is there some other easy way to check if we're in the REPL that I'm just not seeing?

EDIT: we could add a variable in LangOptions for example.

I looked around a bit and it seems that only the Target knows that the REPL is enabled (git grep REPLEnabled). That is too late. So perhaps we need to turn this around and instead set the ModuleList property to disable DWARFImporter when we are initializing the REPL.

-- adrian

SwiftExpressionParser::SetupASTContext receives a bool representing if it's a REPL or not, would creating a new variable in LangOptions called Repl (analogous to the existing Playground one) not work? (Or would that be bad architecture?)

Where might I start looking so I can do that?

Ok, so I got it working. I created a method SetUseSwiftDWARFImporter in ModuleList.

I call this function inside SwiftREPL::Initialize. Do you think this is an acceptable solution?

EDIT:
conditionally setting the DwarfImporter in Target::SetREPL also works:

void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {
  lldbassert(!m_repl_map.count(language));

  m_repl_map[language] = repl_sp;
  if (language == eLanguageTypeSwift) {
      ModuleList::GetGlobalModuleListProperties().SetUseSwiftDWARFImporter(repl_sp == NULL);
  }
}

Is this a better place to do this?

Hi @dcci and @Adrian_Prantl,

You guys are probably busy, but could you guide me with this issue whenever you have the time?

Even if not for GSOC, I think it would be cool to submit a PR for the Swift project :slight_smile:

I'm terribly sorry about my slow response time, the current situation has multiplied my distractions. I think you are doing a great job analyzing the issue!

Ok, so I got it working. I created a method SetUseSwiftDWARFImporter in ModuleList.

I call this function inside SwiftREPL::Initialize. Do you think this is an acceptable solution?

I think that is exactly what we should be doing. The only thing left to do is figure out a way to test this and then we can land a pull request. For the REPL shell tests are most appropriate, such as the ones in test/Shell/REPL.

-- adrian

Hi Adrian!

I'm terribly sorry about my slow response time, the current situation has multiplied my distractions

Of course! The way the world is chaotic right now that is totally understandable, don't worry about it.

I think that is exactly what we should be doing. The only thing left to do is figure out a way to test this and then we can land a pull request. For the REPL shell tests are most appropriate, such as the ones in test/Shell/REPL.

Nice!! I'm happy to hear I'm on the right path :grin: I'll take a look how the current tests are implemented and report back when I have something I think is acceptable :slight_smile:

HI Adrian,

I wrote a test for the issue.

It's pretty simple, but looking at the other tests in the folder that seems like the correct way to do it.

The whole test is:

// Test that importing non-existing module fails.

// RUN: %lldb --repl < %s 2>&1 | FileCheck %s

import ModuleThatDoesNotExist
// CHECK: error: no such module 'ModuleThatDoesNotExist'

Is that alright? If yes, what are the next steps?

That looks promising. Can you create a pull request against swift/master and an identical one against swift/master-next on Github?

thanks,
adrian