Skip to content

Commit 140f2c6

Browse files
committed
[lldb] Introduce Swift "task info" command
1 parent 0ab2ffb commit 140f2c6

File tree

4 files changed

+102
-1
lines changed

4 files changed

+102
-1
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "SwiftLanguageRuntime.h"
1414
#include "Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h"
15+
#include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
1516
#include "ReflectionContextInterface.h"
1617
#include "SwiftMetadataCache.h"
1718

@@ -34,6 +35,7 @@
3435
#include "lldb/Interpreter/CommandObject.h"
3536
#include "lldb/Interpreter/CommandObjectMultiword.h"
3637
#include "lldb/Interpreter/CommandReturnObject.h"
38+
#include "lldb/Symbol/CompilerType.h"
3739
#include "lldb/Symbol/FuncUnwinders.h"
3840
#include "lldb/Symbol/Function.h"
3941
#include "lldb/Symbol/VariableList.h"
@@ -63,6 +65,8 @@
6365
#include "llvm/ADT/StringRef.h"
6466
#include "llvm/BinaryFormat/Dwarf.h"
6567
#include "llvm/Support/raw_ostream.h"
68+
#include "llvm/Support/Error.h"
69+
#include "llvm/Support/FormatAdapters.h"
6670
#include "llvm/Support/Memory.h"
6771

6872
// FIXME: we should not need this
@@ -2183,6 +2187,61 @@ class CommandObjectLanguageSwiftTaskSelect final : public CommandObjectParsed {
21832187
}
21842188
};
21852189

2190+
class CommandObjectLanguageSwiftTaskInfo final : public CommandObjectParsed {
2191+
public:
2192+
CommandObjectLanguageSwiftTaskInfo(CommandInterpreter &interpreter)
2193+
: CommandObjectParsed(interpreter, "info",
2194+
"Print the Task being run on the current thread.") {
2195+
}
2196+
2197+
private:
2198+
void DoExecute(Args &command, CommandReturnObject &result) override {
2199+
if (!m_exe_ctx.GetThreadPtr()) {
2200+
result.AppendError("must be run from a running process and valid thread");
2201+
return;
2202+
}
2203+
2204+
auto task_addr_or_err =
2205+
GetTaskAddrFromThreadLocalStorage(m_exe_ctx.GetThreadRef());
2206+
if (auto error = task_addr_or_err.takeError()) {
2207+
result.AppendError(toString(std::move(error)));
2208+
return;
2209+
}
2210+
2211+
auto ts_or_err = m_exe_ctx.GetTargetRef().GetScratchTypeSystemForLanguage(
2212+
eLanguageTypeSwift);
2213+
if (auto error = ts_or_err.takeError()) {
2214+
result.AppendErrorWithFormatv("could not get Swift type system: {0}",
2215+
llvm::fmt_consume(std::move(error)));
2216+
return;
2217+
}
2218+
2219+
auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(ts_or_err->get());
2220+
if (!ts) {
2221+
result.AppendError("could not get Swift type system");
2222+
return;
2223+
}
2224+
2225+
addr_t task_addr = task_addr_or_err.get();
2226+
// TypeMangling for "Swift.UnsafeCurrentTask"
2227+
CompilerType task_type =
2228+
ts->GetTypeFromMangledTypename(ConstString("$sSctD"));
2229+
auto task_sp = ValueObject::CreateValueObjectFromAddress(
2230+
"current_task", task_addr, m_exe_ctx, task_type, false);
2231+
if (auto synthetic_sp = task_sp->GetSyntheticValue())
2232+
task_sp = synthetic_sp;
2233+
2234+
auto error = task_sp->Dump(result.GetOutputStream());
2235+
if (error) {
2236+
result.AppendErrorWithFormatv("failed to print current task: {0}",
2237+
toString(std::move(error)));
2238+
return;
2239+
}
2240+
2241+
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
2242+
}
2243+
};
2244+
21862245
class CommandObjectLanguageSwiftTask final : public CommandObjectMultiword {
21872246
public:
21882247
CommandObjectLanguageSwiftTask(CommandInterpreter &interpreter)
@@ -2195,6 +2254,9 @@ class CommandObjectLanguageSwiftTask final : public CommandObjectMultiword {
21952254
LoadSubCommand(
21962255
"select",
21972256
CommandObjectSP(new CommandObjectLanguageSwiftTaskSelect(interpreter)));
2257+
LoadSubCommand(
2258+
"info",
2259+
CommandObjectSP(new CommandObjectLanguageSwiftTaskInfo(interpreter)));
21982260
}
21992261
};
22002262

@@ -2643,7 +2705,7 @@ std::optional<lldb::addr_t> SwiftLanguageRuntime::TrySkipVirtualParentProlog(
26432705
}
26442706

26452707
llvm::Expected<lldb::addr_t> GetTaskAddrFromThreadLocalStorage(Thread &thread) {
2646-
#if SWIFT_THREADING_USE_DIRECT_TSD
2708+
#if !SWIFT_THREADING_USE_RESERVED_TLS_KEYS
26472709
return llvm::createStringError(
26482710
"getting the current task from a thread is not supported");
26492711
#else
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -parse-as-library
3+
include Makefile.rules
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import TestBase
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
import re
7+
8+
9+
def _tail(output):
10+
"""Delete the first line of output text."""
11+
result, _ = re.subn(r"^.*\n", "", output, count=1)
12+
return result
13+
14+
15+
class TestCase(TestBase):
16+
17+
@skipUnlessDarwin
18+
def test(self):
19+
self.build()
20+
lldbutil.run_to_source_breakpoint(
21+
self, "break here", lldb.SBFileSpec("main.swift")
22+
)
23+
self.runCmd("frame variable task")
24+
frame_variable_output = self.res.GetOutput()
25+
self.runCmd("language swift task info")
26+
task_info_output = self.res.GetOutput()
27+
self.assertEqual(_tail(task_info_output), _tail(frame_variable_output))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@main struct Main {
2+
static func main() async {
3+
withUnsafeCurrentTask { task in
4+
if let task {
5+
print("break here")
6+
}
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)