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<BreakpointOptions *> &bp_options_vec,
38  CommandReturnObject &result) {
40  result.AppendError(
41  "This script interpreter does not support breakpoint callbacks.");
42 }
43 
45  WatchpointOptions *bp_options, CommandReturnObject &result) {
47  result.AppendError(
48  "This script interpreter does not support watchpoint callbacks.");
49 }
50 
51 bool ScriptInterpreter::LoadScriptingModule(const char *filename,
52  bool init_session,
54  StructuredData::ObjectSP *module_sp,
55  FileSpec extra_search_dir) {
56  error.SetErrorString(
57  "This script interpreter does not support importing modules.");
58  return false;
59 }
60 
62  switch (language) {
64  return "None";
66  return "Python";
67  case eScriptLanguageLua:
68  return "Lua";
70  return "Unknown";
71  }
72  llvm_unreachable("Unhandled ScriptInterpreter!");
73 }
74 
75 lldb::DataExtractorSP
77  return data.m_opaque_sp;
78 }
79 
80 Status
82  if (error.m_opaque_up)
83  return *error.m_opaque_up.get();
84 
85  return Status();
86 }
87 
89 ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
90  if (language.equals_lower(LanguageToString(eScriptLanguageNone)))
91  return eScriptLanguageNone;
92  if (language.equals_lower(LanguageToString(eScriptLanguagePython)))
93  return eScriptLanguagePython;
94  if (language.equals_lower(LanguageToString(eScriptLanguageLua)))
95  return eScriptLanguageLua;
97 }
98 
100  std::vector<BreakpointOptions *> &bp_options_vec,
101  const char *callback_text) {
102  Status return_error;
103  for (BreakpointOptions *bp_options : bp_options_vec) {
104  return_error = SetBreakpointCommandCallback(bp_options, callback_text);
105  if (return_error.Success())
106  break;
107  }
108  return return_error;
109 }
110 
112  std::vector<BreakpointOptions *> &bp_options_vec, const char *function_name,
113  StructuredData::ObjectSP extra_args_sp) {
114  Status error;
115  for (BreakpointOptions *bp_options : bp_options_vec) {
116  error = SetBreakpointCommandCallbackFunction(bp_options, function_name,
117  extra_args_sp);
118  if (!error.Success())
119  return error;
120  }
121  return error;
122 }
123 
124 std::unique_ptr<ScriptInterpreterLocker>
126  return std::make_unique<ScriptInterpreterLocker>();
127 }
128 
129 static void ReadThreadBytesReceived(void *baton, const void *src,
130  size_t src_len) {
131  if (src && src_len) {
132  Stream *strm = (Stream *)baton;
133  strm->Write(src, src_len);
134  strm->Flush();
135  }
136 }
137 
138 llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
140  CommandReturnObject *result) {
141  if (enable_io)
142  return std::unique_ptr<ScriptInterpreterIORedirect>(
143  new ScriptInterpreterIORedirect(debugger, result));
144 
147  if (!nullin)
148  return nullin.takeError();
149 
152  if (!nullout)
153  return nullin.takeError();
154 
155  return std::unique_ptr<ScriptInterpreterIORedirect>(
156  new ScriptInterpreterIORedirect(std::move(*nullin), std::move(*nullout)));
157 }
158 
160  std::unique_ptr<File> input, std::unique_ptr<File> output)
161  : m_input_file_sp(std::move(input)),
162  m_output_file_sp(std::make_shared<StreamFile>(std::move(output))),
163  m_error_file_sp(m_output_file_sp),
164  m_communication("lldb.ScriptInterpreterIORedirect.comm"),
165  m_disconnect(false) {}
166 
168  Debugger &debugger, CommandReturnObject *result)
169  : m_communication("lldb.ScriptInterpreterIORedirect.comm"),
170  m_disconnect(false) {
171 
172  if (result) {
173  m_input_file_sp = debugger.GetInputFileSP();
174 
175  Pipe pipe;
176  Status pipe_result = pipe.CreateNew(false);
177 #if defined(_WIN32)
178  lldb::file_t read_file = pipe.GetReadNativeHandle();
179  pipe.ReleaseReadFileDescriptor();
180  std::unique_ptr<ConnectionGenericFile> conn_up =
181  std::make_unique<ConnectionGenericFile>(read_file, true);
182 #else
183  std::unique_ptr<ConnectionFileDescriptor> conn_up =
184  std::make_unique<ConnectionFileDescriptor>(
185  pipe.ReleaseReadFileDescriptor(), true);
186 #endif
187 
188  if (conn_up->IsConnected()) {
189  m_communication.SetConnection(std::move(conn_up));
193  m_disconnect = true;
194 
195  FILE *outfile_handle = fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
196  m_output_file_sp = std::make_shared<StreamFile>(outfile_handle, true);
198  if (outfile_handle)
199  ::setbuf(outfile_handle, nullptr);
200 
201  result->SetImmediateOutputFile(debugger.GetOutputStream().GetFileSP());
202  result->SetImmediateErrorFile(debugger.GetErrorStream().GetFileSP());
203  }
204  }
205 
209 }
210 
212  if (m_output_file_sp)
213  m_output_file_sp->Flush();
214  if (m_error_file_sp)
215  m_error_file_sp->Flush();
216 }
217 
219  if (!m_disconnect)
220  return;
221 
222  assert(m_output_file_sp);
223  assert(m_error_file_sp);
225 
226  // Close the write end of the pipe since we are done with our one line
227  // script. This should cause the read thread that output_comm is using to
228  // exit.
229  m_output_file_sp->GetFile().Close();
230  // The close above should cause this thread to exit when it gets to the end
231  // of file, so let it get all its data.
233  // Now we can close the read end of the pipe.
235 }
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:957
lldb_private::ScriptInterpreter::SetBreakpointCommandCallback
Status SetBreakpointCommandCallback(std::vector< BreakpointOptions * > &bp_options_vec, const char *callback_text)
Set the specified text as the callback for the breakpoint.
Definition: ScriptInterpreter.cpp:99
lldb_private::ScriptInterpreter::SetBreakpointCommandCallbackFunction
Status SetBreakpointCommandCallbackFunction(std::vector< BreakpointOptions * > &bp_options_vec, const char *function_name, StructuredData::ObjectSP extra_args_sp)
Definition: ScriptInterpreter.cpp:111
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:64
ConnectionGenericFileWindows.h
lldb_private::ScriptInterpreter::GetStatusFromSBError
Status GetStatusFromSBError(const lldb::SBError &error) const
Definition: ScriptInterpreter.cpp:81
ReadThreadBytesReceived
static void ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
Definition: ScriptInterpreter.cpp:129
lldb_private::ScriptInterpreter::StringToLanguage
static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string)
Definition: ScriptInterpreter.cpp:89
lldb_private::Stream::Flush
virtual void Flush()=0
Flush the stream.
lldb_private::Debugger::GetOutputStream
StreamFile & GetOutputStream()
Definition: Debugger.h:173
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:139
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:76
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:159
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:44
lldb_private::File::eOpenOptionRead
@ eOpenOptionRead
Definition: File.h:47
lldb_private::CommandReturnObject::SetImmediateOutputFile
void SetImmediateOutputFile(lldb::FileSP file_sp)
Definition: CommandReturnObject.h:65
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:134
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:66
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::eReturnStatusFailed
@ eReturnStatusFailed
Definition: lldb-enumerations.h:265
lldb_private::Debugger
Definition: Debugger.h:70
lldb_private::ScriptInterpreterIORedirect::m_communication
Communication m_communication
Definition: ScriptInterpreter.h:65
lldb::eScriptLanguageUnknown
@ eScriptLanguageUnknown
Definition: lldb-enumerations.h:220
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
StringList.h
lldb_private::ScriptInterpreter::LoadScriptingModule
virtual bool LoadScriptingModule(const char *filename, bool init_session, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={})
Definition: ScriptInterpreter.cpp:51
lldb_private::ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect
~ScriptInterpreterIORedirect()
Definition: ScriptInterpreter.cpp:218
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::Status
Definition: Status.h:44
lldb::SBData::m_opaque_sp
lldb::DataExtractorSP m_opaque_sp
Definition: SBData.h:156
lldb_private::ScriptInterpreter::CollectDataForBreakpointCommandCallback
virtual void CollectDataForBreakpointCommandCallback(std::vector< BreakpointOptions * > &options, CommandReturnObject &result)
Definition: ScriptInterpreter.cpp:36
lldb_private::CommandReturnObject
Definition: CommandReturnObject.h:25
lldb::SBData
Definition: SBData.h:20
lldb_private::ScriptInterpreter::LanguageToString
static std::string LanguageToString(lldb::ScriptLanguage language)
Definition: ScriptInterpreter.cpp:61
PseudoTerminal.h
lldb_private::CommandReturnObject::SetImmediateErrorFile
void SetImmediateErrorFile(lldb::FileSP file_sp)
Definition: CommandReturnObject.h:70
lldb_private::ScriptInterpreterIORedirect::Flush
void Flush()
Flush our output and error file handles.
Definition: ScriptInterpreter.cpp:211
lldb_private::ScriptInterpreter::AcquireInterpreterLock
virtual std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock()
Definition: ScriptInterpreter.cpp:125
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:62
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::File::eOpenOptionWrite
@ eOpenOptionWrite
Definition: File.h:48
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::StreamFile
Definition: StreamFile.h:22
Stream.h
lldb_private::CommandReturnObject::AppendError
void void AppendError(llvm::StringRef in_string)
Definition: CommandReturnObject.cpp:102
lldb_private::ScriptInterpreterIORedirect::m_output_file_sp
lldb::StreamFileSP m_output_file_sp
Definition: ScriptInterpreter.h:63
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