Skip to content

Improve error handling in SwiftUserExpression #8808

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
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 29 additions & 10 deletions lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#endif

#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/ExpressionParser.h"
Expand Down Expand Up @@ -65,31 +66,49 @@ SwiftUserExpression::SwiftUserExpression(
m_result_delegate(exe_scope.CalculateTarget(), *this, false),
m_error_delegate(exe_scope.CalculateTarget(), *this, true),
m_persistent_variable_delegate(*this) {
if (auto target = exe_scope.CalculateTarget())
m_debugger_id = target->GetDebugger().GetID();
m_runs_in_playground_or_repl =
options.GetREPLEnabled() || options.GetPlaygroundTransformEnabled();
}

SwiftUserExpression::~SwiftUserExpression() {}

void SwiftUserExpression::WillStartExecuting() {
if (auto process = m_jit_process_wp.lock()) {
if (auto process = m_jit_process_wp.lock())
if (auto *swift_runtime = SwiftLanguageRuntime::Get(process))
swift_runtime->WillStartExecutingUserExpression(
m_runs_in_playground_or_repl);
else
llvm_unreachable("Can't execute a swift expression without a runtime");
} else
llvm_unreachable("Can't execute an expression without a process");
Debugger::ReportError(
"Can't execute a swift expression without a runtime",
m_debugger_id);
else
Debugger::ReportError("Can't execute an expression without a process",
m_debugger_id);
}

void SwiftUserExpression::DidFinishExecuting() {
if (auto process = m_jit_process_wp.lock()) {
if (auto *swift_runtime = SwiftLanguageRuntime::Get(process))
swift_runtime->DidFinishExecutingUserExpression(
m_runs_in_playground_or_repl);
else
llvm_unreachable("Can't execute a swift expression without a runtime");
auto process = m_jit_process_wp.lock();
if (!process) {
Debugger::ReportError("Could not finish a expression without a process",
m_debugger_id);
return;
}
if (!process->IsValid()) {
// This will cause SwiftLanguageRuntime::Get(process) tp fail.
Debugger::ReportError("Could not finish swift expression because the "
"process is being torn down",
m_debugger_id);
return;
}
auto *swift_runtime = SwiftLanguageRuntime::Get(process);
if (!swift_runtime) {
Debugger::ReportError("Could not finish swift expression without a runtime",
m_debugger_id);
return;
}
swift_runtime->DidFinishExecutingUserExpression(m_runs_in_playground_or_repl);
}

/// Determine whether we have a Swift language symbol context. This handles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class SwiftUserExpression : public LLVMUserExpression {
PersistentVariableDelegate m_persistent_variable_delegate;
std::unique_ptr<SwiftExpressionParser> m_parser;
std::optional<SwiftLanguageRuntime::GenericSignature> m_generic_signature;
std::optional<lldb::user_id_t> m_debugger_id;
Status m_err;
bool m_runs_in_playground_or_repl;
bool m_needs_object_ptr = false;
Expand Down
2 changes: 2 additions & 0 deletions lldb/test/API/lang/swift/no_runtime/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SWIFT_SOURCES := main.swift
include Makefile.rules
21 changes: 21 additions & 0 deletions lldb/test/API/lang/swift/no_runtime/TestSwiftNoRuntime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import unittest2

class TestSwiftNoRuntime(TestBase):
NO_DEBUG_INFO_TESTCASE = True

@swiftTest
def test(self):
"""Test running a Swift expression in a C program"""
self.build()
self.expect("b test")
_, process, _, _ = lldbutil.run_to_name_breakpoint(self, "main")
options = lldb.SBExpressionOptions()
options.SetIgnoreBreakpoints(False);
value = self.frame().EvaluateExpression("test()", options)
self.assertIn("breakpoint", str(value.GetError()))
process.Kill()

2 changes: 2 additions & 0 deletions lldb/test/API/lang/swift/no_runtime/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
func test() {}