diff options
Diffstat (limited to 'source/Host')
| -rw-r--r-- | source/Host/common/Editline.cpp | 172 | ||||
| -rw-r--r-- | source/Host/common/File.cpp | 410 | ||||
| -rw-r--r-- | source/Host/common/FileCache.cpp | 38 | ||||
| -rw-r--r-- | source/Host/common/FileSystem.cpp | 33 | ||||
| -rw-r--r-- | source/Host/common/Host.cpp | 39 | ||||
| -rw-r--r-- | source/Host/common/HostInfoBase.cpp | 21 | ||||
| -rw-r--r-- | source/Host/common/HostNativeThreadBase.cpp | 3 | ||||
| -rw-r--r-- | source/Host/common/LZMA.cpp | 146 | ||||
| -rw-r--r-- | source/Host/common/MainLoop.cpp | 1 | ||||
| -rw-r--r-- | source/Host/common/NativeProcessProtocol.cpp | 75 | ||||
| -rw-r--r-- | source/Host/common/NativeRegisterContext.cpp | 32 | ||||
| -rw-r--r-- | source/Host/common/Socket.cpp | 102 | ||||
| -rw-r--r-- | source/Host/common/TCPSocket.cpp | 6 | ||||
| -rw-r--r-- | source/Host/common/UDPSocket.cpp | 5 | ||||
| -rw-r--r-- | source/Host/freebsd/HostInfoFreeBSD.cpp | 11 | ||||
| -rw-r--r-- | source/Host/posix/ConnectionFileDescriptorPosix.cpp | 159 | ||||
| -rw-r--r-- | source/Host/posix/HostInfoPosix.cpp | 45 | 
17 files changed, 781 insertions, 517 deletions
| diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp index d3a70aeaa326..3e655244b107 100644 --- a/source/Host/common/Editline.cpp +++ b/source/Host/common/Editline.cpp @@ -14,6 +14,7 @@  #include "lldb/Host/Editline.h"  #include "lldb/Host/FileSystem.h"  #include "lldb/Host/Host.h" +#include "lldb/Utility/CompletionRequest.h"  #include "lldb/Utility/FileSpec.h"  #include "lldb/Utility/LLDBAssert.h"  #include "lldb/Utility/SelectHelper.h" @@ -863,26 +864,59 @@ unsigned char Editline::BufferEndCommand(int ch) {  /// Prints completions and their descriptions to the given file. Only the  /// completions in the interval [start, end) are printed. -static void PrintCompletion(FILE *output_file, size_t start, size_t end, -                            StringList &completions, StringList &descriptions) { -  // This is an 'int' because of printf. -  int max_len = 0; - -  for (size_t i = start; i < end; i++) { -    const char *completion_str = completions.GetStringAtIndex(i); -    max_len = std::max((int)strlen(completion_str), max_len); +static void +PrintCompletion(FILE *output_file, +                llvm::ArrayRef<CompletionResult::Completion> results, +                size_t max_len) { +  for (const CompletionResult::Completion &c : results) { +    fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str()); +    if (!c.GetDescription().empty()) +      fprintf(output_file, " -- %s", c.GetDescription().c_str()); +    fprintf(output_file, "\n");    } +} + +static void +DisplayCompletions(::EditLine *editline, FILE *output_file, +                   llvm::ArrayRef<CompletionResult::Completion> results) { +  assert(!results.empty()); -  for (size_t i = start; i < end; i++) { -    const char *completion_str = completions.GetStringAtIndex(i); -    const char *description_str = descriptions.GetStringAtIndex(i); +  fprintf(output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n"); +  const size_t page_size = 40; +  bool all = false; -    if (completion_str) -      fprintf(output_file, "\n\t%-*s", max_len, completion_str); +  auto longest = +      std::max_element(results.begin(), results.end(), [](auto &c1, auto &c2) { +        return c1.GetCompletion().size() < c2.GetCompletion().size(); +      }); -    // Print the description if we got one. -    if (description_str && strlen(description_str)) -      fprintf(output_file, " -- %s", description_str); +  const size_t max_len = longest->GetCompletion().size(); + +  if (results.size() < page_size) { +    PrintCompletion(output_file, results, max_len); +    return; +  } + +  size_t cur_pos = 0; +  while (cur_pos < results.size()) { +    size_t remaining = results.size() - cur_pos; +    size_t next_size = all ? remaining : std::min(page_size, remaining); + +    PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len); + +    cur_pos += next_size; + +    if (cur_pos >= results.size()) +      break; + +    fprintf(output_file, "More (Y/n/a): "); +    char reply = 'n'; +    int got_char = el_getc(editline, &reply); +    fprintf(output_file, "\n"); +    if (got_char == -1 || reply == 'n') +      break; +    if (reply == 'a') +      all = true;    }  } @@ -891,74 +925,64 @@ unsigned char Editline::TabCommand(int ch) {      return CC_ERROR;    const LineInfo *line_info = el_line(m_editline); -  StringList completions, descriptions; -  int page_size = 40; -  const int num_completions = m_completion_callback( -      line_info->buffer, line_info->cursor, line_info->lastchar, -      0,  // Don't skip any matches (start at match zero) -      -1, // Get all the matches -      completions, descriptions, m_completion_callback_baton); +  llvm::StringRef line(line_info->buffer, +                       line_info->lastchar - line_info->buffer); +  unsigned cursor_index = line_info->cursor - line_info->buffer; +  CompletionResult result; +  CompletionRequest request(line, cursor_index, result); -  if (num_completions == 0) +  m_completion_callback(request, m_completion_callback_baton); + +  llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults(); + +  StringList completions; +  result.GetMatches(completions); + +  if (results.size() == 0)      return CC_ERROR; -  //    if (num_completions == -1) -  //    { -  //        el_insertstr (m_editline, m_completion_key); -  //        return CC_REDISPLAY; -  //    } -  //    else -  if (num_completions == -2) { -    // Replace the entire line with the first string... -    el_deletestr(m_editline, line_info->cursor - line_info->buffer); -    el_insertstr(m_editline, completions.GetStringAtIndex(0)); + +  if (results.size() == 1) { +    CompletionResult::Completion completion = results.front(); +    switch (completion.GetMode()) { +    case CompletionMode::Normal: { +      std::string to_add = completion.GetCompletion(); +      to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); +      if (request.GetParsedArg().IsQuoted()) +        to_add.push_back(request.GetParsedArg().GetQuoteChar()); +      to_add.push_back(' '); +      el_insertstr(m_editline, to_add.c_str()); +      break; +    } +    case CompletionMode::Partial: { +      std::string to_add = completion.GetCompletion(); +      to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); +      el_insertstr(m_editline, to_add.c_str()); +      break; +    } +    case CompletionMode::RewriteLine: { +      el_deletestr(m_editline, line_info->cursor - line_info->buffer); +      el_insertstr(m_editline, completion.GetCompletion().c_str()); +      break; +    } +    }      return CC_REDISPLAY;    }    // If we get a longer match display that first. -  const char *completion_str = completions.GetStringAtIndex(0); -  if (completion_str != nullptr && *completion_str != '\0') { -    el_insertstr(m_editline, completion_str); +  std::string longest_prefix = completions.LongestCommonPrefix(); +  if (!longest_prefix.empty()) +    longest_prefix = +        longest_prefix.substr(request.GetCursorArgumentPrefix().size()); +  if (!longest_prefix.empty()) { +    el_insertstr(m_editline, longest_prefix.c_str());      return CC_REDISPLAY;    } -  if (num_completions > 1) { -    int num_elements = num_completions + 1; -    fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:"); -    if (num_completions < page_size) { -      PrintCompletion(m_output_file, 1, num_elements, completions, -                      descriptions); -      fprintf(m_output_file, "\n"); -    } else { -      int cur_pos = 1; -      char reply; -      int got_char; -      while (cur_pos < num_elements) { -        int endpoint = cur_pos + page_size; -        if (endpoint > num_elements) -          endpoint = num_elements; - -        PrintCompletion(m_output_file, cur_pos, endpoint, completions, -                        descriptions); -        cur_pos = endpoint; - -        if (cur_pos >= num_elements) { -          fprintf(m_output_file, "\n"); -          break; -        } - -        fprintf(m_output_file, "\nMore (Y/n/a): "); -        reply = 'n'; -        got_char = el_getc(m_editline, &reply); -        if (got_char == -1 || reply == 'n') -          break; -        if (reply == 'a') -          page_size = num_elements - cur_pos; -      } -    } -    DisplayInput(); -    MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); -  } +  DisplayCompletions(m_editline, m_output_file, results); + +  DisplayInput(); +  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);    return CC_REDISPLAY;  } diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp index c8c8d7a0d496..9dae24d766f6 100644 --- a/source/Host/common/File.cpp +++ b/source/Host/common/File.cpp @@ -37,8 +37,10 @@  using namespace lldb;  using namespace lldb_private; +using llvm::Expected; -static const char *GetStreamOpenModeFromOptions(uint32_t options) { +Expected<const char *> +File::GetStreamOpenModeFromOptions(File::OpenOptions options) {    if (options & File::eOpenOptionAppend) {      if (options & File::eOpenOptionRead) {        if (options & File::eOpenOptionCanCreateNewOnly) @@ -65,15 +67,188 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) {    } else if (options & File::eOpenOptionWrite) {      return "w";    } -  return nullptr; +  return llvm::createStringError( +      llvm::inconvertibleErrorCode(), +      "invalid options, cannot convert to mode string"); +} + +Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) { +  OpenOptions opts = +      llvm::StringSwitch<OpenOptions>(mode) +          .Cases("r", "rb", eOpenOptionRead) +          .Cases("w", "wb", eOpenOptionWrite) +          .Cases("a", "ab", +                 eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate) +          .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite) +          .Cases("w+", "wb+", "w+b", +                 eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate | +                     eOpenOptionTruncate) +          .Cases("a+", "ab+", "a+b", +                 eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend | +                     eOpenOptionCanCreate) +          .Default(OpenOptions()); +  if (opts) +    return opts; +  return llvm::createStringError( +      llvm::inconvertibleErrorCode(), +      "invalid mode, cannot convert to File::OpenOptions");  }  int File::kInvalidDescriptor = -1;  FILE *File::kInvalidStream = nullptr; -File::~File() { Close(); } +Status File::Read(void *buf, size_t &num_bytes) { +  return std::error_code(ENOTSUP, std::system_category()); +} +Status File::Write(const void *buf, size_t &num_bytes) { +  return std::error_code(ENOTSUP, std::system_category()); +} + +bool File::IsValid() const { return false; } + +Status File::Close() { return Flush(); } + +IOObject::WaitableHandle File::GetWaitableHandle() { +  return IOObject::kInvalidHandleValue; +} -int File::GetDescriptor() const { +Status File::GetFileSpec(FileSpec &file_spec) const { +  file_spec.Clear(); +  return std::error_code(ENOTSUP, std::system_category()); +} + +int File::GetDescriptor() const { return kInvalidDescriptor; } + +FILE *File::GetStream() { return nullptr; } + +off_t File::SeekFromStart(off_t offset, Status *error_ptr) { +  if (error_ptr) +    *error_ptr = std::error_code(ENOTSUP, std::system_category()); +  return -1; +} + +off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) { +  if (error_ptr) +    *error_ptr = std::error_code(ENOTSUP, std::system_category()); +  return -1; +} + +off_t File::SeekFromEnd(off_t offset, Status *error_ptr) { +  if (error_ptr) +    *error_ptr = std::error_code(ENOTSUP, std::system_category()); +  return -1; +} + +Status File::Read(void *dst, size_t &num_bytes, off_t &offset) { +  return std::error_code(ENOTSUP, std::system_category()); +} + +Status File::Write(const void *src, size_t &num_bytes, off_t &offset) { +  return std::error_code(ENOTSUP, std::system_category()); +} + +Status File::Flush() { return Status(); } + +Status File::Sync() { return Flush(); } + +void File::CalculateInteractiveAndTerminal() { +  const int fd = GetDescriptor(); +  if (!DescriptorIsValid(fd)) { +    m_is_interactive = eLazyBoolNo; +    m_is_real_terminal = eLazyBoolNo; +    m_supports_colors = eLazyBoolNo; +    return; +  } +  m_is_interactive = eLazyBoolNo; +  m_is_real_terminal = eLazyBoolNo; +#if defined(_WIN32) +  if (_isatty(fd)) { +    m_is_interactive = eLazyBoolYes; +    m_is_real_terminal = eLazyBoolYes; +#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) +    m_supports_colors = eLazyBoolYes; +#endif +  } +#else +  if (isatty(fd)) { +    m_is_interactive = eLazyBoolYes; +    struct winsize window_size; +    if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) { +      if (window_size.ws_col > 0) { +        m_is_real_terminal = eLazyBoolYes; +        if (llvm::sys::Process::FileDescriptorHasColors(fd)) +          m_supports_colors = eLazyBoolYes; +      } +    } +  } +#endif +} + +bool File::GetIsInteractive() { +  if (m_is_interactive == eLazyBoolCalculate) +    CalculateInteractiveAndTerminal(); +  return m_is_interactive == eLazyBoolYes; +} + +bool File::GetIsRealTerminal() { +  if (m_is_real_terminal == eLazyBoolCalculate) +    CalculateInteractiveAndTerminal(); +  return m_is_real_terminal == eLazyBoolYes; +} + +bool File::GetIsTerminalWithColors() { +  if (m_supports_colors == eLazyBoolCalculate) +    CalculateInteractiveAndTerminal(); +  return m_supports_colors == eLazyBoolYes; +} + +size_t File::Printf(const char *format, ...) { +  va_list args; +  va_start(args, format); +  size_t result = PrintfVarArg(format, args); +  va_end(args); +  return result; +} + +size_t File::PrintfVarArg(const char *format, va_list args) { +  size_t result = 0; +  char *s = nullptr; +  result = vasprintf(&s, format, args); +  if (s != nullptr) { +    if (result > 0) { +      size_t s_len = result; +      Write(s, s_len); +      result = s_len; +    } +    free(s); +  } +  return result; +} + +Expected<File::OpenOptions> File::GetOptions() const { +  return llvm::createStringError( +      llvm::inconvertibleErrorCode(), +      "GetOptions() not implemented for this File class"); +} + +uint32_t File::GetPermissions(Status &error) const { +  int fd = GetDescriptor(); +  if (!DescriptorIsValid(fd)) { +    error = std::error_code(ENOTSUP, std::system_category()); +    return 0; +  } +  struct stat file_stats; +  if (::fstat(fd, &file_stats) == -1) { +    error.SetErrorToErrno(); +    return 0; +  } +  error.Clear(); +  return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); +} + +Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; } + +int NativeFile::GetDescriptor() const {    if (DescriptorIsValid())      return m_descriptor; @@ -91,21 +266,18 @@ int File::GetDescriptor() const {    return kInvalidDescriptor;  } -IOObject::WaitableHandle File::GetWaitableHandle() { return m_descriptor; } - -void File::SetDescriptor(int fd, bool transfer_ownership) { -  if (IsValid()) -    Close(); -  m_descriptor = fd; -  m_should_close_fd = transfer_ownership; +IOObject::WaitableHandle NativeFile::GetWaitableHandle() { +  return GetDescriptor();  } -FILE *File::GetStream() { +FILE *NativeFile::GetStream() {    if (!StreamIsValid()) {      if (DescriptorIsValid()) { -      const char *mode = GetStreamOpenModeFromOptions(m_options); -      if (mode) { -        if (!m_should_close_fd) { +      auto mode = GetStreamOpenModeFromOptions(m_options); +      if (!mode) +        llvm::consumeError(mode.takeError()); +      else { +        if (!m_own_descriptor) {  // We must duplicate the file descriptor if we don't own it because when you  // call fdopen, the stream will own the fd  #ifdef _WIN32 @@ -113,18 +285,18 @@ FILE *File::GetStream() {  #else            m_descriptor = dup(GetDescriptor());  #endif -          m_should_close_fd = true; +          m_own_descriptor = true;          } -        m_stream = -            llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode); +        m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, +                                               mode.get());          // If we got a stream, then we own the stream and should no longer own          // the descriptor because fclose() will close it for us          if (m_stream) {            m_own_stream = true; -          m_should_close_fd = false; +          m_own_descriptor = false;          }        }      } @@ -132,60 +304,32 @@ FILE *File::GetStream() {    return m_stream;  } -void File::SetStream(FILE *fh, bool transfer_ownership) { -  if (IsValid()) -    Close(); -  m_stream = fh; -  m_own_stream = transfer_ownership; -} - -uint32_t File::GetPermissions(Status &error) const { -  int fd = GetDescriptor(); -  if (fd != kInvalidDescriptor) { -    struct stat file_stats; -    if (::fstat(fd, &file_stats) == -1) -      error.SetErrorToErrno(); -    else { -      error.Clear(); -      return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); -    } -  } else { -    error.SetErrorString("invalid file descriptor"); -  } -  return 0; -} - -Status File::Close() { +Status NativeFile::Close() {    Status error; -  if (StreamIsValid() && m_own_stream) { -    if (::fclose(m_stream) == EOF) -      error.SetErrorToErrno(); +  if (StreamIsValid()) { +    if (m_own_stream) { +      if (::fclose(m_stream) == EOF) +        error.SetErrorToErrno(); +    } else { +      if (::fflush(m_stream) == EOF) +        error.SetErrorToErrno(); +    }    } - -  if (DescriptorIsValid() && m_should_close_fd) { +  if (DescriptorIsValid() && m_own_descriptor) {      if (::close(m_descriptor) != 0)        error.SetErrorToErrno();    }    m_descriptor = kInvalidDescriptor;    m_stream = kInvalidStream; -  m_options = 0; +  m_options = OpenOptions(0);    m_own_stream = false; -  m_should_close_fd = false; +  m_own_descriptor = false;    m_is_interactive = eLazyBoolCalculate;    m_is_real_terminal = eLazyBoolCalculate;    return error;  } -void File::Clear() { -  m_stream = nullptr; -  m_descriptor = kInvalidDescriptor; -  m_options = 0; -  m_own_stream = false; -  m_is_interactive = m_supports_colors = m_is_real_terminal = -      eLazyBoolCalculate; -} - -Status File::GetFileSpec(FileSpec &file_spec) const { +Status NativeFile::GetFileSpec(FileSpec &file_spec) const {    Status error;  #ifdef F_GETPATH    if (IsValid()) { @@ -212,7 +356,8 @@ Status File::GetFileSpec(FileSpec &file_spec) const {      }    }  #else -  error.SetErrorString("File::GetFileSpec is not supported on this platform"); +  error.SetErrorString( +      "NativeFile::GetFileSpec is not supported on this platform");  #endif    if (error.Fail()) @@ -220,7 +365,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {    return error;  } -off_t File::SeekFromStart(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) {    off_t result = 0;    if (DescriptorIsValid()) {      result = ::lseek(m_descriptor, offset, SEEK_SET); @@ -246,7 +391,7 @@ off_t File::SeekFromStart(off_t offset, Status *error_ptr) {    return result;  } -off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) {    off_t result = -1;    if (DescriptorIsValid()) {      result = ::lseek(m_descriptor, offset, SEEK_CUR); @@ -272,7 +417,7 @@ off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) {    return result;  } -off_t File::SeekFromEnd(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) {    off_t result = -1;    if (DescriptorIsValid()) {      result = ::lseek(m_descriptor, offset, SEEK_END); @@ -298,7 +443,7 @@ off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {    return result;  } -Status File::Flush() { +Status NativeFile::Flush() {    Status error;    if (StreamIsValid()) {      if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF) @@ -309,7 +454,7 @@ Status File::Flush() {    return error;  } -Status File::Sync() { +Status NativeFile::Sync() {    Status error;    if (DescriptorIsValid()) {  #ifdef _WIN32 @@ -332,7 +477,7 @@ Status File::Sync() {  #define MAX_WRITE_SIZE INT_MAX  #endif -Status File::Read(void *buf, size_t &num_bytes) { +Status NativeFile::Read(void *buf, size_t &num_bytes) {    Status error;  #if defined(MAX_READ_SIZE) @@ -391,7 +536,7 @@ Status File::Read(void *buf, size_t &num_bytes) {    return error;  } -Status File::Write(const void *buf, size_t &num_bytes) { +Status NativeFile::Write(const void *buf, size_t &num_bytes) {    Status error;  #if defined(MAX_WRITE_SIZE) @@ -453,7 +598,7 @@ Status File::Write(const void *buf, size_t &num_bytes) {    return error;  } -Status File::Read(void *buf, size_t &num_bytes, off_t &offset) { +Status NativeFile::Read(void *buf, size_t &num_bytes, off_t &offset) {    Status error;  #if defined(MAX_READ_SIZE) @@ -513,51 +658,7 @@ Status File::Read(void *buf, size_t &num_bytes, off_t &offset) {    return error;  } -Status File::Read(size_t &num_bytes, off_t &offset, bool null_terminate, -                  DataBufferSP &data_buffer_sp) { -  Status error; - -  if (num_bytes > 0) { -    int fd = GetDescriptor(); -    if (fd != kInvalidDescriptor) { -      struct stat file_stats; -      if (::fstat(fd, &file_stats) == 0) { -        if (file_stats.st_size > offset) { -          const size_t bytes_left = file_stats.st_size - offset; -          if (num_bytes > bytes_left) -            num_bytes = bytes_left; - -          size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0); -          std::unique_ptr<DataBufferHeap> data_heap_up; -          data_heap_up.reset(new DataBufferHeap()); -          data_heap_up->SetByteSize(num_bytes_plus_nul_char); - -          if (data_heap_up) { -            error = Read(data_heap_up->GetBytes(), num_bytes, offset); -            if (error.Success()) { -              // Make sure we read exactly what we asked for and if we got -              // less, adjust the array -              if (num_bytes_plus_nul_char < data_heap_up->GetByteSize()) -                data_heap_up->SetByteSize(num_bytes_plus_nul_char); -              data_buffer_sp.reset(data_heap_up.release()); -              return error; -            } -          } -        } else -          error.SetErrorString("file is empty"); -      } else -        error.SetErrorToErrno(); -    } else -      error.SetErrorString("invalid file handle"); -  } else -    error.SetErrorString("invalid file handle"); - -  num_bytes = 0; -  data_buffer_sp.reset(); -  return error; -} - -Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) { +Status NativeFile::Write(const void *buf, size_t &num_bytes, off_t &offset) {    Status error;  #if defined(MAX_WRITE_SIZE) @@ -621,36 +722,15 @@ Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) {    return error;  } -// Print some formatted output to the stream. -size_t File::Printf(const char *format, ...) { -  va_list args; -  va_start(args, format); -  size_t result = PrintfVarArg(format, args); -  va_end(args); -  return result; -} - -// Print some formatted output to the stream. -size_t File::PrintfVarArg(const char *format, va_list args) { -  size_t result = 0; -  if (DescriptorIsValid()) { -    char *s = nullptr; -    result = vasprintf(&s, format, args); -    if (s != nullptr) { -      if (result > 0) { -        size_t s_len = result; -        Write(s, s_len); -        result = s_len; -      } -      free(s); -    } -  } else if (StreamIsValid()) { -    result = ::vfprintf(m_stream, format, args); +size_t NativeFile::PrintfVarArg(const char *format, va_list args) { +  if (StreamIsValid()) { +    return ::vfprintf(m_stream, format, args); +  } else { +    return File::PrintfVarArg(format, args);    } -  return result;  } -mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) { +mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) {    mode_t mode = 0;    if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite)      mode |= O_RDWR; @@ -674,49 +754,5 @@ mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) {    return mode;  } -void File::CalculateInteractiveAndTerminal() { -  const int fd = GetDescriptor(); -  if (fd >= 0) { -    m_is_interactive = eLazyBoolNo; -    m_is_real_terminal = eLazyBoolNo; -#if defined(_WIN32) -    if (_isatty(fd)) { -      m_is_interactive = eLazyBoolYes; -      m_is_real_terminal = eLazyBoolYes; -#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) -      m_supports_colors = eLazyBoolYes; -#endif -    } -#else -    if (isatty(fd)) { -      m_is_interactive = eLazyBoolYes; -      struct winsize window_size; -      if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) { -        if (window_size.ws_col > 0) { -          m_is_real_terminal = eLazyBoolYes; -          if (llvm::sys::Process::FileDescriptorHasColors(fd)) -            m_supports_colors = eLazyBoolYes; -        } -      } -    } -#endif -  } -} - -bool File::GetIsInteractive() { -  if (m_is_interactive == eLazyBoolCalculate) -    CalculateInteractiveAndTerminal(); -  return m_is_interactive == eLazyBoolYes; -} - -bool File::GetIsRealTerminal() { -  if (m_is_real_terminal == eLazyBoolCalculate) -    CalculateInteractiveAndTerminal(); -  return m_is_real_terminal == eLazyBoolYes; -} - -bool File::GetIsTerminalWithColors() { -  if (m_supports_colors == eLazyBoolCalculate) -    CalculateInteractiveAndTerminal(); -  return m_supports_colors == eLazyBoolYes; -} +char File::ID = 0; +char NativeFile::ID = 0; diff --git a/source/Host/common/FileCache.cpp b/source/Host/common/FileCache.cpp index 4bd3efda7fb0..d9dcad992c33 100644 --- a/source/Host/common/FileCache.cpp +++ b/source/Host/common/FileCache.cpp @@ -23,18 +23,20 @@ FileCache &FileCache::GetInstance() {    return *m_instance;  } -lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, -                                    uint32_t mode, Status &error) { +lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, +                                    File::OpenOptions flags, uint32_t mode, +                                    Status &error) {    if (!file_spec) {      error.SetErrorString("empty path");      return UINT64_MAX;    } -  FileSP file_sp(new File()); -  error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode); -  if (!file_sp->IsValid()) +  auto file = FileSystem::Instance().Open(file_spec, flags, mode); +  if (!file) { +    error = file.takeError();      return UINT64_MAX; -  lldb::user_id_t fd = file_sp->GetDescriptor(); -  m_cache[fd] = file_sp; +  } +  lldb::user_id_t fd = file.get()->GetDescriptor(); +  m_cache[fd] = std::move(file.get());    return fd;  } @@ -48,12 +50,12 @@ bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) {      error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);      return false;    } -  FileSP file_sp = pos->second; -  if (!file_sp) { +  FileUP &file_up = pos->second; +  if (!file_up) {      error.SetErrorString("invalid host backing file");      return false;    } -  error = file_sp->Close(); +  error = file_up->Close();    m_cache.erase(pos);    return error.Success();  } @@ -70,16 +72,16 @@ uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset,      error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);      return false;    } -  FileSP file_sp = pos->second; -  if (!file_sp) { +  FileUP &file_up = pos->second; +  if (!file_up) {      error.SetErrorString("invalid host backing file");      return UINT64_MAX;    } -  if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || +  if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||        error.Fail())      return UINT64_MAX;    size_t bytes_written = src_len; -  error = file_sp->Write(src, bytes_written); +  error = file_up->Write(src, bytes_written);    if (error.Fail())      return UINT64_MAX;    return bytes_written; @@ -96,16 +98,16 @@ uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,      error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd);      return false;    } -  FileSP file_sp = pos->second; -  if (!file_sp) { +  FileUP &file_up = pos->second; +  if (!file_up) {      error.SetErrorString("invalid host backing file");      return UINT64_MAX;    } -  if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || +  if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset ||        error.Fail())      return UINT64_MAX;    size_t bytes_read = dst_len; -  error = file_sp->Read(dst, bytes_read); +  error = file_up->Read(dst, bytes_read);    if (error.Fail())      return UINT64_MAX;    return bytes_read; diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp index d5ac05bd447c..2db5bff3207f 100644 --- a/source/Host/common/FileSystem.cpp +++ b/source/Host/common/FileSystem.cpp @@ -49,7 +49,7 @@ void FileSystem::Initialize() {    InstanceImpl().emplace();  } -void FileSystem::Initialize(FileCollector &collector) { +void FileSystem::Initialize(std::shared_ptr<FileCollector> collector) {    lldbassert(!InstanceImpl() && "Already initialized.");    InstanceImpl().emplace(collector);  } @@ -280,7 +280,7 @@ std::shared_ptr<DataBufferLLVM>  FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,                               uint64_t offset) {    if (m_collector) -    m_collector->AddFile(path); +    m_collector->addFile(path);    const bool is_volatile = !IsLocal(path);    const ErrorOr<std::string> external_path = GetExternalPath(path); @@ -415,13 +415,11 @@ static mode_t GetOpenMode(uint32_t permissions) {    return mode;  } -Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options, -                        uint32_t permissions, bool should_close_fd) { +Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, +                                  File::OpenOptions options, +                                  uint32_t permissions, bool should_close_fd) {    if (m_collector) -    m_collector->AddFile(file_spec); - -  if (File.IsValid()) -    File.Close(); +    m_collector->addFile(file_spec.GetPath());    const int open_flags = GetOpenFlags(options);    const mode_t open_mode = @@ -429,20 +427,19 @@ Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options,    auto path = GetExternalPath(file_spec);    if (!path) -    return Status(path.getError()); +    return errorCodeToError(path.getError());    int descriptor = llvm::sys::RetryAfterSignal(        -1, OpenWithFS, *this, path->c_str(), open_flags, open_mode); -  Status error; -  if (!File::DescriptorIsValid(descriptor)) { -    File.SetDescriptor(descriptor, false); -    error.SetErrorToErrno(); -  } else { -    File.SetDescriptor(descriptor, should_close_fd); -    File.SetOptions(options); -  } -  return error; +  if (!File::DescriptorIsValid(descriptor)) +    return llvm::errorCodeToError( +        std::error_code(errno, std::system_category())); + +  auto file = std::unique_ptr<File>( +      new NativeFile(descriptor, options, should_close_fd)); +  assert(file->IsValid()); +  return std::move(file);  }  ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) { diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp index 3ba9ab7f21f3..8e210c7e5fa5 100644 --- a/source/Host/common/Host.cpp +++ b/source/Host/common/Host.cpp @@ -164,8 +164,7 @@ static bool CheckForMonitorCancellation() {  static thread_result_t MonitorChildProcessThreadFunction(void *arg) {    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));    const char *function = __FUNCTION__; -  if (log) -    log->Printf("%s (arg = %p) thread starting...", function, arg); +  LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg);    MonitorInfo *info = (MonitorInfo *)arg; @@ -193,9 +192,8 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {    while (1) {      log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); -    if (log) -      log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", -                  function, pid, options); +    LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", +              function, pid, options);      if (CheckForMonitorCancellation())        break; @@ -245,12 +243,12 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {  #endif          log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); -        if (log) -          log->Printf("%s ::waitpid (pid = %" PRIi32 -                      ", &status, options = %i) => pid = %" PRIi32 -                      ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", -                      function, pid, options, wait_pid, status, status_cstr, -                      signal, exit_status); +        LLDB_LOGF(log, +                  "%s ::waitpid (pid = %" PRIi32 +                  ", &status, options = %i) => pid = %" PRIi32 +                  ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", +                  function, pid, options, wait_pid, status, status_cstr, signal, +                  exit_status);          if (exited || (signal != 0 && monitor_signals)) {            bool callback_return = false; @@ -259,18 +257,18 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {            // If our process exited, then this thread should exit            if (exited && wait_pid == abs(pid)) { -            if (log) -              log->Printf("%s (arg = %p) thread exiting because pid received " -                          "exit signal...", -                          __FUNCTION__, arg); +            LLDB_LOGF(log, +                      "%s (arg = %p) thread exiting because pid received " +                      "exit signal...", +                      __FUNCTION__, arg);              break;            }            // If the callback returns true, it means this process should exit            if (callback_return) { -            if (log) -              log->Printf("%s (arg = %p) thread exiting because callback " -                          "returned true...", -                          __FUNCTION__, arg); +            LLDB_LOGF(log, +                      "%s (arg = %p) thread exiting because callback " +                      "returned true...", +                      __FUNCTION__, arg);              break;            }          } @@ -279,8 +277,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {    }    log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); -  if (log) -    log->Printf("%s (arg = %p) thread exiting...", __FUNCTION__, arg); +  LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg);    return nullptr;  } diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp index 130f0eb8ac8d..3765f36fc79a 100644 --- a/source/Host/common/HostInfoBase.cpp +++ b/source/Host/common/HostInfoBase.cpp @@ -221,25 +221,24 @@ bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec,      return false;    std::string raw_path = lldb_file_spec.GetPath(); -  if (log) -    log->Printf("HostInfo::%s() attempting to " -                "derive the path %s relative to liblldb install path: %s", -                __FUNCTION__, dir.data(), raw_path.c_str()); +  LLDB_LOGF(log, +            "HostInfo::%s() attempting to " +            "derive the path %s relative to liblldb install path: %s", +            __FUNCTION__, dir.data(), raw_path.c_str());    // Drop bin (windows) or lib    llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);    if (parent_path.empty()) { -    if (log) -      log->Printf("HostInfo::%s() failed to find liblldb within the shared " -                  "lib path", -                  __FUNCTION__); +    LLDB_LOGF(log, +              "HostInfo::%s() failed to find liblldb within the shared " +              "lib path", +              __FUNCTION__);      return false;    }    raw_path = (parent_path + dir).str(); -  if (log) -    log->Printf("HostInfo::%s() derived the path as: %s", __FUNCTION__, -                raw_path.c_str()); +  LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__, +            raw_path.c_str());    file_spec.GetDirectory().SetString(raw_path);    return (bool)file_spec.GetDirectory();  } diff --git a/source/Host/common/HostNativeThreadBase.cpp b/source/Host/common/HostNativeThreadBase.cpp index a5f876a7232a..fe7d85acaf11 100644 --- a/source/Host/common/HostNativeThreadBase.cpp +++ b/source/Host/common/HostNativeThreadBase.cpp @@ -62,8 +62,7 @@ HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) {    thread_arg_t thread_arg = info->thread_arg;    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); -  if (log) -    log->Printf("thread created"); +  LLDB_LOGF(log, "thread created");    delete info;    return thread_fptr(thread_arg); diff --git a/source/Host/common/LZMA.cpp b/source/Host/common/LZMA.cpp new file mode 100644 index 000000000000..02be8a09df66 --- /dev/null +++ b/source/Host/common/LZMA.cpp @@ -0,0 +1,146 @@ +//===-- LZMA.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +#if LLDB_ENABLE_LZMA +#include <lzma.h> +#endif // LLDB_ENABLE_LZMA + +namespace lldb_private { + +namespace lzma { + +#if !LLDB_ENABLE_LZMA +bool isAvailable() { return false; } +llvm::Expected<uint64_t> +getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) { +  llvm_unreachable("lzma::getUncompressedSize is unavailable"); +} + +llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer, +                       llvm::SmallVectorImpl<uint8_t> &Uncompressed) { +  llvm_unreachable("lzma::uncompress is unavailable"); +} + +#else // LLDB_ENABLE_LZMA + +bool isAvailable() { return true; } + +static const char *convertLZMACodeToString(lzma_ret Code) { +  switch (Code) { +  case LZMA_STREAM_END: +    return "lzma error: LZMA_STREAM_END"; +  case LZMA_NO_CHECK: +    return "lzma error: LZMA_NO_CHECK"; +  case LZMA_UNSUPPORTED_CHECK: +    return "lzma error: LZMA_UNSUPPORTED_CHECK"; +  case LZMA_GET_CHECK: +    return "lzma error: LZMA_GET_CHECK"; +  case LZMA_MEM_ERROR: +    return "lzma error: LZMA_MEM_ERROR"; +  case LZMA_MEMLIMIT_ERROR: +    return "lzma error: LZMA_MEMLIMIT_ERROR"; +  case LZMA_FORMAT_ERROR: +    return "lzma error: LZMA_FORMAT_ERROR"; +  case LZMA_OPTIONS_ERROR: +    return "lzma error: LZMA_OPTIONS_ERROR"; +  case LZMA_DATA_ERROR: +    return "lzma error: LZMA_DATA_ERROR"; +  case LZMA_BUF_ERROR: +    return "lzma error: LZMA_BUF_ERROR"; +  case LZMA_PROG_ERROR: +    return "lzma error: LZMA_PROG_ERROR"; +  default: +    llvm_unreachable("unknown or unexpected lzma status code"); +  } +} + +llvm::Expected<uint64_t> +getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) { +  lzma_stream_flags opts{}; +  if (InputBuffer.size() < LZMA_STREAM_HEADER_SIZE) { +    return llvm::createStringError( +        llvm::inconvertibleErrorCode(), +        "size of xz-compressed blob (%lu bytes) is smaller than the " +        "LZMA_STREAM_HEADER_SIZE (%lu bytes)", +        InputBuffer.size(), LZMA_STREAM_HEADER_SIZE); +  } + +  // Decode xz footer. +  lzma_ret xzerr = lzma_stream_footer_decode( +      &opts, InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE).data()); +  if (xzerr != LZMA_OK) { +    return llvm::createStringError(llvm::inconvertibleErrorCode(), +                                   "lzma_stream_footer_decode()=%s", +                                   convertLZMACodeToString(xzerr)); +  } +  if (InputBuffer.size() < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) { +    return llvm::createStringError( +        llvm::inconvertibleErrorCode(), +        "xz-compressed buffer size (%lu bytes) too small (required at " +        "least %lu bytes) ", +        InputBuffer.size(), (opts.backward_size + LZMA_STREAM_HEADER_SIZE)); +  } + +  // Decode xz index. +  lzma_index *xzindex; +  uint64_t memlimit(UINT64_MAX); +  size_t inpos = 0; +  xzerr = lzma_index_buffer_decode( +      &xzindex, &memlimit, nullptr, +      InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE + opts.backward_size) +          .data(), +      &inpos, InputBuffer.size()); +  if (xzerr != LZMA_OK) { +    return llvm::createStringError(llvm::inconvertibleErrorCode(), +                                   "lzma_index_buffer_decode()=%s", +                                   convertLZMACodeToString(xzerr)); +  } + +  // Get size of uncompressed file to construct an in-memory buffer of the +  // same size on the calling end (if needed). +  uint64_t uncompressedSize = lzma_index_uncompressed_size(xzindex); + +  // Deallocate xz index as it is no longer needed. +  lzma_index_end(xzindex, nullptr); + +  return uncompressedSize; +} + +llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer, +                       llvm::SmallVectorImpl<uint8_t> &Uncompressed) { +  llvm::Expected<uint64_t> uncompressedSize = getUncompressedSize(InputBuffer); + +  if (auto err = uncompressedSize.takeError()) +    return err; + +  Uncompressed.resize(*uncompressedSize); + +  // Decompress xz buffer to buffer. +  uint64_t memlimit = UINT64_MAX; +  size_t inpos = 0; +  size_t outpos = 0; +  lzma_ret ret = lzma_stream_buffer_decode( +      &memlimit, 0, nullptr, InputBuffer.data(), &inpos, InputBuffer.size(), +      Uncompressed.data(), &outpos, Uncompressed.size()); +  if (ret != LZMA_OK) { +    return llvm::createStringError(llvm::inconvertibleErrorCode(), +                                   "lzma_stream_buffer_decode()=%s", +                                   convertLZMACodeToString(ret)); +  } + +  return llvm::Error::success(); +} + +#endif // LLDB_ENABLE_LZMA + +} // end of namespace lzma +} // namespace lldb_private diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp index 1ce09a84671c..6f774451c8a4 100644 --- a/source/Host/common/MainLoop.cpp +++ b/source/Host/common/MainLoop.cpp @@ -320,6 +320,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {    // Even if using kqueue, the signal handler will still be invoked, so it's    // important to replace it with our "benign" handler.    int ret = sigaction(signo, &new_action, &info.old_action); +  (void)ret;    assert(ret == 0 && "sigaction failed");  #if HAVE_SYS_EVENT_H diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp index 90272cb8d0bc..fd349cc2915b 100644 --- a/source/Host/common/NativeProcessProtocol.cpp +++ b/source/Host/common/NativeProcessProtocol.cpp @@ -16,6 +16,8 @@  #include "lldb/Utility/State.h"  #include "lldb/lldb-enumerations.h" +#include "llvm/Support/Process.h" +  using namespace lldb;  using namespace lldb_private; @@ -329,22 +331,23 @@ void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged(    if (log) {      if (!m_delegates.empty()) { -      log->Printf("NativeProcessProtocol::%s: sent state notification [%s] " -                  "from process %" PRIu64, -                  __FUNCTION__, lldb_private::StateAsCString(state), GetID()); +      LLDB_LOGF(log, +                "NativeProcessProtocol::%s: sent state notification [%s] " +                "from process %" PRIu64, +                __FUNCTION__, lldb_private::StateAsCString(state), GetID());      } else { -      log->Printf("NativeProcessProtocol::%s: would send state notification " -                  "[%s] from process %" PRIu64 ", but no delegates", -                  __FUNCTION__, lldb_private::StateAsCString(state), GetID()); +      LLDB_LOGF(log, +                "NativeProcessProtocol::%s: would send state notification " +                "[%s] from process %" PRIu64 ", but no delegates", +                __FUNCTION__, lldb_private::StateAsCString(state), GetID());      }    }  }  void NativeProcessProtocol::NotifyDidExec() {    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); -  if (log) -    log->Printf("NativeProcessProtocol::%s - preparing to call delegates", -                __FUNCTION__); +  LLDB_LOGF(log, "NativeProcessProtocol::%s - preparing to call delegates", +            __FUNCTION__);    {      std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); @@ -524,6 +527,7 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {    switch (GetArchitecture().GetMachine()) {    case llvm::Triple::aarch64: +  case llvm::Triple::aarch64_32:      return llvm::makeArrayRef(g_aarch64_opcode);    case llvm::Triple::x86: @@ -560,6 +564,7 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {    case llvm::Triple::arm:    case llvm::Triple::aarch64: +  case llvm::Triple::aarch64_32:    case llvm::Triple::mips64:    case llvm::Triple::mips64el:    case llvm::Triple::mips: @@ -659,6 +664,58 @@ Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,    return Status();  } +llvm::Expected<llvm::StringRef> +NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer, +                                             size_t max_size, +                                             size_t &total_bytes_read) { +  static const size_t cache_line_size = +      llvm::sys::Process::getPageSizeEstimate(); +  size_t bytes_read = 0; +  size_t bytes_left = max_size; +  addr_t curr_addr = addr; +  size_t string_size; +  char *curr_buffer = buffer; +  total_bytes_read = 0; +  Status status; + +  while (bytes_left > 0 && status.Success()) { +    addr_t cache_line_bytes_left = +        cache_line_size - (curr_addr % cache_line_size); +    addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left); +    status = ReadMemory(curr_addr, reinterpret_cast<void *>(curr_buffer), +                        bytes_to_read, bytes_read); + +    if (bytes_read == 0) +      break; + +    void *str_end = std::memchr(curr_buffer, '\0', bytes_read); +    if (str_end != nullptr) { +      total_bytes_read = +          (size_t)(reinterpret_cast<char *>(str_end) - buffer + 1); +      status.Clear(); +      break; +    } + +    total_bytes_read += bytes_read; +    curr_buffer += bytes_read; +    curr_addr += bytes_read; +    bytes_left -= bytes_read; +  } + +  string_size = total_bytes_read - 1; + +  // Make sure we return a null terminated string. +  if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') { +    buffer[max_size - 1] = '\0'; +    total_bytes_read--; +  } + +  if (!status.Success()) +    return status.ToError(); + +  return llvm::StringRef(buffer, string_size); +} +  lldb::StateType NativeProcessProtocol::GetState() const {    std::lock_guard<std::recursive_mutex> guard(m_state_mutex);    return m_state; diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp index 2f30d52aea63..fe40073eb59d 100644 --- a/source/Host/common/NativeRegisterContext.cpp +++ b/source/Host/common/NativeRegisterContext.cpp @@ -114,16 +114,15 @@ lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) {    uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,                                                       LLDB_REGNUM_GENERIC_PC); -  if (log) -    log->Printf("NativeRegisterContext::%s using reg index %" PRIu32 -                " (default %" PRIu64 ")", -                __FUNCTION__, reg, fail_value); +  LLDB_LOGF(log, +            "NativeRegisterContext::%s using reg index %" PRIu32 +            " (default %" PRIu64 ")", +            __FUNCTION__, reg, fail_value);    const uint64_t retval = ReadRegisterAsUnsigned(reg, fail_value); -  if (log) -    log->Printf("NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, -                __FUNCTION__, retval); +  LLDB_LOGF(log, "NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, +            __FUNCTION__, retval);    return retval;  } @@ -192,20 +191,19 @@ NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,      RegisterValue value;      Status error = ReadRegister(reg_info, value);      if (error.Success()) { -      if (log) -        log->Printf("NativeRegisterContext::%s ReadRegister() succeeded, value " -                    "%" PRIu64, -                    __FUNCTION__, value.GetAsUInt64()); +      LLDB_LOGF(log, +                "NativeRegisterContext::%s ReadRegister() succeeded, value " +                "%" PRIu64, +                __FUNCTION__, value.GetAsUInt64());        return value.GetAsUInt64();      } else { -      if (log) -        log->Printf("NativeRegisterContext::%s ReadRegister() failed, error %s", -                    __FUNCTION__, error.AsCString()); +      LLDB_LOGF(log, +                "NativeRegisterContext::%s ReadRegister() failed, error %s", +                __FUNCTION__, error.AsCString());      }    } else { -    if (log) -      log->Printf("NativeRegisterContext::%s ReadRegister() null reg_info", -                  __FUNCTION__); +    LLDB_LOGF(log, "NativeRegisterContext::%s ReadRegister() null reg_info", +              __FUNCTION__);    }    return fail_value;  } diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp index a89f1178e96c..6358ab8a8e77 100644 --- a/source/Host/common/Socket.cpp +++ b/source/Host/common/Socket.cpp @@ -74,9 +74,10 @@ bool IsInterrupted() {  Socket::Socket(SocketProtocol protocol, bool should_close,                 bool child_processes_inherit) -    : IOObject(eFDTypeSocket, should_close), m_protocol(protocol), +    : IOObject(eFDTypeSocket), m_protocol(protocol),        m_socket(kInvalidSocketValue), -      m_child_processes_inherit(child_processes_inherit) {} +      m_child_processes_inherit(child_processes_inherit), +      m_should_close_fd(should_close) {}  Socket::~Socket() { Close(); } @@ -114,16 +115,16 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,    switch (protocol) {    case ProtocolTcp:      socket_up = -        llvm::make_unique<TCPSocket>(true, child_processes_inherit); +        std::make_unique<TCPSocket>(true, child_processes_inherit);      break;    case ProtocolUdp:      socket_up = -        llvm::make_unique<UDPSocket>(true, child_processes_inherit); +        std::make_unique<UDPSocket>(true, child_processes_inherit);      break;    case ProtocolUnixDomain:  #ifndef LLDB_DISABLE_POSIX      socket_up = -        llvm::make_unique<DomainSocket>(true, child_processes_inherit); +        std::make_unique<DomainSocket>(true, child_processes_inherit);  #else      error.SetErrorString(          "Unix domain sockets are not supported on this platform."); @@ -132,7 +133,7 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,    case ProtocolUnixAbstract:  #ifdef __linux__      socket_up = -        llvm::make_unique<AbstractSocket>(child_processes_inherit); +        std::make_unique<AbstractSocket>(child_processes_inherit);  #else      error.SetErrorString(          "Abstract domain sockets are not supported on this platform."); @@ -149,9 +150,8 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,  Status Socket::TcpConnect(llvm::StringRef host_and_port,                            bool child_processes_inherit, Socket *&socket) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); -  if (log) -    log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, -                host_and_port.str().c_str()); +  LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, +            host_and_port.str().c_str());    Status error;    std::unique_ptr<Socket> connect_socket( @@ -170,8 +170,7 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,                           bool child_processes_inherit, Socket *&socket,                           Predicate<uint16_t> *predicate, int backlog) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); +  LLDB_LOGF(log, "Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str());    Status error;    std::string host_str; @@ -209,9 +208,8 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,  Status Socket::UdpConnect(llvm::StringRef host_and_port,                            bool child_processes_inherit, Socket *&socket) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, -                host_and_port.str().c_str()); +  LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, +            host_and_port.str().c_str());    return UDPSocket::Connect(host_and_port, child_processes_inherit, socket);  } @@ -285,27 +283,25 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port,                                 int32_t &port, Status *error_ptr) {    static RegularExpression g_regex(        llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)")); -  RegularExpression::Match regex_match(2); -  if (g_regex.Execute(host_and_port, ®ex_match)) { -    if (regex_match.GetMatchAtIndex(host_and_port, 1, host_str) && -        regex_match.GetMatchAtIndex(host_and_port, 2, port_str)) { -      // IPv6 addresses are wrapped in [] when specified with ports -      if (host_str.front() == '[' && host_str.back() == ']') -        host_str = host_str.substr(1, host_str.size() - 2); -      bool ok = false; -      port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); -      if (ok && port <= UINT16_MAX) { -        if (error_ptr) -          error_ptr->Clear(); -        return true; -      } -      // port is too large +  llvm::SmallVector<llvm::StringRef, 3> matches; +  if (g_regex.Execute(host_and_port, &matches)) { +    host_str = matches[1].str(); +    port_str = matches[2].str(); +    // IPv6 addresses are wrapped in [] when specified with ports +    if (host_str.front() == '[' && host_str.back() == ']') +      host_str = host_str.substr(1, host_str.size() - 2); +    bool ok = false; +    port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); +    if (ok && port <= UINT16_MAX) {        if (error_ptr) -        error_ptr->SetErrorStringWithFormat( -            "invalid host:port specification: '%s'", -            host_and_port.str().c_str()); -      return false; +        error_ptr->Clear(); +      return true;      } +    // port is too large +    if (error_ptr) +      error_ptr->SetErrorStringWithFormat( +          "invalid host:port specification: '%s'", host_and_port.str().c_str()); +    return false;    }    // If this was unsuccessful, then check if it's simply a signed 32-bit @@ -345,18 +341,20 @@ Status Socket::Read(void *buf, size_t &num_bytes) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));    if (log) { -    log->Printf("%p Socket::Read() (socket = %" PRIu64 -                ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 -                " (error = %s)", -                static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, -                static_cast<uint64_t>(num_bytes), -                static_cast<int64_t>(bytes_received), error.AsCString()); +    LLDB_LOGF(log, +              "%p Socket::Read() (socket = %" PRIu64 +              ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 +              " (error = %s)", +              static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, +              static_cast<uint64_t>(num_bytes), +              static_cast<int64_t>(bytes_received), error.AsCString());    }    return error;  }  Status Socket::Write(const void *buf, size_t &num_bytes) { +  const size_t src_len = num_bytes;    Status error;    int bytes_sent = 0;    do { @@ -371,12 +369,13 @@ Status Socket::Write(const void *buf, size_t &num_bytes) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));    if (log) { -    log->Printf("%p Socket::Write() (socket = %" PRIu64 -                ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 -                " (error = %s)", -                static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, -                static_cast<uint64_t>(num_bytes), -                static_cast<int64_t>(bytes_sent), error.AsCString()); +    LLDB_LOGF(log, +              "%p Socket::Write() (socket = %" PRIu64 +              ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 +              " (error = %s)", +              static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, +              static_cast<uint64_t>(src_len), +              static_cast<int64_t>(bytes_sent), error.AsCString());    }    return error; @@ -393,9 +392,8 @@ Status Socket::Close() {      return error;    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("%p Socket::Close (fd = %" PRIu64 ")", -                static_cast<void *>(this), static_cast<uint64_t>(m_socket)); +  LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", +            static_cast<void *>(this), static_cast<uint64_t>(m_socket));  #if defined(_WIN32)    bool success = !!closesocket(m_socket); @@ -479,11 +477,11 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,    if (!child_processes_inherit) {      flags |= SOCK_CLOEXEC;    } -  NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept4, -      sockfd, addr, addrlen, flags); +  NativeSocket fd = llvm::sys::RetryAfterSignal( +      static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags);  #else -  NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept, -      sockfd, addr, addrlen); +  NativeSocket fd = llvm::sys::RetryAfterSignal( +      static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen);  #endif    if (fd == kInvalidSocketValue)      SetLastError(error); diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp index 58f99f7832fe..e84054f3f581 100644 --- a/source/Host/common/TCPSocket.cpp +++ b/source/Host/common/TCPSocket.cpp @@ -140,8 +140,7 @@ Status TCPSocket::CreateSocket(int domain) {  Status TCPSocket::Connect(llvm::StringRef name) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); -  if (log) -    log->Printf("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); +  LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data());    Status error;    std::string host_str; @@ -177,8 +176,7 @@ Status TCPSocket::Connect(llvm::StringRef name) {  Status TCPSocket::Listen(llvm::StringRef name, int backlog) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data()); +  LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data());    Status error;    std::string host_str; diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp index 8dbf57d6fe4e..7accbb651ba9 100644 --- a/source/Host/common/UDPSocket.cpp +++ b/source/Host/common/UDPSocket.cpp @@ -58,8 +58,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,    std::unique_ptr<UDPSocket> final_socket;    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); +  LLDB_LOGF(log, "UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());    Status error;    std::string host_str; @@ -81,7 +80,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,                            &service_info_list);    if (err != 0) {      error.SetErrorStringWithFormat( -#if defined(_MSC_VER) && defined(UNICODE) +#if defined(_WIN32) && defined(UNICODE)          "getaddrinfo(%s, %s, &hints, &info) returned error %i (%S)",  #else          "getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp index e28cf4aa420f..7fc6f43d4676 100644 --- a/source/Host/freebsd/HostInfoFreeBSD.cpp +++ b/source/Host/freebsd/HostInfoFreeBSD.cpp @@ -64,13 +64,10 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() {    static FileSpec g_program_filespec;    if (!g_program_filespec) {      int exe_path_mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, getpid()}; -    size_t exe_path_size; -    if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) { -      char *exe_path = new char[exe_path_size]; -      if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) -        g_program_filespec.SetFile(exe_path, FileSpec::Style::native); -      delete[] exe_path; -    } +    char exe_path[PATH_MAX]; +    size_t exe_path_size = sizeof(exe_path); +    if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) +      g_program_filespec.SetFile(exe_path, FileSpec::Style::native);    }    return g_program_filespec;  } diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp index 067e85972eca..325d854921e3 100644 --- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -79,23 +79,22 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)        m_child_processes_inherit(child_processes_inherit) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |                                                    LIBLLDB_LOG_OBJECT)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", -                static_cast<void *>(this)); +  LLDB_LOGF(log, "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", +            static_cast<void *>(this));  }  ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd)      : Connection(), m_pipe(), m_mutex(), m_shutting_down(false),        m_waiting_for_accept(false), m_child_processes_inherit(false) { -  m_write_sp = std::make_shared<File>(fd, owns_fd); -  m_read_sp = std::make_shared<File>(fd, false); +  m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, owns_fd); +  m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false);    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |                                                    LIBLLDB_LOG_OBJECT)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = " -                "%i, owns_fd = %i)", -                static_cast<void *>(this), fd, owns_fd); +  LLDB_LOGF(log, +            "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = " +            "%i, owns_fd = %i)", +            static_cast<void *>(this), fd, owns_fd);    OpenCommandPipe();  } @@ -108,9 +107,8 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket)  ConnectionFileDescriptor::~ConnectionFileDescriptor() {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION |                                                    LIBLLDB_LOG_OBJECT)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", -                static_cast<void *>(this)); +  LLDB_LOGF(log, "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", +            static_cast<void *>(this));    Disconnect(nullptr);    CloseCommandPipe();  } @@ -122,24 +120,23 @@ void ConnectionFileDescriptor::OpenCommandPipe() {    // Make the command file descriptor here:    Status result = m_pipe.CreateNew(m_child_processes_inherit);    if (!result.Success()) { -    if (log) -      log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe () - could not " -                  "make pipe: %s", -                  static_cast<void *>(this), result.AsCString()); +    LLDB_LOGF(log, +              "%p ConnectionFileDescriptor::OpenCommandPipe () - could not " +              "make pipe: %s", +              static_cast<void *>(this), result.AsCString());    } else { -    if (log) -      log->Printf("%p ConnectionFileDescriptor::OpenCommandPipe() - success " -                  "readfd=%d writefd=%d", -                  static_cast<void *>(this), m_pipe.GetReadFileDescriptor(), -                  m_pipe.GetWriteFileDescriptor()); +    LLDB_LOGF(log, +              "%p ConnectionFileDescriptor::OpenCommandPipe() - success " +              "readfd=%d writefd=%d", +              static_cast<void *>(this), m_pipe.GetReadFileDescriptor(), +              m_pipe.GetWriteFileDescriptor());    }  }  void ConnectionFileDescriptor::CloseCommandPipe() {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::CloseCommandPipe()", -                static_cast<void *>(this)); +  LLDB_LOGF(log, "%p ConnectionFileDescriptor::CloseCommandPipe()", +            static_cast<void *>(this));    m_pipe.Close();  } @@ -153,9 +150,8 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,                                                     Status *error_ptr) {    std::lock_guard<std::recursive_mutex> guard(m_mutex);    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::Connect (url = '%s')", -                static_cast<void *>(this), path.str().c_str()); +  LLDB_LOGF(log, "%p ConnectionFileDescriptor::Connect (url = '%s')", +            static_cast<void *>(this), path.str().c_str());    OpenCommandPipe(); @@ -222,8 +218,10 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,              m_read_sp = std::move(tcp_socket);              m_write_sp = m_read_sp;            } else { -            m_read_sp = std::make_shared<File>(fd, false); -            m_write_sp = std::make_shared<File>(fd, false); +            m_read_sp = +                std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false); +            m_write_sp = +                std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);            }            m_uri = *addr;            return eConnectionStatusSuccess; @@ -272,8 +270,8 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,            ::fcntl(fd, F_SETFL, flags);          }        } -      m_read_sp = std::make_shared<File>(fd, true); -      m_write_sp = std::make_shared<File>(fd, false); +      m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, true); +      m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false);        return eConnectionStatusSuccess;      }  #endif @@ -295,17 +293,15 @@ bool ConnectionFileDescriptor::InterruptRead() {  ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf("%p ConnectionFileDescriptor::Disconnect ()", -                static_cast<void *>(this)); +  LLDB_LOGF(log, "%p ConnectionFileDescriptor::Disconnect ()", +            static_cast<void *>(this));    ConnectionStatus status = eConnectionStatusSuccess;    if (!IsConnected()) { -    if (log) -      log->Printf( -          "%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", -          static_cast<void *>(this)); +    LLDB_LOGF( +        log, "%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", +        static_cast<void *>(this));      return eConnectionStatusSuccess;    } @@ -318,27 +314,28 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {    // descriptor.  If that's the case, then send the "q" char to the command    // file channel so the read will wake up and the connection will then know to    // shut down. - -  m_shutting_down = true; -    std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);    if (!locker.try_lock()) {      if (m_pipe.CanWrite()) {        size_t bytes_written = 0;        Status result = m_pipe.Write("q", 1, bytes_written); -      if (log) -        log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get " -                    "the lock, sent 'q' to %d, error = '%s'.", -                    static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(), -                    result.AsCString()); +      LLDB_LOGF(log, +                "%p ConnectionFileDescriptor::Disconnect(): Couldn't get " +                "the lock, sent 'q' to %d, error = '%s'.", +                static_cast<void *>(this), m_pipe.GetWriteFileDescriptor(), +                result.AsCString());      } else if (log) { -      log->Printf("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the " -                  "lock, but no command pipe is available.", -                  static_cast<void *>(this)); +      LLDB_LOGF(log, +                "%p ConnectionFileDescriptor::Disconnect(): Couldn't get the " +                "lock, but no command pipe is available.", +                static_cast<void *>(this));      }      locker.lock();    } +  // Prevents reads and writes during shutdown. +  m_shutting_down = true; +    Status error = m_read_sp->Close();    Status error2 = m_write_sp->Close();    if (error.Fail() || error2.Fail()) @@ -362,10 +359,10 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,    std::unique_lock<std::recursive_mutex> locker(m_mutex, std::defer_lock);    if (!locker.try_lock()) { -    if (log) -      log->Printf("%p ConnectionFileDescriptor::Read () failed to get the " -                  "connection lock.", -                  static_cast<void *>(this)); +    LLDB_LOGF(log, +              "%p ConnectionFileDescriptor::Read () failed to get the " +              "connection lock.", +              static_cast<void *>(this));      if (error_ptr)        error_ptr->SetErrorString("failed to get the connection lock for read."); @@ -374,6 +371,8 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,    }    if (m_shutting_down) { +    if (error_ptr) +      error_ptr->SetErrorString("shutting down");      status = eConnectionStatusError;      return 0;    } @@ -387,12 +386,13 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,    error = m_read_sp->Read(dst, bytes_read);    if (log) { -    log->Printf("%p ConnectionFileDescriptor::Read()  fd = %" PRIu64 -                ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", -                static_cast<void *>(this), -                static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), -                static_cast<void *>(dst), static_cast<uint64_t>(dst_len), -                static_cast<uint64_t>(bytes_read), error.AsCString()); +    LLDB_LOGF(log, +              "%p ConnectionFileDescriptor::Read()  fd = %" PRIu64 +              ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", +              static_cast<void *>(this), +              static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), +              static_cast<void *>(dst), static_cast<uint64_t>(dst_len), +              static_cast<uint64_t>(bytes_read), error.AsCString());    }    if (bytes_read == 0) { @@ -464,11 +464,11 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,                                         ConnectionStatus &status,                                         Status *error_ptr) {    Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); -  if (log) -    log->Printf( -        "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", -        static_cast<void *>(this), static_cast<const void *>(src), -        static_cast<uint64_t>(src_len)); +  LLDB_LOGF(log, +            "%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 +            ")", +            static_cast<void *>(this), static_cast<const void *>(src), +            static_cast<uint64_t>(src_len));    if (!IsConnected()) {      if (error_ptr) @@ -477,19 +477,26 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len,      return 0;    } +  if (m_shutting_down) { +    if (error_ptr) +      error_ptr->SetErrorString("shutting down"); +    status = eConnectionStatusError; +    return 0; +  } +    Status error;    size_t bytes_sent = src_len;    error = m_write_sp->Write(src, bytes_sent);    if (log) { -    log->Printf("%p ConnectionFileDescriptor::Write(fd = %" PRIu64 -                ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 -                " (error = %s)", -                static_cast<void *>(this), -                static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), -                static_cast<const void *>(src), static_cast<uint64_t>(src_len), -                static_cast<uint64_t>(bytes_sent), error.AsCString()); +    LLDB_LOGF(log, +              "%p ConnectionFileDescriptor::Write(fd = %" PRIu64 +              ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)", +              static_cast<void *>(this), +              static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), +              static_cast<const void *>(src), static_cast<uint64_t>(src_len), +              static_cast<uint64_t>(bytes_sent), error.AsCString());    }    if (error_ptr) @@ -559,7 +566,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,        select_helper.SetTimeout(*timeout);      select_helper.FDSetRead(handle); -#if defined(_MSC_VER) +#if defined(_WIN32)      // select() won't accept pipes on Windows.  The entire Windows codepath      // needs to be converted over to using WaitForMultipleObjects and event      // HANDLEs, but for now at least this will allow ::select() to not return @@ -613,10 +620,10 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,            (void)bytes_read;            switch (c) {            case 'q': -            if (log) -              log->Printf("%p ConnectionFileDescriptor::BytesAvailable() " -                          "got data: %c from the command channel.", -                          static_cast<void *>(this), c); +            LLDB_LOGF(log, +                      "%p ConnectionFileDescriptor::BytesAvailable() " +                      "got data: %c from the command channel.", +                      static_cast<void *>(this), c);              return eConnectionStatusEndOfFile;            case 'i':              // Interrupt the current read diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp index f300e22e9e5c..63cc5dc65e00 100644 --- a/source/Host/posix/HostInfoPosix.cpp +++ b/source/Host/posix/HostInfoPosix.cpp @@ -7,8 +7,8 @@  //===----------------------------------------------------------------------===//  #include "lldb/Host/posix/HostInfoPosix.h" -#include "lldb/Utility/UserIDResolver.h"  #include "lldb/Utility/Log.h" +#include "lldb/Utility/UserIDResolver.h"  #include "llvm/ADT/SmallString.h"  #include "llvm/ADT/Twine.h" @@ -18,7 +18,6 @@  #include <grp.h>  #include <limits.h>  #include <mutex> -#include <netdb.h>  #include <pwd.h>  #include <stdlib.h>  #include <sys/types.h> @@ -32,11 +31,7 @@ bool HostInfoPosix::GetHostname(std::string &s) {    char hostname[PATH_MAX];    hostname[sizeof(hostname) - 1] = '\0';    if (::gethostname(hostname, sizeof(hostname) - 1) == 0) { -    struct hostent *h = ::gethostbyname(hostname); -    if (h) -      s.assign(h->h_name); -    else -      s.assign(hostname); +    s.assign(hostname);      return true;    }    return false; @@ -57,15 +52,19 @@ protected:  };  } // namespace -llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) { +struct PasswdEntry { +  std::string username; +  std::string shell; +}; + +static llvm::Optional<PasswdEntry> GetPassword(id_t uid) {  #ifdef USE_GETPWUID    // getpwuid_r is missing from android-9 -  // UserIDResolver provides some thread safety by making sure noone calls this -  // function concurrently, but using getpwuid is ultimately not thread-safe as -  // we don't know who else might be calling it. -  struct passwd *user_info_ptr = ::getpwuid(uid); -  if (user_info_ptr) -    return std::string(user_info_ptr->pw_name); +  // The caller should provide some thread safety by making sure no one calls +  // this function concurrently, because using getpwuid is ultimately not +  // thread-safe as we don't know who else might be calling it. +  if (auto *user_info_ptr = ::getpwuid(uid)) +    return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};  #else    struct passwd user_info;    struct passwd *user_info_ptr = &user_info; @@ -74,12 +73,18 @@ llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {    if (::getpwuid_r(uid, &user_info, user_buffer, user_buffer_size,                     &user_info_ptr) == 0 &&        user_info_ptr) { -    return std::string(user_info_ptr->pw_name); +    return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};    }  #endif    return llvm::None;  } +llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) { +  if (llvm::Optional<PasswdEntry> password = GetPassword(uid)) +    return password->username; +  return llvm::None; +} +  llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {  #ifndef __ANDROID__    char group_buffer[PATH_MAX]; @@ -98,8 +103,6 @@ llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {      if (group_info_ptr)        return std::string(group_info_ptr->gr_name);    } -#else -  assert(false && "getgrgid_r() not supported on Android");  #endif    return llvm::None;  } @@ -118,7 +121,13 @@ uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); }  uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); } -FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); } +FileSpec HostInfoPosix::GetDefaultShell() { +  if (const char *v = ::getenv("SHELL")) +    return FileSpec(v); +  if (llvm::Optional<PasswdEntry> password = GetPassword(::geteuid())) +    return FileSpec(password->shell); +  return FileSpec("/bin/sh"); +}  bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {    return ComputePathRelativeToLibrary(file_spec, "/bin"); | 
