LLDB mainline
ScriptedThreadPlanPythonInterface.cpp
Go to the documentation of this file.
1//===-- ScriptedThreadPlanPythonInterface.cpp -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "../lldb-python.h"
10
14#include "lldb/Utility/Log.h"
17
18#include "../SWIGPythonBridge.h"
21
22using namespace lldb;
23using namespace lldb_private;
24using namespace lldb_private::python;
25
29
30llvm::Expected<StructuredData::GenericSP>
32 const ScriptedMetadata &scripted_metadata,
33 lldb::ThreadPlanSP thread_plan_sp) {
34 StructuredDataImpl args_sp(scripted_metadata.GetArgsSP());
35 return ScriptedPythonInterface::CreatePluginObject(scripted_metadata, nullptr,
36 thread_plan_sp, args_sp);
37}
38
39llvm::Expected<bool>
41 llvm::Expected<std::optional<StructuredData::ObjectSP>> obj_or_err =
42 DispatchToOptional("explains_stop", event);
43 if (!obj_or_err)
44 return obj_or_err.takeError();
45
46 // Absent or None: the plan doesn't claim to explain the stop.
47 StructuredData::ObjectSP obj = obj_or_err->value_or(nullptr);
48 if (!obj || !obj->IsValid())
49 return false;
50
51 return obj->GetBooleanValue();
52}
53
54llvm::Expected<bool>
56 llvm::Expected<std::optional<StructuredData::ObjectSP>> obj_or_err =
57 DispatchToOptional("should_stop", event);
58 if (!obj_or_err)
59 return obj_or_err.takeError();
60
61 // Absent or None: the plan doesn't ask to stop.
62 StructuredData::ObjectSP obj = obj_or_err->value_or(nullptr);
63 if (!obj || !obj->IsValid())
64 return false;
65
66 return obj->GetBooleanValue();
67}
68
70 llvm::Expected<std::optional<StructuredData::ObjectSP>> obj_or_err =
71 DispatchToOptional("is_stale");
72 if (!obj_or_err)
73 return obj_or_err.takeError();
74
75 // Absent or None: assume the plan is still fresh.
76 StructuredData::ObjectSP obj = obj_or_err->value_or(nullptr);
77 if (!obj || !obj->IsValid())
78 return false;
79
80 return obj->GetBooleanValue();
81}
82
83llvm::Expected<lldb::StateType>
85 llvm::Expected<std::optional<StructuredData::ObjectSP>> obj_or_err =
86 DispatchToOptional("should_step");
87 if (!obj_or_err)
88 return obj_or_err.takeError();
89
90 StructuredData::ObjectSP obj = obj_or_err->value_or(nullptr);
91 if (!obj || !obj->IsValid())
93
94 // A thread plan's run state can formally be eStateSuspended, but that state
95 // is decided by the thread plan negotiation, not by the plan itself. So a
96 // scripted plan's contract is only running or stepping: a bool.
97 if (StructuredData::Boolean *should_step = obj->GetAsBoolean())
98 return should_step->GetValue() ? lldb::eStateStepping : lldb::eStateRunning;
99
100 if (Log *log = GetLog(LLDBLog::Script)) {
101 StreamString reply;
102 obj->Dump(reply, /*pretty_print=*/false);
103 LLDB_LOG(log, "should_step returned {0}, not a bool; stepping.",
104 reply.GetData());
105 }
107}
108
109llvm::Error
111 return DispatchToOptional("stop_description", stream).takeError();
112}
113
115 const std::vector<llvm::StringRef> ci_usages = {
116 "thread step-scripted -C <script-name> [-k key -v value ...]"};
117 const std::vector<llvm::StringRef> api_usages = {
118 "SBThread.StepUsingScriptedThreadPlan"};
121 llvm::StringRef("Alter thread stepping logic and stop reason"),
123 eScriptLanguagePython, {ci_usages, api_usages});
124}
125
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
static bool CreateInstance(lldb::ScriptLanguage language, ScriptedInterfaceUsages usages)
StructuredData::DictionarySP GetArgsSP() const
ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter)
llvm::Expected< std::optional< T > > DispatchToOptional(llvm::StringRef method_name, Args &&...args)
Call an optional method_name, reporting "the script doesn't implementit" as std::nullopt rather than ...
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, StructuredData::Generic *script_obj, Args... args)
llvm::Error GetStopDescription(lldb::StreamSP &stream) override
llvm::Expected< bool > ShouldStop(Event *event) override
llvm::Expected< StructuredData::GenericSP > CreatePluginObject(const ScriptedMetadata &scripted_metadata, lldb::ThreadPlanSP thread_plan_sp) override
ScriptedThreadPlanPythonInterface(ScriptInterpreterPythonImpl &interpreter)
llvm::Expected< bool > ExplainsStop(Event *event) override
llvm::Expected< lldb::StateType > GetRunState() override
const char * GetData() const
std::shared_ptr< Object > ObjectSP
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
@ eScriptLanguagePython
@ eScriptedExtensionScriptedThreadPlan
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
std::shared_ptr< lldb_private::Stream > StreamSP