LLDB  mainline
IOHandler.h
Go to the documentation of this file.
1 //===-- IOHandler.h ---------------------------------------------*- C++ -*-===//
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 #ifndef liblldb_IOHandler_h_
10 #define liblldb_IOHandler_h_
11 
14 #include "lldb/Utility/Flags.h"
15 #include "lldb/Utility/Predicate.h"
17 #include "lldb/Utility/Stream.h"
19 #include "lldb/lldb-defines.h"
20 #include "lldb/lldb-forward.h"
21 #include "llvm/ADT/StringRef.h"
22 
23 #include <memory>
24 #include <mutex>
25 #include <string>
26 #include <vector>
27 
28 #include <stdint.h>
29 #include <stdio.h>
30 
31 namespace lldb_private {
32 class Debugger;
33 }
34 
35 namespace curses {
37 typedef std::unique_ptr<Application> ApplicationAP;
38 } // namespace curses
39 
40 namespace lldb_private {
41 
42 class IOHandler {
43 public:
44  enum class Type {
46  CommandList,
47  Confirm,
48  Curses,
49  Expression,
50  REPL,
51  ProcessIO,
52  PythonInterpreter,
53  PythonCode,
54  Other
55  };
56 
57  IOHandler(Debugger &debugger, IOHandler::Type type);
58 
59  IOHandler(Debugger &debugger, IOHandler::Type type,
60  const lldb::StreamFileSP &input_sp,
61  const lldb::StreamFileSP &output_sp,
62  const lldb::StreamFileSP &error_sp, uint32_t flags,
63  repro::DataRecorder *data_recorder);
64 
65  virtual ~IOHandler();
66 
67  // Each IOHandler gets to run until it is done. It should read data from the
68  // "in" and place output into "out" and "err and return when done.
69  virtual void Run() = 0;
70 
71  // Called when an input reader should relinquish its control so another can
72  // be pushed onto the IO handler stack, or so the current IO handler can pop
73  // itself off the stack
74 
75  virtual void Cancel() = 0;
76 
77  // Called when CTRL+C is pressed which usually causes
78  // Debugger::DispatchInputInterrupt to be called.
79 
80  virtual bool Interrupt() = 0;
81 
82  virtual void GotEOF() = 0;
83 
84  virtual bool IsActive() { return m_active && !m_done; }
85 
86  virtual void SetIsDone(bool b) { m_done = b; }
87 
88  virtual bool GetIsDone() { return m_done; }
89 
90  Type GetType() const { return m_type; }
91 
92  virtual void Activate() { m_active = true; }
93 
94  virtual void Deactivate() { m_active = false; }
95 
96  virtual const char *GetPrompt() {
97  // Prompt support isn't mandatory
98  return nullptr;
99  }
100 
101  virtual bool SetPrompt(llvm::StringRef prompt) {
102  // Prompt support isn't mandatory
103  return false;
104  }
105  bool SetPrompt(const char *) = delete;
106 
107  virtual ConstString GetControlSequence(char ch) { return ConstString(); }
108 
109  virtual const char *GetCommandPrefix() { return nullptr; }
110 
111  virtual const char *GetHelpPrologue() { return nullptr; }
112 
113  int GetInputFD();
114 
115  int GetOutputFD();
116 
117  int GetErrorFD();
118 
119  FILE *GetInputFILE();
120 
121  FILE *GetOutputFILE();
122 
123  FILE *GetErrorFILE();
124 
125  lldb::StreamFileSP &GetInputStreamFile();
126 
127  lldb::StreamFileSP &GetOutputStreamFile();
128 
129  lldb::StreamFileSP &GetErrorStreamFile();
130 
131  Debugger &GetDebugger() { return m_debugger; }
132 
133  void *GetUserData() { return m_user_data; }
134 
135  void SetUserData(void *user_data) { m_user_data = user_data; }
136 
137  Flags &GetFlags() { return m_flags; }
138 
139  const Flags &GetFlags() const { return m_flags; }
140 
141  /// Check if the input is being supplied interactively by a user
142  ///
143  /// This will return true if the input stream is a terminal (tty or
144  /// pty) and can cause IO handlers to do different things (like
145  /// for a confirmation when deleting all breakpoints).
146  bool GetIsInteractive();
147 
148  /// Check if the input is coming from a real terminal.
149  ///
150  /// A real terminal has a valid size with a certain number of rows
151  /// and columns. If this function returns true, then terminal escape
152  /// sequences are expected to work (cursor movement escape sequences,
153  /// clearing lines, etc).
154  bool GetIsRealTerminal();
155 
156  void SetPopped(bool b);
157 
158  void WaitForPop();
159 
160  virtual void PrintAsync(Stream *stream, const char *s, size_t len) {
161  stream->Write(s, len);
162  stream->Flush();
163  }
164 
165 protected:
167  lldb::StreamFileSP m_input_sp;
168  lldb::StreamFileSP m_output_sp;
169  lldb::StreamFileSP m_error_sp;
174  void *m_user_data;
175  bool m_done;
176  bool m_active;
177 
178 private:
179  DISALLOW_COPY_AND_ASSIGN(IOHandler);
180 };
181 
182 /// A delegate class for use with IOHandler subclasses.
183 ///
184 /// The IOHandler delegate is designed to be mixed into classes so
185 /// they can use an IOHandler subclass to fetch input and notify the
186 /// object that inherits from this delegate class when a token is
187 /// received.
189 public:
190  enum class Completion { None, LLDBCommand, Expression };
191 
193  : m_completion(completion) {}
194 
195  virtual ~IOHandlerDelegate() = default;
196 
197  virtual void IOHandlerActivated(IOHandler &io_handler, bool interactive) {}
198 
199  virtual void IOHandlerDeactivated(IOHandler &io_handler) {}
200 
201  virtual int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
202  const char *cursor, const char *last_char,
203  int skip_first_n_matches, int max_matches,
204  StringList &matches, StringList &descriptions);
205 
206  virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; }
207 
208  /// Called when a new line is created or one of an identified set of
209  /// indentation characters is typed.
210  ///
211  /// This function determines how much indentation should be added
212  /// or removed to match the recommended amount for the final line.
213  ///
214  /// \param[in] io_handler
215  /// The IOHandler that responsible for input.
216  ///
217  /// \param[in] lines
218  /// The current input up to the line to be corrected. Lines
219  /// following the line containing the cursor are not included.
220  ///
221  /// \param[in] cursor_position
222  /// The number of characters preceding the cursor on the final
223  /// line at the time.
224  ///
225  /// \return
226  /// Returns an integer describing the number of spaces needed
227  /// to correct the indentation level. Positive values indicate
228  /// that spaces should be added, while negative values represent
229  /// spaces that should be removed.
230  virtual int IOHandlerFixIndentation(IOHandler &io_handler,
231  const StringList &lines,
232  int cursor_position) {
233  return 0;
234  }
235 
236  /// Called when a line or lines have been retrieved.
237  ///
238  /// This function can handle the current line and possibly call
239  /// IOHandler::SetIsDone(true) when the IO handler is done like when
240  /// "quit" is entered as a command, of when an empty line is
241  /// received. It is up to the delegate to determine when a line
242  /// should cause a IOHandler to exit.
243  virtual void IOHandlerInputComplete(IOHandler &io_handler,
244  std::string &data) = 0;
245 
246  virtual void IOHandlerInputInterrupted(IOHandler &io_handler,
247  std::string &data) {}
248 
249  /// Called to determine whether typing enter after the last line in
250  /// \a lines should end input. This function will not be called on
251  /// IOHandler objects that are getting single lines.
252  /// \param[in] io_handler
253  /// The IOHandler that responsible for updating the lines.
254  ///
255  /// \param[in] lines
256  /// The current multi-line content. May be altered to provide
257  /// alternative input when complete.
258  ///
259  /// \return
260  /// Return an boolean to indicate whether input is complete,
261  /// true indicates that no additional input is necessary, while
262  /// false indicates that more input is required.
263  virtual bool IOHandlerIsInputComplete(IOHandler &io_handler,
264  StringList &lines) {
265  // Impose no requirements for input to be considered complete. subclasses
266  // should do something more intelligent.
267  return true;
268  }
269 
271  return ConstString();
272  }
273 
274  virtual const char *IOHandlerGetCommandPrefix() { return nullptr; }
275 
276  virtual const char *IOHandlerGetHelpPrologue() { return nullptr; }
277 
278  // Intercept the IOHandler::Interrupt() calls and do something.
279  //
280  // Return true if the interrupt was handled, false if the IOHandler should
281  // continue to try handle the interrupt itself.
282  virtual bool IOHandlerInterrupt(IOHandler &io_handler) { return false; }
283 
284 protected:
285  Completion m_completion; // Support for common builtin completions
286 };
287 
288 // IOHandlerDelegateMultiline
289 //
290 // A IOHandlerDelegate that handles terminating multi-line input when
291 // the last line is equal to "end_line" which is specified in the constructor.
293 public:
294  IOHandlerDelegateMultiline(const char *end_line,
295  Completion completion = Completion::None)
296  : IOHandlerDelegate(completion),
297  m_end_line((end_line && end_line[0]) ? end_line : "") {}
298 
299  ~IOHandlerDelegateMultiline() override = default;
300 
302  if (ch == 'd')
303  return ConstString(m_end_line + "\n");
304  return ConstString();
305  }
306 
308  StringList &lines) override {
309  // Determine whether the end of input signal has been entered
310  const size_t num_lines = lines.GetSize();
311  if (num_lines > 0 && lines[num_lines - 1] == m_end_line) {
312  // Remove the terminal line from "lines" so it doesn't appear in the
313  // resulting input and return true to indicate we are done getting lines
314  lines.PopBack();
315  return true;
316  }
317  return false;
318  }
319 
320 protected:
321  const std::string m_end_line;
322 };
323 
324 class IOHandlerEditline : public IOHandler {
325 public:
327  const char *editline_name, // Used for saving history files
328  llvm::StringRef prompt, llvm::StringRef continuation_prompt,
329  bool multi_line, bool color_prompts,
330  uint32_t line_number_start, // If non-zero show line numbers
331  // starting at
332  // 'line_number_start'
333  IOHandlerDelegate &delegate,
334  repro::DataRecorder *data_recorder);
335 
337  const lldb::StreamFileSP &input_sp,
338  const lldb::StreamFileSP &output_sp,
339  const lldb::StreamFileSP &error_sp, uint32_t flags,
340  const char *editline_name, // Used for saving history files
341  llvm::StringRef prompt, llvm::StringRef continuation_prompt,
342  bool multi_line, bool color_prompts,
343  uint32_t line_number_start, // If non-zero show line numbers
344  // starting at
345  // 'line_number_start'
346  IOHandlerDelegate &delegate,
347  repro::DataRecorder *data_recorder);
348 
349  IOHandlerEditline(Debugger &, IOHandler::Type, const char *, const char *,
350  const char *, bool, bool, uint32_t,
351  IOHandlerDelegate &) = delete;
352 
353  IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::StreamFileSP &,
354  const lldb::StreamFileSP &, const lldb::StreamFileSP &,
355  uint32_t, const char *, const char *, const char *, bool,
356  bool, uint32_t, IOHandlerDelegate &) = delete;
357 
358  ~IOHandlerEditline() override;
359 
360  void Run() override;
361 
362  void Cancel() override;
363 
364  bool Interrupt() override;
365 
366  void GotEOF() override;
367 
368  void Activate() override;
369 
370  void Deactivate() override;
371 
372  ConstString GetControlSequence(char ch) override {
373  return m_delegate.IOHandlerGetControlSequence(ch);
374  }
375 
376  const char *GetCommandPrefix() override {
377  return m_delegate.IOHandlerGetCommandPrefix();
378  }
379 
380  const char *GetHelpPrologue() override {
381  return m_delegate.IOHandlerGetHelpPrologue();
382  }
383 
384  const char *GetPrompt() override;
385 
386  bool SetPrompt(llvm::StringRef prompt) override;
387  bool SetPrompt(const char *prompt) = delete;
388 
389  const char *GetContinuationPrompt();
390 
391  void SetContinuationPrompt(llvm::StringRef prompt);
392  void SetContinuationPrompt(const char *) = delete;
393 
394  bool GetLine(std::string &line, bool &interrupted);
395 
396  bool GetLines(StringList &lines, bool &interrupted);
397 
398  void SetBaseLineNumber(uint32_t line);
399 
400  bool GetInterruptExits() { return m_interrupt_exits; }
401 
402  void SetInterruptExits(bool b) { m_interrupt_exits = b; }
403 
404  const StringList *GetCurrentLines() const { return m_current_lines_ptr; }
405 
406  uint32_t GetCurrentLineIndex() const;
407 
408  void PrintAsync(Stream *stream, const char *s, size_t len) override;
409 
410 private:
411 #ifndef LLDB_DISABLE_LIBEDIT
412  static bool IsInputCompleteCallback(Editline *editline, StringList &lines,
413  void *baton);
414 
415  static int FixIndentationCallback(Editline *editline, const StringList &lines,
416  int cursor_position, void *baton);
417 
418  static int AutoCompleteCallback(const char *current_line, const char *cursor,
419  const char *last_char,
420  int skip_first_n_matches, int max_matches,
421  StringList &matches, StringList &descriptions,
422  void *baton);
423 #endif
424 
425 protected:
426 #ifndef LLDB_DISABLE_LIBEDIT
427  std::unique_ptr<Editline> m_editline_up;
428 #endif
430  std::string m_prompt;
433  uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt
438  bool m_editing; // Set to true when fetching a line manually (not using
439  // libedit)
440 };
441 
442 // The order of base classes is important. Look at the constructor of
443 // IOHandlerConfirm to see how.
445 public:
446  IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
447  bool default_response);
448 
449  ~IOHandlerConfirm() override;
450 
451  bool GetResponse() const { return m_user_response; }
452 
453  int IOHandlerComplete(IOHandler &io_handler, const char *current_line,
454  const char *cursor, const char *last_char,
455  int skip_first_n_matches, int max_matches,
456  StringList &matches, StringList &descriptions) override;
457 
458  void IOHandlerInputComplete(IOHandler &io_handler,
459  std::string &data) override;
460 
461 protected:
462  const bool m_default_response;
464 };
465 
467 public:
468  IOHandlerCursesGUI(Debugger &debugger);
469 
470  ~IOHandlerCursesGUI() override;
471 
472  void Run() override;
473 
474  void Cancel() override;
475 
476  bool Interrupt() override;
477 
478  void GotEOF() override;
479 
480  void Activate() override;
481 
482  void Deactivate() override;
483 
484 protected:
486 };
487 
489 public:
491  ValueObjectList &valobj_list);
492 
493  ~IOHandlerCursesValueObjectList() override;
494 
495  void Run() override;
496 
497  void GotEOF() override;
498 
499 protected:
501 };
502 
504 public:
505  IOHandlerStack() : m_stack(), m_mutex(), m_top(nullptr) {}
506 
507  ~IOHandlerStack() = default;
508 
509  size_t GetSize() const {
510  std::lock_guard<std::recursive_mutex> guard(m_mutex);
511  return m_stack.size();
512  }
513 
514  void Push(const lldb::IOHandlerSP &sp) {
515  if (sp) {
516  std::lock_guard<std::recursive_mutex> guard(m_mutex);
517  sp->SetPopped(false);
518  m_stack.push_back(sp);
519  // Set m_top the non-locking IsTop() call
520  m_top = sp.get();
521  }
522  }
523 
524  bool IsEmpty() const {
525  std::lock_guard<std::recursive_mutex> guard(m_mutex);
526  return m_stack.empty();
527  }
528 
529  lldb::IOHandlerSP Top() {
530  lldb::IOHandlerSP sp;
531  {
532  std::lock_guard<std::recursive_mutex> guard(m_mutex);
533  if (!m_stack.empty())
534  sp = m_stack.back();
535  }
536  return sp;
537  }
538 
539  void Pop() {
540  std::lock_guard<std::recursive_mutex> guard(m_mutex);
541  if (!m_stack.empty()) {
542  lldb::IOHandlerSP sp(m_stack.back());
543  m_stack.pop_back();
544  sp->SetPopped(true);
545  }
546  // Set m_top the non-locking IsTop() call
547 
548  m_top = (m_stack.empty() ? nullptr : m_stack.back().get());
549  }
550 
551  std::recursive_mutex &GetMutex() { return m_mutex; }
552 
553  bool IsTop(const lldb::IOHandlerSP &io_handler_sp) const {
554  return m_top == io_handler_sp.get();
555  }
556 
558  IOHandler::Type second_top_type) {
559  std::lock_guard<std::recursive_mutex> guard(m_mutex);
560  const size_t num_io_handlers = m_stack.size();
561  return (num_io_handlers >= 2 &&
562  m_stack[num_io_handlers - 1]->GetType() == top_type &&
563  m_stack[num_io_handlers - 2]->GetType() == second_top_type);
564  }
565 
567  return ((m_top != nullptr) ? m_top->GetControlSequence(ch) : ConstString());
568  }
569 
571  return ((m_top != nullptr) ? m_top->GetCommandPrefix() : nullptr);
572  }
573 
575  return ((m_top != nullptr) ? m_top->GetHelpPrologue() : nullptr);
576  }
577 
578  void PrintAsync(Stream *stream, const char *s, size_t len);
579 
580 protected:
581  typedef std::vector<lldb::IOHandlerSP> collection;
582  collection m_stack;
583  mutable std::recursive_mutex m_mutex;
585 
586 private:
587  DISALLOW_COPY_AND_ASSIGN(IOHandlerStack);
588 };
589 
590 } // namespace lldb_private
591 
592 #endif // liblldb_IOHandler_h_
A class to manage flag bits.
Definition: Debugger.h:82
virtual const char * GetHelpPrologue()
Definition: IOHandler.h:111
ConstString GetTopIOHandlerControlSequence(char ch)
Definition: IOHandler.h:566
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
virtual ConstString GetControlSequence(char ch)
Definition: IOHandler.h:107
virtual bool SetPrompt(llvm::StringRef prompt)
Definition: IOHandler.h:101
const char * GetTopIOHandlerCommandPrefix()
Definition: IOHandler.h:570
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void Push(const lldb::IOHandlerSP &sp)
Definition: IOHandler.h:514
lldb::StreamFileSP m_input_sp
Definition: IOHandler.h:167
virtual bool IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines)
Called to determine whether typing enter after the last line in lines should end input.
Definition: IOHandler.h:263
const char * GetCommandPrefix() override
Definition: IOHandler.h:376
IOHandlerDelegateMultiline(const char *end_line, Completion completion=Completion::None)
Definition: IOHandler.h:294
Encapsulates a single expression for use in lldb.
Definition: Expression.h:33
virtual void Flush()=0
Flush the stream.
const char * GetTopIOHandlerHelpPrologue()
Definition: IOHandler.h:574
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
Definition: Stream.h:100
virtual const char * IOHandlerGetCommandPrefix()
Definition: IOHandler.h:274
A delegate class for use with IOHandler subclasses.
Definition: IOHandler.h:188
const Flags & GetFlags() const
Definition: IOHandler.h:139
std::recursive_mutex m_mutex
Definition: IOHandler.h:583
ConstString GetControlSequence(char ch) override
Definition: IOHandler.h:372
virtual void Deactivate()
Definition: IOHandler.h:94
virtual void IOHandlerInputInterrupted(IOHandler &io_handler, std::string &data)
Definition: IOHandler.h:246
virtual const char * GetCommandPrefix()
Definition: IOHandler.h:109
virtual bool GetIsDone()
Definition: IOHandler.h:88
bool IsTop(const lldb::IOHandlerSP &io_handler_sp) const
Definition: IOHandler.h:553
std::unique_ptr< Application > ApplicationAP
Definition: IOHandler.h:36
const StringList * GetCurrentLines() const
Definition: IOHandler.h:404
Predicate< bool > m_popped
Definition: IOHandler.h:171
bool CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type)
Definition: IOHandler.h:557
std::vector< lldb::IOHandlerSP > collection
Definition: IOHandler.h:581
Debugger & GetDebugger()
Definition: IOHandler.h:131
virtual const char * GetPrompt()
Definition: IOHandler.h:96
virtual bool IOHandlerInterrupt(IOHandler &io_handler)
Definition: IOHandler.h:282
virtual ConstString IOHandlerGetControlSequence(char ch)
Definition: IOHandler.h:270
virtual bool IsActive()
Definition: IOHandler.h:84
std::recursive_mutex & GetMutex()
Definition: IOHandler.h:551
size_t GetSize() const
Definition: StringList.cpp:70
virtual int IOHandlerFixIndentation(IOHandler &io_handler, const StringList &lines, int cursor_position)
Called when a new line is created or one of an identified set of indentation characters is typed...
Definition: IOHandler.h:230
A class to manage flags.
Definition: Flags.h:22
lldb::IOHandlerSP Top()
Definition: IOHandler.h:529
virtual const char * IOHandlerGetHelpPrologue()
Definition: IOHandler.h:276
IOHandlerDelegate(Completion completion=Completion::None)
Definition: IOHandler.h:192
A uniqued constant string class.
Definition: ConstString.h:38
virtual void SetIsDone(bool b)
Definition: IOHandler.h:86
lldb::StreamFileSP m_output_sp
Definition: IOHandler.h:168
void SetUserData(void *user_data)
Definition: IOHandler.h:135
Type GetType() const
Definition: IOHandler.h:90
virtual void PrintAsync(Stream *stream, const char *s, size_t len)
Definition: IOHandler.h:160
lldb::StreamFileSP m_error_sp
Definition: IOHandler.h:169
virtual void IOHandlerDeactivated(IOHandler &io_handler)
Definition: IOHandler.h:199
IOHandlerDelegate & m_delegate
Definition: IOHandler.h:429
repro::DataRecorder * m_data_recorder
Definition: IOHandler.h:170
virtual const char * IOHandlerGetFixIndentationCharacters()
Definition: IOHandler.h:206
curses::ApplicationAP m_app_ap
Definition: IOHandler.h:485
ConstString IOHandlerGetControlSequence(char ch) override
Definition: IOHandler.h:301
virtual void Activate()
Definition: IOHandler.h:92
bool IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) override
Called to determine whether typing enter after the last line in lines should end input.
Definition: IOHandler.h:307
const char * GetHelpPrologue() override
Definition: IOHandler.h:380
virtual void IOHandlerActivated(IOHandler &io_handler, bool interactive)
Definition: IOHandler.h:197
std::unique_ptr< Editline > m_editline_up
Definition: IOHandler.h:427