LLDB  mainline
ScriptInterpreter.cpp
Go to the documentation of this file.
1 //===-- ScriptInterpreter.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 
10 #include "lldb/Core/Debugger.h"
12 #include "lldb/Host/Pipe.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/Utility/Stream.h"
18 #if defined(_WIN32)
20 #endif
21 #include <cstdio>
22 #include <cstdlib>
23 #include <memory>
24 #include <string>
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 ScriptInterpreter::ScriptInterpreter(
30  Debugger &debugger, lldb::ScriptLanguage script_lang,
31  lldb::ScriptedProcessInterfaceUP scripted_process_interface_up)
32  : m_debugger(debugger), m_script_lang(script_lang),
33  m_scripted_process_interface_up(
34  std::move(scripted_process_interface_up)) {}
35 
37  std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
38  CommandReturnObject &result) {
39  result.AppendError(
40  "This script interpreter does not support breakpoint callbacks.");
41 }
42 
44  WatchpointOptions *bp_options, CommandReturnObject &result) {
45  result.AppendError(
46  "This script interpreter does not support watchpoint callbacks.");
47 }
48 
49 bool ScriptInterpreter::LoadScriptingModule(const char *filename,
50  const LoadScriptOptions &options,
52  StructuredData::ObjectSP *module_sp,
53  FileSpec extra_search_dir) {
54  error.SetErrorString(
55  "This script interpreter does not support importing modules.");
56  return false;
57 }
58 
60  switch (language) {
62  return "None";
64  return "Python";
65  case eScriptLanguageLua:
66  return "Lua";
68  return "Unknown";
69  }
70  llvm_unreachable("Unhandled ScriptInterpreter!");
71 }
72 
73 lldb::DataExtractorSP
75  return data.m_opaque_sp;
76 }
77 
78 Status
80  if (error.m_opaque_up)
81  return *error.m_opaque_up.get();
82 
83  return Status();
84 }
85 
86 llvm::Optional<MemoryRegionInfo>
88  const lldb::SBMemoryRegionInfo &mem_region) const {
89  if (!mem_region.m_opaque_up)
90  return llvm::None;
91  return *mem_region.m_opaque_up.get();
92 }
93 
95 ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
96  if (language.equals_insensitive(LanguageToString(eScriptLanguageNone)))
97  return eScriptLanguageNone;
98  if (language.equals_insensitive(LanguageToString(eScriptLanguagePython)))
99  return eScriptLanguagePython;
100  if (language.equals_insensitive(LanguageToString(eScriptLanguageLua)))
101  return eScriptLanguageLua;
102  return eScriptLanguageUnknown;
103 }
104 
106  std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
107  const char *callback_text) {
108  Status return_error;
109  for (BreakpointOptions &bp_options : bp_options_vec) {
110  return_error = SetBreakpointCommandCallback(bp_options, callback_text);
111  if (return_error.Success())
112  break;
113  }
114  return return_error;
115 }
116 
118  std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
119  const char *function_name, StructuredData::ObjectSP extra_args_sp) {
120  Status error;
121  for (BreakpointOptions &bp_options : bp_options_vec) {
122  error = SetBreakpointCommandCallbackFunction(bp_options, function_name,
123  extra_args_sp);
124  if (!error.Success())
125  return error;
126  }
127  return error;
128 }
129 
130 std::unique_ptr<ScriptInterpreterLocker>
132  return std::make_unique<ScriptInterpreterLocker>();
133 }
134 
135 static void ReadThreadBytesReceived(void *baton, const void *src,
136  size_t src_len) {
137  if (src && src_len) {
138  Stream *strm = (Stream *)baton;
139  strm->Write(src, src_len);
140  strm->Flush();
141  }
142 }
143 
144 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
146  CommandReturnObject *result) {
147  if (enable_io)
148  return std::unique_ptr<ScriptInterpreterIORedirect>(
149  new ScriptInterpreterIORedirect(debugger, result));
150 
153  if (!nullin)
154  return nullin.takeError();
155 
158  if (!nullout)
159  return nullin.takeError();
160 
161  return std::unique_ptr<ScriptInterpreterIORedirect>(
162  new ScriptInterpreterIORedirect(std::move(*nullin), std::move(*nullout)));
163 }
164 
166  std::unique_ptr<File> input, std::unique_ptr<File> output)
167  : m_input_file_sp(std::move(input)),
168  m_output_file_sp(std::make_shared<StreamFile>(std::move(output))),
169  m_error_file_sp(m_output_file_sp),
170  m_communication("lldb.ScriptInterpreterIORedirect.comm"),
171  m_disconnect(false) {}
172 
174  Debugger &debugger, CommandReturnObject *result)
175  : m_communication("lldb.ScriptInterpreterIORedirect.comm"),
176  m_disconnect(false) {
177 
178  if (result) {
179  m_input_file_sp = debugger.GetInputFileSP();
180 
181  Pipe pipe;
182  Status pipe_result = pipe.CreateNew(false);
183 #if defined(_WIN32)
184  lldb::file_t read_file = pipe.GetReadNativeHandle();
185  pipe.ReleaseReadFileDescriptor();
186  std::unique_ptr<ConnectionGenericFile> conn_up =
187  std::make_unique<ConnectionGenericFile>(read_file, true);
188 #else
189  std::unique_ptr<ConnectionFileDescriptor> conn_up =
190  std::make_unique<ConnectionFileDescriptor>(
191  pipe.ReleaseReadFileDescriptor(), true);
192 #endif
193 
194  if (conn_up->IsConnected()) {
195  m_communication.SetConnection(std::move(conn_up));
199  m_disconnect = true;
200 
201  FILE *outfile_handle = fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
202  m_output_file_sp = std::make_shared<StreamFile>(outfile_handle, true);
204  if (outfile_handle)
205  ::setbuf(outfile_handle, nullptr);
206 
207  result->SetImmediateOutputFile(debugger.GetOutputStream().GetFileSP());
208  result->SetImmediateErrorFile(debugger.GetErrorStream().GetFileSP());
209  }
210  }
211 
215 }
216 
218  if (m_output_file_sp)
219  m_output_file_sp->Flush();
220  if (m_error_file_sp)
221  m_error_file_sp->Flush();
222 }
223 
225  if (!m_disconnect)
226  return;
227 
228  assert(m_output_file_sp);
229  assert(m_error_file_sp);
231 
232  // Close the write end of the pipe since we are done with our one line
233  // script. This should cause the read thread that output_comm is using to
234  // exit.
235  m_output_file_sp->GetFile().Close();
236  // The close above should cause this thread to exit when it gets to the end
237  // of file, so let it get all its data.
239  // Now we can close the read end of the pipe.
241 }
lldb_private::ScriptInterpreter::SetBreakpointCommandCallback
Status SetBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions >> &bp_options_vec, const char *callback_text)
Set the specified text as the callback for the breakpoint.
Definition: ScriptInterpreter.cpp:105
lldb_private::FileSystem::Open
int Open(const char *path, int flags, int mode)
Wraps ::open in a platform-independent way.
Definition: FileSystemPosix.cpp:79
lldb::ScriptLanguage
ScriptLanguage
Script interpreter types.
Definition: lldb-enumerations.h:216
lldb_private::Pipe
PipePosix Pipe
Definition: Pipe.h:20
lldb_private::Debugger::AdoptTopIOHandlerFilesIfInvalid
void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::StreamFileSP &out, lldb::StreamFileSP &err)
Definition: Debugger.cpp:966
lldb::SBError
Definition: SBError.h:20
lldb_private::StreamFile::GetFileSP
std::shared_ptr< File > GetFileSP()
Definition: StreamFile.h:41
lldb_private::ScriptInterpreterIORedirect::m_error_file_sp
lldb::StreamFileSP m_error_file_sp
Definition: ScriptInterpreter.h:121
ConnectionGenericFileWindows.h
lldb_private::ScriptInterpreter::LoadScriptingModule
virtual bool LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={})
Definition: ScriptInterpreter.cpp:49
lldb_private::ScriptInterpreter::GetStatusFromSBError
Status GetStatusFromSBError(const lldb::SBError &error) const
Definition: ScriptInterpreter.cpp:79
ReadThreadBytesReceived
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
Definition: ScriptInterpreter.cpp:135
lldb_private::ScriptInterpreter::StringToLanguage
static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string)
Definition: ScriptInterpreter.cpp:95
lldb_private::Stream::Flush
virtual void Flush()=0
Flush the stream.
lldb_private::Debugger::GetOutputStream
StreamFile & GetOutputStream()
Definition: Debugger.h:173
lldb_private::ScriptInterpreter::SetBreakpointCommandCallbackFunction
Status SetBreakpointCommandCallbackFunction(std::vector< std::reference_wrapper< BreakpointOptions >> &bp_options_vec, const char *function_name, StructuredData::ObjectSP extra_args_sp)
Definition: ScriptInterpreter.cpp:117
lldb_private::Stream
Definition: Stream.h:28
lldb::file_t
int file_t
Definition: lldb-types.h:59
lldb_private::ScriptInterpreterIORedirect::Create
static llvm::Expected< std::unique_ptr< ScriptInterpreterIORedirect > > Create(bool enable_io, Debugger &debugger, CommandReturnObject *result)
Create an IO redirect.
Definition: ScriptInterpreter.cpp:145
CommandReturnObject.h
lldb_private::FileSystem::DEV_NULL
static const char * DEV_NULL
Definition: FileSystem.h:31
Debugger.h
lldb_private::ScriptInterpreter::GetDataExtractorFromSBData
lldb::DataExtractorSP GetDataExtractorFromSBData(const lldb::SBData &data) const
Definition: ScriptInterpreter.cpp:74
lldb::eScriptLanguageNone
@ eScriptLanguageNone
Definition: lldb-enumerations.h:217
lldb_private::Communication::SetConnection
void SetConnection(std::unique_ptr< Connection > connection)
Sets the connection that it to be used by this class.
Definition: Communication.cpp:413
lldb_private::ScriptInterpreterIORedirect::ScriptInterpreterIORedirect
ScriptInterpreterIORedirect(std::unique_ptr< File > input, std::unique_ptr< File > output)
Definition: ScriptInterpreter.cpp:165
lldb_private::FileSpec
Definition: FileSpec.h:56
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:288
lldb_private::ScriptInterpreter::CollectDataForWatchpointCommandCallback
virtual void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result)
Definition: ScriptInterpreter.cpp:43
lldb_private::CommandReturnObject::SetImmediateOutputFile
void SetImmediateOutputFile(lldb::FileSP file_sp)
Definition: CommandReturnObject.h:65
lldb_private::ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo
llvm::Optional< MemoryRegionInfo > GetOpaqueTypeFromSBMemoryRegionInfo(const lldb::SBMemoryRegionInfo &mem_region) const
Definition: ScriptInterpreter.cpp:87
lldb_private::StructuredData::ObjectSP
std::shared_ptr< Object > ObjectSP
Definition: StructuredData.h:59
lldb_private::CommandReturnObject::GetOutputStream
Stream & GetOutputStream()
Definition: CommandReturnObject.h:45
lldb_private::WatchpointOptions
Definition: WatchpointOptions.h:25
lldb_private::BreakpointOptions
Definition: BreakpointOptions.h:27
lldb::eScriptLanguagePython
@ eScriptLanguagePython
Definition: lldb-enumerations.h:218
lldb_private::Communication::StartReadThread
virtual bool StartReadThread(Status *error_ptr=nullptr)
Starts a read thread whose sole purpose it to read bytes from the current connection.
Definition: Communication.cpp:192
lldb_private::ScriptInterpreterIORedirect::m_disconnect
bool m_disconnect
Definition: ScriptInterpreter.h:123
Pipe.h
lldb_private::Debugger::GetInputFileSP
lldb::FileSP GetInputFileSP()
Definition: Debugger.h:161
lldb_private::Communication::SetReadThreadBytesReceivedCallback
void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback, void *callback_baton)
Definition: Communication.cpp:386
ConnectionFileDescriptor.h
lldb_private::File::eOpenOptionReadOnly
@ eOpenOptionReadOnly
Definition: File.h:49
lldb_private::Debugger
Definition: Debugger.h:70
lldb_private::ScriptInterpreterIORedirect::m_communication
Communication m_communication
Definition: ScriptInterpreter.h:122
lldb::eScriptLanguageUnknown
@ eScriptLanguageUnknown
Definition: lldb-enumerations.h:220
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
StringList.h
lldb_private::ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect
~ScriptInterpreterIORedirect()
Definition: ScriptInterpreter.cpp:224
lldb_private::Communication::Disconnect
lldb::ConnectionStatus Disconnect(Status *error_ptr=nullptr)
Disconnect the communications connection if one is currently connected.
Definition: Communication.cpp:92
lldb_private::File::eOpenOptionWriteOnly
@ eOpenOptionWriteOnly
Definition: File.h:50
lldb_private::Status
Definition: Status.h:44
lldb::SBData::m_opaque_sp
lldb::DataExtractorSP m_opaque_sp
Definition: SBData.h:156
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:25
lldb::SBMemoryRegionInfo::m_opaque_up
lldb::MemoryRegionInfoUP m_opaque_up
Definition: SBMemoryRegionInfo.h:133
lldb::SBData
Definition: SBData.h:20
lldb::SBMemoryRegionInfo
Definition: SBMemoryRegionInfo.h:17
lldb_private::ScriptInterpreter::LanguageToString
static std::string LanguageToString(lldb::ScriptLanguage language)
Definition: ScriptInterpreter.cpp:59
PseudoTerminal.h
lldb_private::CommandReturnObject::SetImmediateErrorFile
void SetImmediateErrorFile(lldb::FileSP file_sp)
Definition: CommandReturnObject.h:72
lldb_private::ScriptInterpreterIORedirect::Flush
void Flush()
Flush our output and error file handles.
Definition: ScriptInterpreter.cpp:217
lldb_private::ScriptInterpreter::AcquireInterpreterLock
virtual std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock()
Definition: ScriptInterpreter.cpp:131
lldb_private::FileSystem::Instance
static FileSystem & Instance()
Definition: common/FileSystem.cpp:45
lldb_private::ScriptInterpreterIORedirect::m_input_file_sp
lldb::FileSP m_input_file_sp
Definition: ScriptInterpreter.h:119
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::Stream::Write
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition: Stream.h:101
lldb::eScriptLanguageLua
@ eScriptLanguageLua
Definition: lldb-enumerations.h:219
lldb_private::LoadScriptOptions
Definition: ScriptInterpreter.h:75
lldb_private::StreamFile
Definition: StreamFile.h:22
Stream.h
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:100
lldb_private::ScriptInterpreterIORedirect::m_output_file_sp
lldb::StreamFileSP m_output_file_sp
Definition: ScriptInterpreter.h:120
ScriptInterpreter.h
lldb_private::Debugger::GetErrorStream
StreamFile & GetErrorStream()
Definition: Debugger.h:175
lldb
Definition: SBAddress.h:15
lldb_private::Communication::JoinReadThread
virtual bool JoinReadThread(Status *error_ptr=nullptr)
Definition: Communication.cpp:244
lldb_private::ScriptInterpreter::CollectDataForBreakpointCommandCallback
virtual void CollectDataForBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions >> &options, CommandReturnObject &result)
Definition: ScriptInterpreter.cpp:36