summaryrefslogtreecommitdiff
path: root/source/Host
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
commitf73363f1dd94996356cefbf24388f561891acf0b (patch)
treee3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Host
parent160ee69dd7ae18978f4068116777639ea98dc951 (diff)
Notes
Diffstat (limited to 'source/Host')
-rw-r--r--source/Host/CMakeLists.txt54
-rw-r--r--source/Host/android/HostInfoAndroid.cpp11
-rw-r--r--source/Host/common/Editline.cpp118
-rw-r--r--source/Host/common/File.cpp14
-rw-r--r--source/Host/common/Host.cpp42
-rw-r--r--source/Host/common/HostInfoBase.cpp259
-rw-r--r--source/Host/common/MainLoop.cpp21
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp52
-rw-r--r--source/Host/common/NativeBreakpointList.cpp4
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp97
-rw-r--r--source/Host/common/NativeRegisterContext.cpp14
-rw-r--r--source/Host/common/NativeThreadProtocol.cpp33
-rw-r--r--source/Host/common/PseudoTerminal.cpp101
-rw-r--r--source/Host/common/Socket.cpp24
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp17
-rw-r--r--source/Host/common/Symbols.cpp42
-rw-r--r--source/Host/common/TCPSocket.cpp4
-rw-r--r--source/Host/common/TaskPool.cpp9
-rw-r--r--source/Host/common/Terminal.cpp26
-rw-r--r--source/Host/common/UDPSocket.cpp4
-rw-r--r--source/Host/common/XML.cpp16
-rw-r--r--source/Host/freebsd/Host.cpp23
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp15
-rw-r--r--source/Host/linux/Host.cpp67
-rw-r--r--source/Host/linux/HostInfoLinux.cpp56
-rw-r--r--source/Host/macosx/Symbols.cpp184
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableDictionary.cpp20
-rw-r--r--source/Host/macosx/cfcpp/CFCString.cpp11
-rw-r--r--source/Host/macosx/objcxx/CMakeLists.txt20
-rw-r--r--source/Host/macosx/objcxx/Host.mm (renamed from source/Host/macosx/Host.mm)364
-rw-r--r--source/Host/macosx/objcxx/HostInfoMacOSX.mm (renamed from source/Host/macosx/HostInfoMacOSX.mm)97
-rw-r--r--source/Host/macosx/objcxx/HostThreadMacOSX.mm (renamed from source/Host/macosx/HostThreadMacOSX.mm)0
-rw-r--r--source/Host/netbsd/Host.cpp20
-rw-r--r--source/Host/netbsd/HostInfoNetBSD.cpp20
-rw-r--r--source/Host/openbsd/Host.cpp13
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp91
-rw-r--r--source/Host/posix/FileSystem.cpp7
-rw-r--r--source/Host/posix/HostInfoPosix.cpp64
-rw-r--r--source/Host/posix/HostThreadPosix.cpp5
-rw-r--r--source/Host/posix/PipePosix.cpp14
-rw-r--r--source/Host/posix/ProcessLauncherPosixFork.cpp54
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp44
-rw-r--r--source/Host/windows/EditLineWin.cpp8
-rw-r--r--source/Host/windows/FileSystem.cpp2
-rw-r--r--source/Host/windows/Host.cpp36
-rw-r--r--source/Host/windows/HostInfoWindows.cpp51
-rw-r--r--source/Host/windows/HostProcessWindows.cpp6
-rw-r--r--source/Host/windows/PipeWindows.cpp27
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp21
49 files changed, 858 insertions, 1444 deletions
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index 2b6f0e48a3f20..5a92447edf308 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -3,6 +3,18 @@ macro(add_host_subdirectory group)
source_group(${group} FILES ${ARGN})
endmacro()
+# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for
+# the Objective-C++ code in lldb which we don't want to build with modules.
+# Reasons for this are that modules with Objective-C++ would require that
+# all LLVM/Clang modules are Objective-C++ compatible (which they are likely
+# not) and we would have rebuild a second set of modules just for the few
+# Objective-C++ files in lldb (which slows down the build process).
+macro(remove_module_flags)
+ string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+endmacro()
+
add_host_subdirectory(common
common/File.cpp
common/FileCache.cpp
@@ -39,11 +51,6 @@ add_host_subdirectory(common
common/UDPSocket.cpp
)
-# Keep track of whether we want to provide a define for the
-# Python's architecture-specific lib path (i.e. where a
-# Python lldb module would go).
-set (get_python_libdir 0)
-
if (NOT LLDB_DISABLE_LIBEDIT)
add_host_subdirectory(common
common/Editline.cpp
@@ -54,10 +61,6 @@ add_host_subdirectory(posix
posix/ConnectionFileDescriptorPosix.cpp
)
-if(NOT LLDB_DISABLE_PYTHON)
- list(APPEND LLDB_PLUGINS lldbPluginScriptInterpreterPython)
-endif()
-
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_host_subdirectory(windows
windows/ConnectionGenericFileWindows.cpp
@@ -74,11 +77,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
windows/Windows.cpp
)
else()
- if (NOT LLDB_DISABLE_PYTHON)
- # We'll grab the arch-specific python libdir on POSIX systems.
- set (get_python_libdir 1)
- endif()
-
add_host_subdirectory(posix
posix/DomainSocket.cpp
posix/FileSystem.cpp
@@ -92,10 +90,9 @@ else()
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
- add_host_subdirectory(macosx
- macosx/Host.mm
- macosx/HostInfoMacOSX.mm
- macosx/HostThreadMacOSX.mm
+ add_subdirectory(macosx/objcxx)
+ set(LLDBObjCLibs lldbHostMacOSXObjCXX)
+ add_host_subdirectory(maqcosx
macosx/Symbols.cpp
macosx/cfcpp/CFCBundle.cpp
macosx/cfcpp/CFCData.cpp
@@ -144,19 +141,6 @@ else()
endif()
endif()
-if (${get_python_libdir})
- # Call a python script to gather the arch-specific libdir for
- # modules like the lldb module.
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../scripts/get_relative_lib_dir.py
- RESULT_VARIABLE get_libdir_status
- OUTPUT_VARIABLE relative_libdir
- )
- if (get_libdir_status EQUAL 0)
- add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}")
- endif()
-endif()
-
set(EXTRA_LIBS)
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
list(APPEND EXTRA_LIBS kvm)
@@ -177,16 +161,16 @@ endif()
add_lldb_library(lldbHost
${HOST_SOURCES}
-
+
LINK_LIBS
lldbCore
- lldbInterpreter
lldbSymbol
lldbTarget
lldbUtility
- ${LLDB_PLUGINS}
${EXTRA_LIBS}
-
+ ${LLDBObjCLibs}
+
LINK_COMPONENTS
+ Object
Support
)
diff --git a/source/Host/android/HostInfoAndroid.cpp b/source/Host/android/HostInfoAndroid.cpp
index 27ce17a76d70c..a960332832126 100644
--- a/source/Host/android/HostInfoAndroid.cpp
+++ b/source/Host/android/HostInfoAndroid.cpp
@@ -79,13 +79,10 @@ bool HostInfoAndroid::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
bool success = HostInfoLinux::ComputeTempFileBaseDirectory(file_spec);
// On Android, there is no path which is guaranteed to be writable. If the
- // user has not
- // provided a path via an environment variable, the generic algorithm will
- // deduce /tmp, which
- // is plain wrong. In that case we have an invalid directory, we substitute
- // the path with
- // /data/local/tmp, which is correct at least in some cases (i.e., when
- // running as shell user).
+ // user has not provided a path via an environment variable, the generic
+ // algorithm will deduce /tmp, which is plain wrong. In that case we have an
+ // invalid directory, we substitute the path with /data/local/tmp, which is
+ // correct at least in some cases (i.e., when running as shell user).
if (!success || !file_spec.Exists())
file_spec = FileSpec("/data/local/tmp", false);
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index 7b580dde656ac..329c0c1f3b707 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -33,8 +33,8 @@ using namespace lldb_private::line_editor;
// doesn't explicitly initialize the curses termcap library, which it gets away
// with until TERM is set to VT100 where it stumbles over an implementation
// assumption that may not exist on other platforms. The setupterm() function
-// would normally require headers that don't work gracefully in this context, so
-// the function declaraction has been hoisted here.
+// would normally require headers that don't work gracefully in this context,
+// so the function declaraction has been hoisted here.
#if defined(__APPLE__)
extern "C" {
int setupterm(char *term, int fildes, int *errret);
@@ -43,12 +43,10 @@ int setupterm(char *term, int fildes, int *errret);
#endif
// Editline uses careful cursor management to achieve the illusion of editing a
-// multi-line block of text
-// with a single line editor. Preserving this illusion requires fairly careful
-// management of cursor
-// state. Read and understand the relationship between DisplayInput(),
-// MoveCursor(), SetCurrentLine(),
-// and SaveEditedLine() before making changes.
+// multi-line block of text with a single line editor. Preserving this
+// illusion requires fairly careful management of cursor state. Read and
+// understand the relationship between DisplayInput(), MoveCursor(),
+// SetCurrentLine(), and SaveEditedLine() before making changes.
#define ESCAPE "\x1b"
#define ANSI_FAINT ESCAPE "[2m"
@@ -70,8 +68,7 @@ int setupterm(char *term, int fildes, int *errret);
#define EditLineStringFormatSpec "%s"
// use #defines so wide version functions and structs will resolve to old
-// versions
-// for case of libedit not built with wide char support
+// versions for case of libedit not built with wide char support
#define history_w history
#define history_winit history_init
#define history_wend history_end
@@ -145,10 +142,8 @@ bool IsInputPending(FILE *file) {
// FIXME: This will be broken on Windows if we ever re-enable Editline. You
// can't use select
// on something that isn't a socket. This will have to be re-written to not
- // use a FILE*, but
- // instead use some kind of yet-to-be-created abstraction that select-like
- // functionality on
- // non-socket objects.
+ // use a FILE*, but instead use some kind of yet-to-be-created abstraction
+ // that select-like functionality on non-socket objects.
const int fd = fileno(file);
SelectHelper select_helper;
select_helper.SetTimeout(std::chrono::microseconds(0));
@@ -160,13 +155,13 @@ namespace lldb_private {
namespace line_editor {
typedef std::weak_ptr<EditlineHistory> EditlineHistoryWP;
-// EditlineHistory objects are sometimes shared between multiple
-// Editline instances with the same program name.
+// EditlineHistory objects are sometimes shared between multiple Editline
+// instances with the same program name.
class EditlineHistory {
private:
- // Use static GetHistory() function to get a EditlineHistorySP to one of these
- // objects
+ // Use static GetHistory() function to get a EditlineHistorySP to one of
+ // these objects
EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries)
: m_history(NULL), m_event(), m_prefix(prefix), m_path() {
m_history = history_winit();
@@ -436,11 +431,10 @@ unsigned char Editline::RecallHistory(bool earlier) {
if (history_w(pHistory, &history_event, H_FIRST) == -1)
return CC_ERROR;
- // Save any edits to the "live" entry in case we return by moving forward in
- // history
- // (it would be more bash-like to save over any current entry, but libedit
- // doesn't
- // offer the ability to add entries anywhere except the end.)
+ // Save any edits to the "live" entry in case we return by moving forward
+ // in history (it would be more bash-like to save over any current entry,
+ // but libedit doesn't offer the ability to add entries anywhere except the
+ // end.)
SaveEditedLine();
m_live_history_lines = m_input_lines;
m_in_history = true;
@@ -466,8 +460,7 @@ unsigned char Editline::RecallHistory(bool earlier) {
DisplayInput();
// Prepare to edit the last line when moving to previous entry, or the first
- // line
- // when moving to next entry
+ // line when moving to next entry
SetCurrentLine(m_current_line_index =
earlier ? (int)m_input_lines.size() - 1 : 0);
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
@@ -490,8 +483,8 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
}
if (m_multiline_enabled) {
- // Detect when the number of rows used for this input line changes due to an
- // edit
+ // Detect when the number of rows used for this input line changes due to
+ // an edit
int lineLength = (int)((info->lastchar - info->buffer) + GetPromptWidth());
int new_line_rows = (lineLength / m_terminal_width) + 1;
if (m_current_line_rows != -1 && new_line_rows != m_current_line_rows) {
@@ -510,12 +503,10 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
char ch = 0;
// This mutex is locked by our caller (GetLine). Unlock it while we read a
- // character
- // (blocking operation), so we do not hold the mutex indefinitely. This
- // gives a chance
- // for someone to interrupt us. After Read returns, immediately lock the
- // mutex again and
- // check if we were interrupted.
+ // character (blocking operation), so we do not hold the mutex
+ // indefinitely. This gives a chance for someone to interrupt us. After
+ // Read returns, immediately lock the mutex again and check if we were
+ // interrupted.
m_output_mutex.unlock();
int read_count = m_input_connection.Read(&ch, 1, llvm::None, status, NULL);
m_output_mutex.lock();
@@ -614,7 +605,8 @@ unsigned char Editline::EndOrAddLineCommand(int ch) {
// Save any edits to this line
SaveEditedLine();
- // If this is the end of the last line, consider whether to add a line instead
+ // If this is the end of the last line, consider whether to add a line
+ // instead
const LineInfoW *info = el_wline(m_editline);
if (m_current_line_index == m_input_lines.size() - 1 &&
info->cursor == info->lastchar) {
@@ -653,8 +645,8 @@ unsigned char Editline::DeleteNextCharCommand(int ch) {
return CC_REFRESH;
}
- // Fail when at the end of the last line, except when ^D is pressed on
- // the line is empty, in which case it is treated as EOF
+ // Fail when at the end of the last line, except when ^D is pressed on the
+ // line is empty, in which case it is treated as EOF
if (m_current_line_index == m_input_lines.size() - 1) {
if (ch == 4 && info->buffer == info->lastchar) {
fprintf(m_output_file, "^D\n");
@@ -685,7 +677,8 @@ unsigned char Editline::DeleteNextCharCommand(int ch) {
unsigned char Editline::DeletePreviousCharCommand(int ch) {
LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
- // Just delete the previous character normally when not at the start of a line
+ // Just delete the previous character normally when not at the start of a
+ // line
if (info->cursor > info->buffer) {
el_deletestr(m_editline, 1);
return CC_REFRESH;
@@ -709,8 +702,7 @@ unsigned char Editline::DeletePreviousCharCommand(int ch) {
DisplayInput(m_current_line_index);
// Put the cursor back where libedit expects it to be before returning to
- // editing
- // by telling libedit about the newly inserted text
+ // editing by telling libedit about the newly inserted text
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
el_winsertstr(m_editline, priorLine.c_str());
return CC_REDISPLAY;
@@ -762,7 +754,8 @@ unsigned char Editline::NextLineCommand(int ch) {
EditLineStringType(indentation, EditLineCharType(' ')));
}
- // Move down past the current line using newlines to force scrolling if needed
+ // Move down past the current line using newlines to force scrolling if
+ // needed
SetCurrentLine(m_current_line_index + 1);
const LineInfoW *info = el_wline(m_editline);
int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth());
@@ -824,8 +817,7 @@ unsigned char Editline::FixIndentationCommand(int ch) {
DisplayInput(m_current_line_index);
// Reposition the cursor back on the original line and prepare to restart
- // editing
- // with a new cursor position
+ // editing with a new cursor position
SetCurrentLine(m_current_line_index);
MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
m_revert_cursor_index = cursor_position + indent_correction;
@@ -945,9 +937,9 @@ void Editline::ConfigureEditor(bool multiline) {
m_multiline_enabled = multiline;
if (m_editline) {
- // Disable edit mode to stop the terminal from flushing all input
- // during the call to el_end() since we expect to have multiple editline
- // instances in this program.
+ // Disable edit mode to stop the terminal from flushing all input during
+ // the call to el_end() since we expect to have multiple editline instances
+ // in this program.
el_set(m_editline, EL_EDITMODE, 0);
el_end(m_editline);
}
@@ -973,7 +965,8 @@ void Editline::ConfigureEditor(bool multiline) {
return Editline::InstanceFor(editline)->GetCharacter(c);
}));
- // Commands used for multiline support, registered whether or not they're used
+ // Commands used for multiline support, registered whether or not they're
+ // used
el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"),
EditLineConstString("Insert a line break"),
(EditlineCommandCallbackType)([](EditLine *editline, int ch) {
@@ -1031,13 +1024,11 @@ void Editline::ConfigureEditor(bool multiline) {
return Editline::InstanceFor(editline)->FixIndentationCommand(ch);
}));
- // Register the complete callback under two names for compatibility with older
- // clients using
- // custom .editrc files (largely because libedit has a bad bug where if you
- // have a bind command
- // that tries to bind to a function name that doesn't exist, it can corrupt
- // the heap and
- // crash your process later.)
+ // Register the complete callback under two names for compatibility with
+ // older clients using custom .editrc files (largely because libedit has a
+ // bad bug where if you have a bind command that tries to bind to a function
+ // name that doesn't exist, it can corrupt the heap and crash your process
+ // later.)
EditlineCommandCallbackType complete_callback = [](EditLine *editline,
int ch) {
return Editline::InstanceFor(editline)->TabCommand(ch);
@@ -1118,8 +1109,7 @@ void Editline::ConfigureEditor(bool multiline) {
NULL);
// Escape is absorbed exiting edit mode, so re-register important
- // sequences
- // without the prefix
+ // sequences without the prefix
el_set(m_editline, EL_BIND, "-a", "[A", "lldb-previous-line", NULL);
el_set(m_editline, EL_BIND, "-a", "[B", "lldb-next-line", NULL);
el_set(m_editline, EL_BIND, "-a", "[\\^", "lldb-revert-line", NULL);
@@ -1176,18 +1166,18 @@ Editline::Editline(const char *editline_name, FILE *input_file,
Editline::~Editline() {
if (m_editline) {
- // Disable edit mode to stop the terminal from flushing all input
- // during the call to el_end() since we expect to have multiple editline
- // instances in this program.
+ // Disable edit mode to stop the terminal from flushing all input during
+ // the call to el_end() since we expect to have multiple editline instances
+ // in this program.
el_set(m_editline, EL_EDITMODE, 0);
el_end(m_editline);
m_editline = nullptr;
}
- // EditlineHistory objects are sometimes shared between multiple
- // Editline instances with the same program name. So just release
- // our shared pointer and if we are the last owner, it will save the
- // history to the history save file automatically.
+ // EditlineHistory objects are sometimes shared between multiple Editline
+ // instances with the same program name. So just release our shared pointer
+ // and if we are the last owner, it will save the history to the history save
+ // file automatically.
m_history_sp.reset();
}
@@ -1313,8 +1303,8 @@ bool Editline::GetLines(int first_line_number, StringList &lines,
bool &interrupted) {
ConfigureEditor(true);
- // Print the initial input lines, then move the cursor back up to the start of
- // input
+ // Print the initial input lines, then move the cursor back up to the start
+ // of input
SetBaseLineNumber(first_line_number);
m_input_lines = std::vector<EditLineStringType>();
m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 6ee4e894756b7..3c3d55df22079 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -100,7 +100,7 @@ int File::GetDescriptor() const {
// Don't open the file descriptor if we don't need to, just get it from the
// stream if we have one.
if (StreamIsValid()) {
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
return _fileno(m_stream);
#else
return fileno(m_stream);
@@ -126,8 +126,8 @@ FILE *File::GetStream() {
const char *mode = GetStreamOpenModeFromOptions(m_options);
if (mode) {
if (!m_should_close_fd) {
-// We must duplicate the file descriptor if we don't own it because
-// when you call fdopen, the stream will own the fd
+// 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
m_descriptor = ::_dup(GetDescriptor());
#else
@@ -139,8 +139,8 @@ FILE *File::GetStream() {
m_stream =
llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
- // 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 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;
@@ -315,7 +315,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
error.SetErrorToErrno();
else
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
} else {
error.SetErrorString("invalid file handle");
}
@@ -330,7 +330,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
error.SetErrorToErrno();
else {
path[len] = '\0';
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
}
}
#else
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 97581185ad9e6..d2848254779e8 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -59,7 +59,6 @@
#include "lldb/Target/FileAction.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -120,9 +119,8 @@ HostThread Host::StartMonitoringChildProcess(
#ifndef __linux__
//------------------------------------------------------------------
-// Scoped class that will disable thread canceling when it is
-// constructed, and exception safely restore the previous value it
-// when it goes out of scope.
+// Scoped class that will disable thread canceling when it is constructed, and
+// exception safely restore the previous value it when it goes out of scope.
//------------------------------------------------------------------
class ScopedPThreadCancelDisabler {
public:
@@ -271,8 +269,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
__FUNCTION__, arg);
break;
}
- // If the callback returns true, it means this process should
- // exit
+ // 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 "
@@ -423,7 +420,7 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
Dl_info info;
if (::dladdr(host_addr, &info)) {
if (info.dli_fname)
- module_filespec.SetFile(info.dli_fname, true);
+ module_filespec.SetFile(info.dli_fname, true, FileSpec::Style::native);
}
#endif
return module_filespec;
@@ -466,15 +463,17 @@ MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
- uint32_t timeout_sec, bool run_in_default_shell) {
+ const Timeout<std::micro> &timeout,
+ bool run_in_default_shell) {
return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
- command_output_ptr, timeout_sec, run_in_default_shell);
+ command_output_ptr, timeout, run_in_default_shell);
}
Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
- uint32_t timeout_sec, bool run_in_default_shell) {
+ const Timeout<std::micro> &timeout,
+ bool run_in_default_shell) {
Status error;
ProcessLaunchInfo launch_info;
launch_info.SetArchitecture(HostInfo::GetArchitecture());
@@ -498,11 +497,10 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
llvm::SmallString<PATH_MAX> output_file_path;
if (command_output_ptr) {
- // Create a temporary file to get the stdout/stderr and redirect the
- // output of the command into this file. We will later read this file
- // if all goes well and fill the data into "command_output_ptr"
- FileSpec tmpdir_file_spec;
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
+ // Create a temporary file to get the stdout/stderr and redirect the output
+ // of the command into this file. We will later read this file if all goes
+ // well and fill the data into "command_output_ptr"
+ if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
output_file_path);
@@ -539,18 +537,14 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
error.SetErrorString("failed to get process ID");
if (error.Success()) {
- bool timed_out = false;
- shell_info_sp->process_reaped.WaitForValueEqualTo(
- true, std::chrono::seconds(timeout_sec), &timed_out);
- if (timed_out) {
+ if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) {
error.SetErrorString("timed out waiting for shell command to complete");
// Kill the process since it didn't complete within the timeout specified
Kill(pid, SIGKILL);
// Wait for the monitor callback to get the message
- timed_out = false;
shell_info_sp->process_reaped.WaitForValueEqualTo(
- true, std::chrono::seconds(1), &timed_out);
+ true, std::chrono::seconds(1));
} else {
if (status_ptr)
*status_ptr = shell_info_sp->status;
@@ -581,7 +575,8 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
return error;
}
-// The functions below implement process launching for non-Apple-based platforms
+// The functions below implement process launching for non-Apple-based
+// platforms
#if !defined(__APPLE__)
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
std::unique_ptr<ProcessLauncher> delegate_launcher;
@@ -596,8 +591,7 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
HostProcess process = launcher.LaunchProcess(launch_info, error);
// TODO(zturner): It would be better if the entire HostProcess were returned
- // instead of writing
- // it into this structure.
+ // instead of writing it into this structure.
launch_info.SetProcessID(process.GetProcessId());
return error;
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index aff887f9f1d2e..4de6953a91e35 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -33,19 +33,19 @@ using namespace lldb_private;
namespace {
//----------------------------------------------------------------------
-// The HostInfoBaseFields is a work around for windows not supporting
-// static variables correctly in a thread safe way. Really each of the
-// variables in HostInfoBaseFields should live in the functions in which
-// they are used and each one should be static, but the work around is
-// in place to avoid this restriction. Ick.
+// The HostInfoBaseFields is a work around for windows not supporting static
+// variables correctly in a thread safe way. Really each of the variables in
+// HostInfoBaseFields should live in the functions in which they are used and
+// each one should be static, but the work around is in place to avoid this
+// restriction. Ick.
//----------------------------------------------------------------------
struct HostInfoBaseFields {
~HostInfoBaseFields() {
if (m_lldb_process_tmp_dir.Exists()) {
// Remove the LLDB temporary directory if we have one. Set "recurse" to
- // true to all files that were created for the LLDB process can be cleaned
- // up.
+ // true to all files that were created for the LLDB process can be
+ // cleaned up.
llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath());
}
}
@@ -58,7 +58,6 @@ struct HostInfoBaseFields {
FileSpec m_lldb_so_dir;
FileSpec m_lldb_support_exe_dir;
FileSpec m_lldb_headers_dir;
- FileSpec m_lldb_python_dir;
FileSpec m_lldb_clang_resource_dir;
FileSpec m_lldb_system_plugin_dir;
FileSpec m_lldb_user_plugin_dir;
@@ -111,152 +110,88 @@ llvm::Optional<HostInfoBase::ArchitectureKind> HostInfoBase::ParseArchitectureKi
.Default(llvm::None);
}
-bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
- file_spec.Clear();
+FileSpec HostInfoBase::GetShlibDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
+ });
+ return success ? g_fields->m_lldb_so_dir : FileSpec();
+}
-#if defined(LLDB_DISABLE_PYTHON)
- if (type == lldb::ePathTypePythonDir)
- return false;
-#endif
+FileSpec HostInfoBase::GetSupportExeDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success =
+ HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);
+ });
+ return success ? g_fields->m_lldb_support_exe_dir : FileSpec();
+}
- FileSpec *result = nullptr;
- switch (type) {
- case lldb::ePathTypeLLDBShlibDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success =
- HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'",
- g_fields->m_lldb_so_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_so_dir;
- } break;
- case lldb::ePathTypeSupportExecutableDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeSupportExeDirectory(
- g_fields->m_lldb_support_exe_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
- g_fields->m_lldb_support_exe_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_support_exe_dir;
- } break;
- case lldb::ePathTypeHeaderDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'",
- g_fields->m_lldb_headers_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_headers_dir;
- } break;
- case lldb::ePathTypePythonDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputePythonDirectory(g_fields->m_lldb_python_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'",
- g_fields->m_lldb_python_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_python_dir;
- } break;
- case lldb::ePathTypeClangDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success =
- HostInfo::ComputeClangDirectory(g_fields->m_lldb_clang_resource_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'",
- g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_clang_resource_dir;
- } break;
- case lldb::ePathTypeLLDBSystemPlugins: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeSystemPluginsDirectory(
- g_fields->m_lldb_system_plugin_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
- g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_system_plugin_dir;
- } break;
- case lldb::ePathTypeLLDBUserPlugins: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeUserPluginsDirectory(
- g_fields->m_lldb_user_plugin_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
- g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_user_plugin_dir;
- } break;
- case lldb::ePathTypeLLDBTempSystemDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeProcessTempFileDirectory(
- g_fields->m_lldb_process_tmp_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf(
- "HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'",
- g_fields->m_lldb_process_tmp_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_process_tmp_dir;
- } break;
- case lldb::ePathTypeGlobalLLDBTempSystemDir: {
- static llvm::once_flag g_once_flag;
- static bool success = false;
- llvm::call_once(g_once_flag, []() {
- success = HostInfo::ComputeGlobalTempFileDirectory(
- g_fields->m_lldb_global_tmp_dir);
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoBase::GetLLDBPath("
- "ePathTypeGlobalLLDBTempSystemDir) => '%s'",
- g_fields->m_lldb_global_tmp_dir.GetPath().c_str());
- });
- if (success)
- result = &g_fields->m_lldb_global_tmp_dir;
- } break;
- }
+FileSpec HostInfoBase::GetHeaderDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);
+ });
+ return success ? g_fields->m_lldb_headers_dir : FileSpec();
+}
- if (!result)
- return false;
- file_spec = *result;
- return true;
+FileSpec HostInfoBase::GetSystemPluginDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeSystemPluginsDirectory(
+ g_fields->m_lldb_system_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "system plugin dir -> `{0}`",
+ g_fields->m_lldb_system_plugin_dir);
+ });
+ return success ? g_fields->m_lldb_system_plugin_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetUserPluginDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success =
+ HostInfo::ComputeUserPluginsDirectory(g_fields->m_lldb_user_plugin_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);
+ });
+ return success ? g_fields->m_lldb_user_plugin_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetProcessTempDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeProcessTempFileDirectory(
+ g_fields->m_lldb_process_tmp_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "process temp dir -> `{0}`",
+ g_fields->m_lldb_process_tmp_dir);
+ });
+ return success ? g_fields->m_lldb_process_tmp_dir : FileSpec();
+}
+
+FileSpec HostInfoBase::GetGlobalTempDir() {
+ static llvm::once_flag g_once_flag;
+ static bool success = false;
+ llvm::call_once(g_once_flag, []() {
+ success = HostInfo::ComputeGlobalTempFileDirectory(
+ g_fields->m_lldb_global_tmp_dir);
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);
+ });
+ return success ? g_fields->m_lldb_global_tmp_dir : FileSpec();
}
ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
@@ -282,14 +217,12 @@ ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
// To get paths related to LLDB we get the path to the executable that
- // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
- // on linux this is assumed to be the "lldb" main executable. If LLDB on
- // linux is actually in a shared library (liblldb.so) then this function will
- // need to be modified to "do the right thing".
+ // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
+ // On other posix systems, we will get .../lib(64|32)?/liblldb.so.
- FileSpec lldb_file_spec(
- Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(
- reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));
+ FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(
+ reinterpret_cast<void *>(reinterpret_cast<intptr_t>(
+ HostInfoBase::ComputeSharedLibraryDirectory))));
// This is necessary because when running the testsuite the shlib might be a
// symbolic link inside the Python resource dir.
@@ -302,7 +235,8 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
}
bool HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) {
- return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
+ file_spec = GetShlibDir();
+ return bool(file_spec);
}
bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {
@@ -353,11 +287,9 @@ bool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
return false;
}
-bool HostInfoBase::ComputeClangDirectory(FileSpec &file_spec) { return false; }
-
bool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) {
- // TODO(zturner): Figure out how to compute the user plugins directory for all
- // platforms.
+ // TODO(zturner): Figure out how to compute the user plugins directory for
+ // all platforms.
return false;
}
@@ -375,6 +307,7 @@ void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32,
case llvm::Triple::aarch64:
case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
case llvm::Triple::x86_64:
arch_64.SetTriple(triple);
arch_32.SetTriple(triple.get32BitArchVariant());
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 6cbb5a8425623..65158c942934f 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -26,7 +26,7 @@
#if HAVE_SYS_EVENT_H
#include <sys/event.h>
-#elif defined(LLVM_ON_WIN32)
+#elif defined(_WIN32)
#include <winsock2.h>
#elif defined(__ANDROID__)
#include <sys/syscall.h>
@@ -34,14 +34,14 @@
#include <poll.h>
#endif
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
#define POLL WSAPoll
#else
#define POLL poll
#endif
#if SIGNAL_POLLING_UNSUPPORTED
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
typedef int sigset_t;
typedef int siginfo_t;
#endif
@@ -209,8 +209,8 @@ Status MainLoop::RunImpl::Poll() {
void MainLoop::RunImpl::ProcessEvents() {
#ifdef __ANDROID__
- // Collect first all readable file descriptors into a separate vector and then
- // iterate over it to invoke callbacks. Iterating directly over
+ // Collect first all readable file descriptors into a separate vector and
+ // then iterate over it to invoke callbacks. Iterating directly over
// loop.m_read_fds is not possible because the callbacks can modify the
// container which could invalidate the iterator.
std::vector<IOObject::WaitableHandle> fds;
@@ -262,7 +262,7 @@ MainLoop::~MainLoop() {
MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
const Callback &callback,
Status &error) {
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) {
error.SetErrorString("MainLoop: non-socket types unsupported on Windows");
return nullptr;
@@ -285,8 +285,7 @@ MainLoop::ReadHandleUP MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
}
// We shall block the signal, then install the signal handler. The signal will
-// be unblocked in
-// the Run() function to check for signal delivery.
+// be unblocked in the Run() function to check for signal delivery.
MainLoop::SignalHandleUP
MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
#ifdef SIGNAL_POLLING_UNSUPPORTED
@@ -321,9 +320,9 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
assert(ret == 0);
#endif
- // If we're using kqueue, the signal needs to be unblocked in order to recieve
- // it. If using pselect/ppoll, we need to block it, and later unblock it as a
- // part of the system call.
+ // If we're using kqueue, the signal needs to be unblocked in order to
+ // recieve it. If using pselect/ppoll, we need to block it, and later unblock
+ // it as a part of the system call.
ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
&new_action.sa_mask, &old_set);
assert(ret == 0 && "pthread_sigmask failed");
diff --git a/source/Host/common/MonitoringProcessLauncher.cpp b/source/Host/common/MonitoringProcessLauncher.cpp
index f1fcd0b44c150..76c11454f573c 100644
--- a/source/Host/common/MonitoringProcessLauncher.cpp
+++ b/source/Host/common/MonitoringProcessLauncher.cpp
@@ -8,11 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/Platform.h"
-#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
@@ -32,36 +28,23 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
ProcessLaunchInfo resolved_info(launch_info);
error.Clear();
- char exe_path[PATH_MAX];
-
- PlatformSP host_platform_sp(Platform::GetHostPlatform());
-
- const ArchSpec &arch_spec = resolved_info.GetArchitecture();
FileSpec exe_spec(resolved_info.GetExecutableFile());
llvm::sys::fs::file_status stats;
status(exe_spec.GetPath(), stats);
- if (!is_regular_file(stats)) {
- ModuleSpec module_spec(exe_spec, arch_spec);
- lldb::ModuleSP exe_module_sp;
- error =
- host_platform_sp->ResolveExecutable(module_spec, exe_module_sp, NULL);
-
- if (error.Fail())
- return HostProcess();
-
- if (exe_module_sp) {
- exe_spec = exe_module_sp->GetFileSpec();
- status(exe_spec.GetPath(), stats);
- }
+ if (!exists(stats)) {
+ exe_spec.ResolvePath();
+ status(exe_spec.GetPath(), stats);
+ }
+ if (!exists(stats)) {
+ exe_spec.ResolveExecutableLocation();
+ status(exe_spec.GetPath(), stats);
}
- if (exists(stats)) {
- exe_spec.GetPath(exe_path, sizeof(exe_path));
- } else {
- resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
+ if (!exists(stats)) {
+ error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
+ exe_spec);
return HostProcess();
}
@@ -74,18 +57,9 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- Host::MonitorChildProcessCallback callback =
- launch_info.GetMonitorProcessCallback();
-
- bool monitor_signals = false;
- if (callback) {
- // If the ProcessLaunchInfo specified a callback, use that.
- monitor_signals = launch_info.GetMonitorSignals();
- } else {
- callback = Process::SetProcessExitStatus;
- }
-
- process.StartMonitoring(callback, monitor_signals);
+ assert(launch_info.GetMonitorProcessCallback());
+ process.StartMonitoring(launch_info.GetMonitorProcessCallback(),
+ launch_info.GetMonitorSignals());
if (log)
log->PutCString("started monitoring child process.");
} else {
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
index ce5eb94a8d1fb..cfcbe0831064b 100644
--- a/source/Host/common/NativeBreakpointList.cpp
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -104,8 +104,8 @@ Status NativeBreakpointList::DecRef(lldb::addr_t addr) {
return error;
}
- // Breakpoint has no more references. Disable it if it's not
- // already disabled.
+ // Breakpoint has no more references. Disable it if it's not already
+ // disabled.
if (log)
log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
" -- removing due to no remaining references",
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 1fcb11b8b6f5d..3e8648f814739 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -8,14 +8,11 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/Host/common/SoftwareBreakpoint.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
@@ -139,29 +136,28 @@ NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags,
bool hardware) {
- // This default implementation assumes setting the watchpoint for
- // the process will require setting the watchpoint for each of the
- // threads. Furthermore, it will track watchpoints set for the
- // process and will add them to each thread that is attached to
- // via the (FIXME implement) OnThreadAttached () method.
+ // This default implementation assumes setting the watchpoint for the process
+ // will require setting the watchpoint for each of the threads. Furthermore,
+ // it will track watchpoints set for the process and will add them to each
+ // thread that is attached to via the (FIXME implement) OnThreadAttached ()
+ // method.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// Update the thread list
UpdateThreads();
- // Keep track of the threads we successfully set the watchpoint
- // for. If one of the thread watchpoint setting operations fails,
- // back off and remove the watchpoint for all the threads that
- // were successfully set so we get back to a consistent state.
+ // Keep track of the threads we successfully set the watchpoint for. If one
+ // of the thread watchpoint setting operations fails, back off and remove the
+ // watchpoint for all the threads that were successfully set so we get back
+ // to a consistent state.
std::vector<NativeThreadProtocol *> watchpoint_established_threads;
- // Tell each thread to set a watchpoint. In the event that
- // hardware watchpoints are requested but the SetWatchpoint fails,
- // try to set a software watchpoint as a fallback. It's
- // conceivable that if there are more threads than hardware
- // watchpoints available, some of the threads will fail to set
- // hardware watchpoints while software ones may be available.
+ // Tell each thread to set a watchpoint. In the event that hardware
+ // watchpoints are requested but the SetWatchpoint fails, try to set a
+ // software watchpoint as a fallback. It's conceivable that if there are
+ // more threads than hardware watchpoints available, some of the threads will
+ // fail to set hardware watchpoints while software ones may be available.
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
for (const auto &thread : m_threads) {
assert(thread && "thread list should not have a NULL thread!");
@@ -169,8 +165,8 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
Status thread_error =
thread->SetWatchpoint(addr, size, watch_flags, hardware);
if (thread_error.Fail() && hardware) {
- // Try software watchpoints since we failed on hardware watchpoint setting
- // and we may have just run out of hardware watchpoints.
+ // Try software watchpoints since we failed on hardware watchpoint
+ // setting and we may have just run out of hardware watchpoints.
thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);
if (thread_error.Success())
LLDB_LOG(log,
@@ -178,13 +174,12 @@ Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
}
if (thread_error.Success()) {
- // Remember that we set this watchpoint successfully in
- // case we need to clear it later.
+ // Remember that we set this watchpoint successfully in case we need to
+ // clear it later.
watchpoint_established_threads.push_back(thread.get());
} else {
- // Unset the watchpoint for each thread we successfully
- // set so that we get back to a consistent state of "not
- // set" for the watchpoint.
+ // Unset the watchpoint for each thread we successfully set so that we
+ // get back to a consistent state of "not set" for the watchpoint.
for (auto unwatch_thread_sp : watchpoint_established_threads) {
Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);
if (remove_error.Fail())
@@ -210,9 +205,9 @@ Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
const Status thread_error = thread->RemoveWatchpoint(addr);
if (thread_error.Fail()) {
- // Keep track of the first thread error if any threads
- // fail. We want to try to remove the watchpoint from
- // every thread, though, even if one or more have errors.
+ // Keep track of the first thread error if any threads fail. We want to
+ // try to remove the watchpoint from every thread, though, even if one or
+ // more have errors.
if (!overall_error.Fail())
overall_error = thread_error;
}
@@ -228,9 +223,9 @@ NativeProcessProtocol::GetHardwareBreakpointMap() const {
Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
- // This default implementation assumes setting a hardware breakpoint for
- // this process will require setting same hardware breakpoint for each
- // of its existing threads. New thread will do the same once created.
+ // This default implementation assumes setting a hardware breakpoint for this
+ // process will require setting same hardware breakpoint for each of its
+ // existing threads. New thread will do the same once created.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// Update the thread list
@@ -256,13 +251,13 @@ Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
Status thread_error = thread->SetHardwareBreakpoint(addr, size);
if (thread_error.Success()) {
- // Remember that we set this breakpoint successfully in
- // case we need to clear it later.
+ // Remember that we set this breakpoint successfully in case we need to
+ // clear it later.
breakpoint_established_threads.push_back(thread.get());
} else {
- // Unset the breakpoint for each thread we successfully
- // set so that we get back to a consistent state of "not
- // set" for this hardware breakpoint.
+ // Unset the breakpoint for each thread we successfully set so that we
+ // get back to a consistent state of "not set" for this hardware
+ // breakpoint.
for (auto rollback_thread_sp : breakpoint_established_threads) {
Status remove_error =
rollback_thread_sp->RemoveHardwareBreakpoint(addr);
@@ -322,8 +317,8 @@ bool NativeProcessProtocol::UnregisterNativeDelegate(
remove(m_delegates.begin(), m_delegates.end(), &native_delegate),
m_delegates.end());
- // We removed the delegate if the count of delegates shrank after
- // removing all copies of the given native_delegate from the vector.
+ // We removed the delegate if the count of delegates shrank after removing
+ // all copies of the given native_delegate from the vector.
return m_delegates.size() < initial_size;
}
@@ -412,8 +407,8 @@ void NativeProcessProtocol::SetState(lldb::StateType state,
// Give process a chance to do any stop id bump processing, such as
// clearing cached data that is invalidated each time the process runs.
- // Note if/when we support some threads running, we'll end up needing
- // to manage this per thread and per process.
+ // Note if/when we support some threads running, we'll end up needing to
+ // manage this per thread and per process.
DoStopIDBumped(m_stop_id);
}
@@ -431,26 +426,4 @@ void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) {
// Default implementation does nothing.
}
-Status NativeProcessProtocol::ResolveProcessArchitecture(lldb::pid_t pid,
- ArchSpec &arch) {
- // Grab process info for the running process.
- ProcessInstanceInfo process_info;
- if (!Host::GetProcessInfo(pid, process_info))
- return Status("failed to get process info");
-
- // Resolve the executable module.
- ModuleSpecList module_specs;
- if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0,
- 0, module_specs))
- return Status("failed to get module specifications");
- lldbassert(module_specs.GetSize() == 1);
-
- arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture();
- if (arch.IsValid())
- return Status();
- else
- return Status(
- "failed to retrieve a valid architecture from the exe module");
-}
-
NativeProcessProtocol::Factory::~Factory() = default;
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 60eaebdc94cd2..49b8284da9703 100644
--- a/source/Host/common/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -28,13 +28,12 @@ NativeRegisterContext::NativeRegisterContext(NativeThreadProtocol &thread)
NativeRegisterContext::~NativeRegisterContext() {}
// FIXME revisit invalidation, process stop ids, etc. Right now we don't
-// support caching in NativeRegisterContext. We can do this later by
-// utilizing NativeProcessProtocol::GetStopID () and adding a stop id to
+// support caching in NativeRegisterContext. We can do this later by utilizing
+// NativeProcessProtocol::GetStopID () and adding a stop id to
// NativeRegisterContext.
// void
-// NativeRegisterContext::InvalidateIfNeeded (bool force)
-// {
+// NativeRegisterContext::InvalidateIfNeeded (bool force) {
// ProcessSP process_sp (m_thread.GetProcess());
// bool invalidate = force;
// uint32_t process_stop_id = UINT32_MAX;
@@ -365,8 +364,8 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory(
// We now have a memory buffer that contains the part or all of the register
// value. Set the register value using this memory data.
// TODO: we might need to add a parameter to this function in case the byte
- // order of the memory data doesn't match the process. For now we are assuming
- // they are the same.
+ // order of the memory data doesn't match the process. For now we are
+ // assuming they are the same.
reg_value.SetFromMemoryData(reg_info, src, src_len, process.GetByteOrder(),
error);
@@ -385,8 +384,7 @@ Status NativeRegisterContext::WriteRegisterValueToMemory(
// TODO: we might need to add a parameter to this function in case the byte
// order of the memory data doesn't match the process. For now we are
- // assuming
- // they are the same.
+ // assuming they are the same.
const size_t bytes_copied = reg_value.GetAsMemoryData(
reg_info, dst, dst_len, process.GetByteOrder(), error);
diff --git a/source/Host/common/NativeThreadProtocol.cpp b/source/Host/common/NativeThreadProtocol.cpp
index 3f3915e006da6..0c648e40eb5c6 100644
--- a/source/Host/common/NativeThreadProtocol.cpp
+++ b/source/Host/common/NativeThreadProtocol.cpp
@@ -19,36 +19,3 @@ using namespace lldb_private;
NativeThreadProtocol::NativeThreadProtocol(NativeProcessProtocol &process,
lldb::tid_t tid)
: m_process(process), m_tid(tid) {}
-
-Status NativeThreadProtocol::ReadRegister(uint32_t reg,
- RegisterValue &reg_value) {
- NativeRegisterContext &register_context = GetRegisterContext();
-
- const RegisterInfo *const reg_info =
- register_context.GetRegisterInfoAtIndex(reg);
- if (!reg_info)
- return Status("no register info for reg num %" PRIu32, reg);
-
- return register_context.ReadRegister(reg_info, reg_value);
- ;
-}
-
-Status NativeThreadProtocol::WriteRegister(uint32_t reg,
- const RegisterValue &reg_value) {
- NativeRegisterContext& register_context = GetRegisterContext();
-
- const RegisterInfo *const reg_info =
- register_context.GetRegisterInfoAtIndex(reg);
- if (!reg_info)
- return Status("no register info for reg num %" PRIu32, reg);
-
- return register_context.WriteRegister(reg_info, reg_value);
-}
-
-Status NativeThreadProtocol::SaveAllRegisters(lldb::DataBufferSP &data_sp) {
- return GetRegisterContext().WriteAllRegisterValues(data_sp);
-}
-
-Status NativeThreadProtocol::RestoreAllRegisters(lldb::DataBufferSP &data_sp) {
- return GetRegisterContext().ReadAllRegisterValues(data_sp);
-}
diff --git a/source/Host/common/PseudoTerminal.cpp b/source/Host/common/PseudoTerminal.cpp
index 9657cb6523dce..c9b290078e182 100644
--- a/source/Host/common/PseudoTerminal.cpp
+++ b/source/Host/common/PseudoTerminal.cpp
@@ -35,10 +35,10 @@ PseudoTerminal::PseudoTerminal()
//----------------------------------------------------------------------
// Destructor
//
-// The destructor will close the master and slave file descriptors
-// if they are valid and ownership has not been released using the
-// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
-// member functions.
+// The destructor will close the master and slave file descriptors if they are
+// valid and ownership has not been released using the
+// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor() member
+// functions.
//----------------------------------------------------------------------
PseudoTerminal::~PseudoTerminal() {
CloseMasterFileDescriptor();
@@ -66,15 +66,14 @@ void PseudoTerminal::CloseSlaveFileDescriptor() {
}
//----------------------------------------------------------------------
-// Open the first available pseudo terminal with OFLAG as the
-// permissions. The file descriptor is stored in this object and can
-// be accessed with the MasterFileDescriptor() accessor. The
-// ownership of the master file descriptor can be released using
-// the ReleaseMasterFileDescriptor() accessor. If this object has
-// a valid master files descriptor when its destructor is called, it
-// will close the master file descriptor, therefore clients must
-// call ReleaseMasterFileDescriptor() if they wish to use the master
-// file descriptor after this object is out of scope or destroyed.
+// Open the first available pseudo terminal with OFLAG as the permissions. The
+// file descriptor is stored in this object and can be accessed with the
+// MasterFileDescriptor() accessor. The ownership of the master file descriptor
+// can be released using the ReleaseMasterFileDescriptor() accessor. If this
+// object has a valid master files descriptor when its destructor is called, it
+// will close the master file descriptor, therefore clients must call
+// ReleaseMasterFileDescriptor() if they wish to use the master file descriptor
+// after this object is out of scope or destroyed.
//
// RETURNS:
// True when successful, false indicating an error occurred.
@@ -118,12 +117,12 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
}
//----------------------------------------------------------------------
-// Open the slave pseudo terminal for the current master pseudo
-// terminal. A master pseudo terminal should already be valid prior to
-// calling this function (see OpenFirstAvailableMaster()).
-// The file descriptor is stored this object's member variables and can
-// be accessed via the GetSlaveFileDescriptor(), or released using the
-// ReleaseSlaveFileDescriptor() member function.
+// Open the slave pseudo terminal for the current master pseudo terminal. A
+// master pseudo terminal should already be valid prior to calling this
+// function (see OpenFirstAvailableMaster()). The file descriptor is stored
+// this object's member variables and can be accessed via the
+// GetSlaveFileDescriptor(), or released using the ReleaseSlaveFileDescriptor()
+// member function.
//
// RETURNS:
// True when successful, false indicating an error occurred.
@@ -152,8 +151,8 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
}
//----------------------------------------------------------------------
-// Get the name of the slave pseudo terminal. A master pseudo terminal
-// should already be valid prior to calling this function (see
+// Get the name of the slave pseudo terminal. A master pseudo terminal should
+// already be valid prior to calling this function (see
// OpenFirstAvailableMaster()).
//
// RETURNS:
@@ -185,18 +184,16 @@ const char *PseudoTerminal::GetSlaveName(char *error_str,
// Fork a child process and have its stdio routed to a pseudo terminal.
//
// In the parent process when a valid pid is returned, the master file
-// descriptor can be used as a read/write access to stdio of the
-// child process.
+// descriptor can be used as a read/write access to stdio of the child process.
//
-// In the child process the stdin/stdout/stderr will already be routed
-// to the slave pseudo terminal and the master file descriptor will be
-// closed as it is no longer needed by the child process.
+// In the child process the stdin/stdout/stderr will already be routed to the
+// slave pseudo terminal and the master file descriptor will be closed as it is
+// no longer needed by the child process.
//
-// This class will close the file descriptors for the master/slave
-// when the destructor is called, so be sure to call
-// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
-// file descriptors are going to be used past the lifespan of this
-// object.
+// This class will close the file descriptors for the master/slave when the
+// destructor is called, so be sure to call ReleaseMasterFileDescriptor() or
+// ReleaseSlaveFileDescriptor() if any file descriptors are going to be used
+// past the lifespan of this object.
//
// RETURNS:
// in the parent process: the pid of the child, or -1 if fork fails
@@ -261,49 +258,47 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
}
//----------------------------------------------------------------------
-// The master file descriptor accessor. This object retains ownership
-// of the master file descriptor when this accessor is used. Use
-// ReleaseMasterFileDescriptor() if you wish this object to release
-// ownership of the master file descriptor.
+// The master file descriptor accessor. This object retains ownership of the
+// master file descriptor when this accessor is used. Use
+// ReleaseMasterFileDescriptor() if you wish this object to release ownership
+// of the master file descriptor.
//
-// Returns the master file descriptor, or -1 if the master file
-// descriptor is not currently valid.
+// Returns the master file descriptor, or -1 if the master file descriptor is
+// not currently valid.
//----------------------------------------------------------------------
int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; }
//----------------------------------------------------------------------
// The slave file descriptor accessor.
//
-// Returns the slave file descriptor, or -1 if the slave file
-// descriptor is not currently valid.
+// Returns the slave file descriptor, or -1 if the slave file descriptor is not
+// currently valid.
//----------------------------------------------------------------------
int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; }
//----------------------------------------------------------------------
-// Release ownership of the master pseudo terminal file descriptor
-// without closing it. The destructor for this class will close the
-// master file descriptor if the ownership isn't released using this
-// call and the master file descriptor has been opened.
+// Release ownership of the master pseudo terminal file descriptor without
+// closing it. The destructor for this class will close the master file
+// descriptor if the ownership isn't released using this call and the master
+// file descriptor has been opened.
//----------------------------------------------------------------------
int PseudoTerminal::ReleaseMasterFileDescriptor() {
- // Release ownership of the master pseudo terminal file
- // descriptor without closing it. (the destructor for this
- // class will close it otherwise!)
+ // Release ownership of the master pseudo terminal file descriptor without
+ // closing it. (the destructor for this class will close it otherwise!)
int fd = m_master_fd;
m_master_fd = invalid_fd;
return fd;
}
//----------------------------------------------------------------------
-// Release ownership of the slave pseudo terminal file descriptor
-// without closing it. The destructor for this class will close the
-// slave file descriptor if the ownership isn't released using this
-// call and the slave file descriptor has been opened.
+// Release ownership of the slave pseudo terminal file descriptor without
+// closing it. The destructor for this class will close the slave file
+// descriptor if the ownership isn't released using this call and the slave
+// file descriptor has been opened.
//----------------------------------------------------------------------
int PseudoTerminal::ReleaseSlaveFileDescriptor() {
- // Release ownership of the slave pseudo terminal file
- // descriptor without closing it (the destructor for this
- // class will close it otherwise!)
+ // Release ownership of the slave pseudo terminal file descriptor without
+ // closing it (the destructor for this class will close it otherwise!)
int fd = m_slave_fd;
m_slave_fd = invalid_fd;
return fd;
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 4c23e4eb560c4..875291bc115f8 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -160,18 +160,17 @@ Status Socket::TcpListen(llvm::StringRef host_and_port,
error = listen_socket->Listen(host_and_port, backlog);
if (error.Success()) {
- // We were asked to listen on port zero which means we
- // must now read the actual port that was given to us
- // as port zero is a special code for "find an open port
- // for me".
+ // We were asked to listen on port zero which means we must now read the
+ // actual port that was given to us as port zero is a special code for
+ // "find an open port for me".
if (port == 0)
port = listen_socket->GetLocalPortNumber();
- // Set the port predicate since when doing a listen://<host>:<port>
- // it often needs to accept the incoming connection which is a blocking
- // system call. Allowing access to the bound port using a predicate allows
- // us to wait for the port predicate to be set to a non-zero value from
- // another thread in an efficient manor.
+ // Set the port predicate since when doing a listen://<host>:<port> it
+ // often needs to accept the incoming connection which is a blocking system
+ // call. Allowing access to the bound port using a predicate allows us to
+ // wait for the port predicate to be set to a non-zero value from another
+ // thread in an efficient manor.
if (predicate)
predicate->SetValue(port, eBroadcastAlways);
socket = listen_socket.release();
@@ -282,8 +281,7 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
}
// If this was unsuccessful, then check if it's simply a signed 32-bit
- // integer, representing
- // a port with an empty host.
+ // integer, representing a port with an empty host.
host_str.clear();
port_str.clear();
bool ok = false;
@@ -436,8 +434,8 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
error.Clear();
#if defined(ANDROID_USE_ACCEPT_WORKAROUND)
// Hack:
- // This enables static linking lldb-server to an API 21 libc, but still having
- // it run on older devices. It is necessary because API 21 libc's
+ // This enables static linking lldb-server to an API 21 libc, but still
+ // having it run on older devices. It is necessary because API 21 libc's
// implementation of accept() uses the accept4 syscall(), which is not
// available in older kernels. Using an older libc would fix this issue, but
// introduce other ones, as the old libraries were quite buggy.
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
index 14dbafd94c039..353dadf6ce6d6 100644
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ b/source/Host/common/SoftwareBreakpoint.cpp
@@ -17,9 +17,8 @@
using namespace lldb_private;
-// -------------------------------------------------------------------
-// static members
-// -------------------------------------------------------------------
+// ------------------------------------------------------------------- static
+// members -------------------------------------------------------------------
Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint,
@@ -34,8 +33,7 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
__FUNCTION__);
// Ask the NativeProcessProtocol subclass to fill in the correct software
- // breakpoint
- // trap for the breakpoint site.
+ // breakpoint trap for the breakpoint site.
size_t bp_opcode_size = 0;
const uint8_t *bp_opcode_bytes = NULL;
Status error = process.GetSoftwareBreakpointTrapOpcode(
@@ -98,9 +96,8 @@ Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
__FUNCTION__, addr);
- // Set the breakpoint and verified it was written properly. Now
- // create a breakpoint remover that understands how to undo this
- // breakpoint.
+ // Set the breakpoint and verified it was written properly. Now create a
+ // breakpoint remover that understands how to undo this breakpoint.
breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes,
bp_opcode_bytes, bp_opcode_size));
return Status();
@@ -280,8 +277,8 @@ Status SoftwareBreakpoint::DoDisable() {
// Make sure the breakpoint opcode exists at this address
if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) {
break_op_found = true;
- // We found a valid breakpoint opcode at this address, now restore
- // the saved opcode.
+ // We found a valid breakpoint opcode at this address, now restore the
+ // saved opcode.
size_t bytes_written = 0;
error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size,
bytes_written);
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index 3f70fdc4bf951..d7e0c13112aaf 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/Symbols.h"
-#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
@@ -91,7 +91,7 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
::strncat(path, exec_fspec->GetFilename().AsCString(),
sizeof(path) - strlen(path) - 1);
- dsym_fspec.SetFile(path, false);
+ dsym_fspec.SetFile(path, false, FileSpec::Style::native);
ModuleSpecList module_specs;
ModuleSpec matched_module_spec;
@@ -111,15 +111,15 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
// Add a ".dSYM" name to each directory component of the path,
// stripping off components. e.g. we may have a binary like
- // /S/L/F/Foundation.framework/Versions/A/Foundation
- // and
+ // /S/L/F/Foundation.framework/Versions/A/Foundation and
// /S/L/F/Foundation.framework.dSYM
//
- // so we'll need to start with /S/L/F/Foundation.framework/Versions/A,
- // add the .dSYM part to the "A", and if that doesn't exist, strip off
- // the "A" and try it again with "Versions", etc., until we find a
- // dSYM bundle or we've stripped off enough path components that
- // there's no need to continue.
+ // so we'll need to start with
+ // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+ // "A", and if that doesn't exist, strip off the "A" and try it again
+ // with "Versions", etc., until we find a dSYM bundle or we've
+ // stripped off enough path components that there's no need to
+ // continue.
for (int i = 0; i < 4; i++) {
// Does this part of the path have a "." character - could it be a
@@ -131,7 +131,8 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
dsym_fspec = parent_dirs;
dsym_fspec.RemoveLastPathComponent();
- // If the current directory name is "Foundation.framework", see if
+ // If the current directory name is "Foundation.framework", see
+ // if
// "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
// exists & has the right uuid.
std::string dsym_fn = fn;
@@ -222,14 +223,18 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
Target::GetDefaultDebugFileSearchPaths());
// Add module directory.
- const ConstString &file_dir = module_spec.GetFileSpec().GetDirectory();
+ FileSpec module_file_spec = module_spec.GetFileSpec();
+ // We keep the unresolved pathname if it fails.
+ FileSystem::ResolveSymbolicLink(module_file_spec, module_file_spec);
+
+ const ConstString &file_dir = module_file_spec.GetDirectory();
debug_file_search_paths.AppendIfUnique(
FileSpec(file_dir.AsCString("."), true));
// Add current working directory.
debug_file_search_paths.AppendIfUnique(FileSpec(".", true));
-#ifndef LLVM_ON_WIN32
+#ifndef _WIN32
#if defined(__NetBSD__)
// Add /usr/libdata/debug directory.
debug_file_search_paths.AppendIfUnique(
@@ -238,7 +243,7 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
// Add /usr/lib/debug directory.
debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
#endif
-#endif // LLVM_ON_WIN32
+#endif // _WIN32
std::string uuid_str;
const UUID &module_uuid = module_spec.GetUUID();
@@ -246,6 +251,8 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
// Some debug files are stored in the .build-id directory like this:
// /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
uuid_str = module_uuid.GetAsString("");
+ std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+ ::tolower);
uuid_str.insert(2, 1, '/');
uuid_str = uuid_str + ".debug";
}
@@ -275,7 +282,7 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
FileSpec file_spec(filename, true);
if (llvm::sys::fs::equivalent(file_spec.GetPath(),
- module_spec.GetFileSpec().GetPath()))
+ module_file_spec.GetPath()))
continue;
if (file_spec.Exists()) {
@@ -287,10 +294,9 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
if (num_specs == 1) {
ModuleSpec mspec;
if (specs.GetModuleSpecAtIndex(0, mspec)) {
- // Skip the uuids check if module_uuid is invalid.
- // For example, this happens for *.dwp files since
- // at the moment llvm-dwp doesn't output build ids,
- // nor does binutils dwp.
+ // Skip the uuids check if module_uuid is invalid. For example,
+ // this happens for *.dwp files since at the moment llvm-dwp
+ // doesn't output build ids, nor does binutils dwp.
if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
return file_spec;
}
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index f896944bb1b36..1a10336f1dfc5 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -26,11 +26,11 @@
#include <sys/socket.h>
#endif
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include <winsock2.h>
#endif
-#ifdef LLVM_ON_WIN32
+#ifdef _WIN32
#define CLOSE_SOCKET closesocket
typedef const char *set_socket_option_arg_type;
#else
diff --git a/source/Host/common/TaskPool.cpp b/source/Host/common/TaskPool.cpp
index 156a079429985..c54b9a8ae56b1 100644
--- a/source/Host/common/TaskPool.cpp
+++ b/source/Host/common/TaskPool.cpp
@@ -49,8 +49,8 @@ void TaskPool::AddTaskImpl(std::function<void()> &&task_fn) {
TaskPoolImpl::TaskPoolImpl() : m_thread_count(0) {}
unsigned GetHardwareConcurrencyHint() {
- // std::thread::hardware_concurrency may return 0
- // if the value is not well defined or not computable.
+ // std::thread::hardware_concurrency may return 0 if the value is not well
+ // defined or not computable.
static const unsigned g_hardware_concurrency =
std::max(1u, std::thread::hardware_concurrency());
return g_hardware_concurrency;
@@ -64,9 +64,8 @@ void TaskPoolImpl::AddTask(std::function<void()> &&task_fn) {
if (m_thread_count < GetHardwareConcurrencyHint()) {
m_thread_count++;
// Note that this detach call needs to happen with the m_tasks_mutex held.
- // This prevents the thread
- // from exiting prematurely and triggering a linux libc bug
- // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
+ // This prevents the thread from exiting prematurely and triggering a linux
+ // libc bug (https://sourceware.org/bugzilla/show_bug.cgi?id=19951).
lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr,
this, nullptr, min_stack_size)
.Release();
diff --git a/source/Host/common/Terminal.cpp b/source/Host/common/Terminal.cpp
index 022b3fa50a8fe..be912fbe61554 100644
--- a/source/Host/common/Terminal.cpp
+++ b/source/Host/common/Terminal.cpp
@@ -9,6 +9,7 @@
#include "lldb/Host/Terminal.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/PosixApi.h"
#include "llvm/ADT/STLExtras.h"
@@ -107,9 +108,9 @@ void TerminalState::Clear() {
}
//----------------------------------------------------------------------
-// Save the current state of the TTY for the file descriptor "fd"
-// and if "save_process_group" is true, attempt to save the process
-// group info for the TTY.
+// Save the current state of the TTY for the file descriptor "fd" and if
+// "save_process_group" is true, attempt to save the process group info for the
+// TTY.
//----------------------------------------------------------------------
bool TerminalState::Save(int fd, bool save_process_group) {
m_tty.SetFileDescriptor(fd);
@@ -142,8 +143,8 @@ bool TerminalState::Save(int fd, bool save_process_group) {
}
//----------------------------------------------------------------------
-// Restore the state of the TTY using the cached values from a
-// previous call to Save().
+// Restore the state of the TTY using the cached values from a previous call to
+// Save().
//----------------------------------------------------------------------
bool TerminalState::Restore() const {
#ifndef LLDB_DISABLE_POSIX
@@ -173,8 +174,8 @@ bool TerminalState::Restore() const {
}
//----------------------------------------------------------------------
-// Returns true if this object has valid saved TTY state settings
-// that can be used to restore a previous state.
+// Returns true if this object has valid saved TTY state settings that can be
+// used to restore a previous state.
//----------------------------------------------------------------------
bool TerminalState::IsValid() const {
return m_tty.FileDescriptorIsValid() &&
@@ -236,21 +237,20 @@ bool TerminalStateSwitcher::Restore(uint32_t idx) const {
m_ttystates[idx].IsValid())
return true;
- // Set the state to match the index passed in and only update the
- // current state if there are no errors.
+ // Set the state to match the index passed in and only update the current
+ // state if there are no errors.
if (m_ttystates[idx].Restore()) {
m_currentState = idx;
return true;
}
- // We failed to set the state. The tty state was invalid or not
- // initialized.
+ // We failed to set the state. The tty state was invalid or not initialized.
return false;
}
//------------------------------------------------------------------
-// Save the state at index "idx" for file descriptor "fd" and
-// save the process group if requested.
+// Save the state at index "idx" for file descriptor "fd" and save the process
+// group if requested.
//
// Returns true if the restore was successful, false otherwise.
//------------------------------------------------------------------
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 21dacbc626eee..96bcc6a150a9e 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -69,8 +69,8 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
return error;
- // At this point we have setup the receive port, now we need to
- // setup the UDP send socket
+ // At this point we have setup the receive port, now we need to setup the UDP
+ // send socket
struct addrinfo hints;
struct addrinfo *service_info_list = nullptr;
diff --git a/source/Host/common/XML.cpp b/source/Host/common/XML.cpp
index c3169bd6e08d1..7468a3d7ac65e 100644
--- a/source/Host/common/XML.cpp
+++ b/source/Host/common/XML.cpp
@@ -151,6 +151,18 @@ llvm::StringRef XMLNode::GetAttributeValue(const char *name,
return llvm::StringRef();
}
+bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value,
+ uint64_t fail_value, int base) const {
+#if defined(LIBXML2_DEFINED)
+ llvm::StringRef str_value = GetAttributeValue(name, "");
+#else
+ llvm::StringRef str_value;
+#endif
+ bool success = false;
+ value = StringConvert::ToUInt64(str_value.data(), fail_value, base, &success);
+ return success;
+}
+
void XMLNode::ForEachChildNode(NodeCallback const &callback) const {
#if defined(LIBXML2_DEFINED)
if (IsValid())
@@ -240,8 +252,8 @@ void XMLNode::ForEachSiblingElementWithName(
if (node->type != XML_ELEMENT_NODE)
continue;
- // If name is nullptr, we take all nodes of type "t", else
- // just the ones whose name matches
+ // If name is nullptr, we take all nodes of type "t", else just the ones
+ // whose name matches
if (name) {
if (strcmp((const char *)node->name, name) != 0)
continue; // Name mismatch, ignore this one
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index 124a8a760133a..87552bc2a27ed 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -26,12 +26,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -78,9 +75,11 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
size_t pathname_len = sizeof(pathname);
mib[2] = KERN_PROC_PATHNAME;
if (::sysctl(mib, 4, pathname, &pathname_len, NULL, 0) == 0)
- process_info.GetExecutableFile().SetFile(pathname, false);
+ process_info.GetExecutableFile().SetFile(pathname, false,
+ FileSpec::Style::native);
else
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
@@ -195,9 +194,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
continue;
// Every thread is a process in FreeBSD, but all the threads of a single
- // process have the same pid. Do not store the process info in the
- // result list if a process with given identifier is already registered
- // there.
+ // process have the same pid. Do not store the process info in the result
+ // list if a process with given identifier is already registered there.
bool already_registered = false;
for (uint32_t pi = 0;
!already_registered && (const int)kinfo.ki_numthreads > 1 &&
@@ -243,14 +241,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Status("unimplemented");
diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp
index 9c82fcca75637..18eae3eb76060 100644
--- a/source/Host/freebsd/HostInfoFreeBSD.cpp
+++ b/source/Host/freebsd/HostInfoFreeBSD.cpp
@@ -18,16 +18,17 @@
using namespace lldb_private;
-bool HostInfoFreeBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoFreeBSD::GetOSVersion() {
struct utsname un;
::memset(&un, 0, sizeof(utsname));
if (uname(&un) < 0)
- return false;
+ return llvm::VersionTuple();
- int status = sscanf(un.release, "%u.%u", &major, &minor);
- return status == 2;
+ unsigned major, minor;
+ if (2 == sscanf(un.release, "%u.%u", &major, &minor))
+ return llvm::VersionTuple(major, minor);
+ return llvm::VersionTuple();
}
bool HostInfoFreeBSD::GetOSBuildString(std::string &s) {
@@ -68,9 +69,9 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() {
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, false);
+ g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
delete[] exe_path;
}
}
return g_program_filespec;
-} \ No newline at end of file
+}
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index f43090eadf812..1a0eb767eb34b 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -20,7 +20,9 @@
// C++ Includes
// Other libraries and framework includes
+#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"
+
// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
@@ -29,12 +31,9 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Symbol/ObjectFile.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -123,28 +122,27 @@ static bool IsDirNumeric(const char *dname) {
return true;
}
-static bool GetELFProcessCPUType(llvm::StringRef exe_path,
- ProcessInstanceInfo &process_info) {
- // Clear the architecture.
- process_info.GetArchitecture().Clear();
+static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- ModuleSpecList specs;
- FileSpec filespec(exe_path, false);
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(filespec, 0, 0, specs);
- // GetModuleSpecifications() could fail if the executable has been deleted or
- // is locked.
- // But it shouldn't return more than 1 architecture.
- assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec module_spec;
- if (specs.GetModuleSpecAtIndex(0, module_spec) &&
- module_spec.GetArchitecture().IsValid()) {
- process_info.GetArchitecture() = module_spec.GetArchitecture();
- return true;
- }
+ auto buffer_sp = DataBufferLLVM::CreateSliceFromPath(exe_path, 0x20, 0);
+ if (!buffer_sp)
+ return ArchSpec();
+
+ uint8_t exe_class =
+ llvm::object::getElfArchType(
+ {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
+ .first;
+
+ switch (exe_class) {
+ case llvm::ELF::ELFCLASS32:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ case llvm::ELF::ELFCLASS64:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind64);
+ default:
+ LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
+ return ArchSpec();
}
- return false;
}
static bool GetProcessAndStatInfo(::pid_t pid,
@@ -173,7 +171,7 @@ static bool GetProcessAndStatInfo(::pid_t pid,
llvm::StringRef PathRef = ExePath;
PathRef.consume_back(" (deleted)");
- GetELFProcessCPUType(PathRef, process_info);
+ process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
// Get the process environment.
auto BufferOrError = getProcFile(pid, "environ");
@@ -192,14 +190,14 @@ static bool GetProcessAndStatInfo(::pid_t pid,
return false;
process_info.SetProcessID(pid);
- process_info.GetExecutableFile().SetFile(PathRef, false);
- process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
+ process_info.GetExecutableFile().SetFile(PathRef, false,
+ FileSpec::Style::native);
llvm::StringRef Rest = Environ->getBuffer();
while (!Rest.empty()) {
llvm::StringRef Var;
std::tie(Var, Rest) = Rest.split('\0');
- process_info.GetEnvironmentEntries().AppendArgument(Var);
+ process_info.GetEnvironment().insert(Var);
}
llvm::StringRef Arg0;
@@ -249,8 +247,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
if (State == ProcessState::Zombie)
continue;
- // Check for user match if we're not matching all users and not running as
- // root.
+ // Check for user match if we're not matching all users and not running
+ // as root.
if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
continue;
@@ -297,14 +295,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Status("unimplemented");
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 8d59cda249e83..1d95010e2f736 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "lldb/Utility/Log.h"
@@ -25,12 +26,8 @@ using namespace lldb_private;
namespace {
struct HostInfoLinuxFields {
- HostInfoLinuxFields() : m_os_major(0), m_os_minor(0), m_os_update(0) {}
-
std::string m_distribution_id;
- uint32_t m_os_major;
- uint32_t m_os_minor;
- uint32_t m_os_update;
+ llvm::VersionTuple m_os_version;
};
HostInfoLinuxFields *g_fields = nullptr;
@@ -42,35 +39,21 @@ void HostInfoLinux::Initialize() {
g_fields = new HostInfoLinuxFields();
}
-bool HostInfoLinux::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- static bool success = false;
+llvm::VersionTuple HostInfoLinux::GetOSVersion() {
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
-
struct utsname un;
- if (uname(&un) == 0) {
- int status = sscanf(un.release, "%u.%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor, &g_fields->m_os_update);
- if (status == 3)
- success = true;
- else {
- // Some kernels omit the update version, so try looking for just "X.Y"
- // and
- // set update to 0.
- g_fields->m_os_update = 0;
- status = sscanf(un.release, "%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor);
- if (status == 2)
- success = true;
- }
- }
+ if (uname(&un) != 0)
+ return;
+
+ llvm::StringRef release = un.release;
+ // The kernel release string can include a lot of stuff (e.g.
+ // 4.9.0-6-amd64). We're only interested in the numbered prefix.
+ release = release.substr(0, release.find_first_not_of("0123456789."));
+ g_fields->m_os_version.tryParse(release);
});
- major = g_fields->m_os_major;
- minor = g_fields->m_os_minor;
- update = g_fields->m_os_update;
- return success;
+ return g_fields->m_os_version;
}
bool HostInfoLinux::GetOSBuildString(std::string &s) {
@@ -99,8 +82,8 @@ bool HostInfoLinux::GetOSKernelDescription(std::string &s) {
}
llvm::StringRef HostInfoLinux::GetDistributionId() {
- // Try to run 'lbs_release -i', and use that response
- // for the distribution id.
+ // Try to run 'lbs_release -i', and use that response for the distribution
+ // id.
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
@@ -108,8 +91,7 @@ llvm::StringRef HostInfoLinux::GetDistributionId() {
if (log)
log->Printf("attempting to determine Linux distribution...");
- // check if the lsb_release command exists at one of the
- // following paths
+ // check if the lsb_release command exists at one of the following paths
const char *const exe_paths[] = {"/bin/lsb_release",
"/usr/bin/lsb_release"};
@@ -188,7 +170,7 @@ FileSpec HostInfoLinux::GetProgramFileSpec() {
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len > 0) {
exe_path[len] = 0;
- g_program_filespec.SetFile(exe_path, false);
+ g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
}
}
@@ -204,15 +186,15 @@ bool HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/usr/lib/lldb/plugins", true);
+ FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins", true);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
bool HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec) {
// XDG Base Directory Specification
- // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
- // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html If
+ // XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
const char *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home && xdg_data_home[0]) {
std::string user_plugin_dir(xdg_data_home);
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index 98c110b1bed67..b01c48e51d900 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -23,7 +23,7 @@
#include "Host/macosx/cfcpp/CFCData.h"
#include "Host/macosx/cfcpp/CFCReleaser.h"
#include "Host/macosx/cfcpp/CFCString.h"
-#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -55,6 +55,13 @@ CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
ModuleSpec &return_module_spec) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+ if (log)
+ log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
+ return 0;
+ }
+
return_module_spec = module_spec;
return_module_spec.GetFileSpec().Clear();
return_module_spec.GetSymbolFileSpec().Clear();
@@ -69,8 +76,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (uuid && uuid->IsValid()) {
// Try and locate the dSYM file using DebugSymbols first
- const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
- if (module_uuid != NULL) {
+ llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
+ if (module_uuid.size() == 16) {
CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
@@ -80,7 +87,6 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (module_uuid_ref.get()) {
CFCReleaser<CFURLRef> exec_url;
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (exec_fspec) {
char exec_cf_path[PATH_MAX];
if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
@@ -241,52 +247,53 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
const lldb_private::UUID *uuid,
const ArchSpec *arch) {
char path[PATH_MAX];
+ if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
+ return {};
- FileSpec dsym_fspec;
+ ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
- if (dsym_bundle_fspec.GetPath(path, sizeof(path))) {
- ::strncat(path, "/Contents/Resources/DWARF",
- sizeof(path) - strlen(path) - 1);
+ DIR *dirp = opendir(path);
+ if (!dirp)
+ return {};
- lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir);
- if (dirp.is_valid()) {
- dsym_fspec.GetDirectory().SetCString(path);
- struct dirent *dp;
- while ((dp = readdir(dirp.get())) != NULL) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- if (dp->d_namlen == 1 && dp->d_name[0] == '.')
- continue;
+ // Make sure we close the directory before exiting this scope.
+ CleanUp cleanup_dir(closedir, dirp);
- if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
+ FileSpec dsym_fspec;
+ dsym_fspec.GetDirectory().SetCString(path);
+ struct dirent *dp;
+ while ((dp = readdir(dirp)) != NULL) {
+ // Only search directories
+ if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
- if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
- dsym_fspec.GetFilename().SetCString(dp->d_name);
- ModuleSpecList module_specs;
- if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0,
- module_specs)) {
- ModuleSpec spec;
- for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
- UNUSED_IF_ASSERT_DISABLED(got_spec);
- assert(got_spec);
- if ((uuid == NULL ||
- (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
- (arch == NULL ||
- (spec.GetArchitecturePtr() &&
- spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
- return dsym_fspec;
- }
- }
+ if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ continue;
+ }
+
+ if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
+ dsym_fspec.GetFilename().SetCString(dp->d_name);
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
+ if ((uuid == NULL ||
+ (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == NULL ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return dsym_fspec;
}
}
}
}
}
- dsym_fspec.Clear();
- return dsym_fspec;
+
+ return {};
}
static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
@@ -302,7 +309,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
(CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetFileSpec().SetFile(str.c_str(), true);
+ module_spec.GetFileSpec().SetFile(str.c_str(), true,
+ FileSpec::Style::native);
if (log) {
log->Printf(
"From dsymForUUID plist: Symbol rich executable is at '%s'",
@@ -315,7 +323,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
CFSTR("DBGDSYMPath"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true);
+ module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true,
+ FileSpec::Style::native);
success = true;
if (log) {
log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
@@ -333,28 +342,13 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
std::string DBGBuildSourcePath;
std::string DBGSourcePath;
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGBuildSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
- }
-
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- }
-
+ // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+ // If DBGVersion 2, strip last two components of path remappings from
+ // entries to fix an issue with a specific set of
+ // DBGSourcePathRemapping entries that lldb worked
+ // with.
+ // If DBGVersion 3, trust & use the source path remappings as-is.
+ //
cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
(CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
@@ -401,10 +395,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
}
if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
// In the "old style" DBGSourcePathRemapping dictionary, the
- // DBGSourcePath values
- // (the "values" half of key-value path pairs) were wrong. Ignore
- // them and use the
- // universal DBGSourcePath string from earlier.
+ // DBGSourcePath values (the "values" half of key-value path pairs)
+ // were wrong. Ignore them and use the universal DBGSourcePath
+ // string from earlier.
if (new_style_source_remapping_dictionary == true &&
!original_DBGSourcePath_value.empty()) {
DBGSourcePath = original_DBGSourcePath_value;
@@ -414,9 +407,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
DBGSourcePath = resolved_source_path.GetPath();
}
// With version 2 of DBGSourcePathRemapping, we can chop off the
- // last two filename parts from the source remapping and get a
- // more general source remapping that still works. Add this as
- // another option in addition to the full source path remap.
+ // last two filename parts from the source remapping and get a more
+ // general source remapping that still works. Add this as another
+ // option in addition to the full source path remap.
module_spec.GetSourceMappingList().Append(
ConstString(DBGBuildSourcePath.c_str()),
ConstString(DBGSourcePath.c_str()), true);
@@ -439,6 +432,32 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
free(values);
}
}
+
+
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
+ // source remappings list.
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGBuildSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+ }
+
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ }
}
return success;
}
@@ -450,8 +469,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
// It's expensive to check for the DBGShellCommands defaults setting, only do
- // it once per
- // lldb run and cache the result.
+ // it once per lldb run and cache the result.
static bool g_have_checked_for_dbgshell_command = false;
static const char *g_dbgshell_command = NULL;
if (g_have_checked_for_dbgshell_command == false) {
@@ -473,8 +491,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
}
// When g_dbgshell_command is NULL, the user has not enabled the use of an
- // external program
- // to find the symbols, don't run it for them.
+ // external program to find the symbols, don't run it for them.
if (force_lookup == false && g_dbgshell_command == NULL) {
return false;
}
@@ -489,12 +506,14 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
FileSpec dsym_for_uuid_exe_spec;
if (dsym_for_uuid_exe_path_cstr) {
- dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
+ dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
if (!g_dsym_for_uuid_exe_exists) {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
+ dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
if (!g_dsym_for_uuid_exe_exists) {
long bufsize;
@@ -508,14 +527,16 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
tilde_rc && tilde_rc->pw_dir) {
std::string dsymforuuid_path(tilde_rc->pw_dir);
dsymforuuid_path += "/bin/dsymForUUID";
- dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false);
+ dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
}
}
}
if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
+ dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true,
+ FileSpec::Style::native);
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
@@ -561,8 +582,9 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
&exit_status, // Exit status
&signo, // Signal int *
&command_output, // Command output
- 30, // Large timeout to allow for long dsym download times
- false); // Don't run in a shell (we don't need shell expansion)
+ std::chrono::seconds(
+ 30), // Large timeout to allow for long dsym download times
+ false); // Don't run in a shell (we don't need shell expansion)
if (error.Success() && exit_status == 0 && !command_output.empty()) {
CFCData data(CFDataCreateWithBytesNoCopy(
NULL, (const UInt8 *)command_output.data(), command_output.size(),
diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
index 201ec9a8f5c24..0c52aa3ed0517 100644
--- a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
+++ b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
@@ -352,9 +352,8 @@ bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
if (cf_number.get()) {
@@ -371,9 +370,8 @@ bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
if (cf_number.get()) {
@@ -390,9 +388,8 @@ bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
if (cf_number.get()) {
@@ -409,9 +406,8 @@ bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value,
CFMutableDictionaryRef dict = Dictionary(can_create);
if (dict != NULL) {
// The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of
- // CFNumber, there isn't a way to have it show up otherwise as of this
- // writing.
+ // limitation of CFNumber, there isn't a way to have it show up otherwise
+ // as of this writing.
CFCReleaser<CFNumberRef> cf_number(
::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
if (cf_number.get()) {
diff --git a/source/Host/macosx/cfcpp/CFCString.cpp b/source/Host/macosx/cfcpp/CFCString.cpp
index 0d3853c60a72f..6191f873c98a2 100644
--- a/source/Host/macosx/cfcpp/CFCString.cpp
+++ b/source/Host/macosx/cfcpp/CFCString.cpp
@@ -88,9 +88,8 @@ const char *CFCString::UTF8(std::string &str) {
return CFCString::UTF8(get(), str);
}
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR
-// and returns the C string pointer that is contained in STR when successful,
-// else
+// Static function that puts a copy of the UTF8 contents of CF_STR into STR and
+// returns the C string pointer that is contained in STR when successful, else
// NULL is returned. This allows the std::string parameter to own the extracted
// string,
// and also allows that string to be returned as a C string pointer that can be
@@ -129,9 +128,9 @@ const char *CFCString::ExpandTildeInPath(const char *path,
// Static function that puts a copy of the file system representation of CF_STR
// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter
-// to own the extracted string, and also allows that string to be returned as
-// a C string pointer that can be used.
+// successful, else NULL is returned. This allows the std::string parameter to
+// own the extracted string, and also allows that string to be returned as a C
+// string pointer that can be used.
const char *CFCString::FileSystemRepresentation(CFStringRef cf_str,
std::string &str) {
diff --git a/source/Host/macosx/objcxx/CMakeLists.txt b/source/Host/macosx/objcxx/CMakeLists.txt
new file mode 100644
index 0000000000000..77e3091dc4fed
--- /dev/null
+++ b/source/Host/macosx/objcxx/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+remove_module_flags()
+include_directories(..)
+
+add_lldb_library(lldbHostMacOSXObjCXX
+ Host.mm
+ HostInfoMacOSX.mm
+ HostThreadMacOSX.mm
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+ ${EXTRA_LIBS}
+
+ LINK_COMPONENTS
+ Object
+ Support
+ )
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/objcxx/Host.mm
index 7359815fdf704..a70bf0421ec48 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/objcxx/Host.mm
@@ -54,13 +54,10 @@
#include <sys/types.h>
#include <unistd.h>
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Platform.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CleanUp.h"
@@ -72,15 +69,16 @@
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-defines.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Errno.h"
-#include "cfcpp/CFCBundle.h"
-#include "cfcpp/CFCMutableArray.h"
-#include "cfcpp/CFCMutableDictionary.h"
-#include "cfcpp/CFCReleaser.h"
-#include "cfcpp/CFCString.h"
+#include "../cfcpp/CFCBundle.h"
+#include "../cfcpp/CFCMutableArray.h"
+#include "../cfcpp/CFCMutableDictionary.h"
+#include "../cfcpp/CFCReleaser.h"
+#include "../cfcpp/CFCString.h"
#include <objc/objc-auto.h>
@@ -107,7 +105,7 @@ bool Host::GetBundleDirectory(const FileSpec &file,
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
if (bundle.GetPath(path, sizeof(path))) {
- bundle_directory.SetFile(path, false);
+ bundle_directory.SetFile(path, false, FileSpec::Style::native);
return true;
}
}
@@ -127,7 +125,7 @@ bool Host::ResolveExecutableInBundle(FileSpec &file) {
if (url.get()) {
if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path,
sizeof(path))) {
- file.SetFile(path, false);
+ file.SetFile(path, false, FileSpec::Style::native);
return true;
}
}
@@ -184,175 +182,6 @@ static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid,
}
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
-// static lldb::pid_t
-// LaunchInNewTerminalWithCommandFile
-//(
-// const char **argv,
-// const char **envp,
-// const char *working_dir,
-// const ArchSpec *arch_spec,
-// bool stop_at_entry,
-// bool disable_aslr
-//)
-//{
-// if (!argv || !argv[0])
-// return LLDB_INVALID_PROCESS_ID;
-//
-// OSStatus error = 0;
-//
-// FileSpec program (argv[0], false);
-//
-//
-// std::string unix_socket_name;
-//
-// char temp_file_path[PATH_MAX];
-// const char *tmpdir = ::getenv ("TMPDIR");
-// if (tmpdir == NULL)
-// tmpdir = "/tmp/";
-// ::snprintf (temp_file_path, sizeof(temp_file_path), "%s%s-XXXXXX", tmpdir,
-// program.GetFilename().AsCString());
-//
-// if (::mktemp (temp_file_path) == NULL)
-// return LLDB_INVALID_PROCESS_ID;
-//
-// unix_socket_name.assign (temp_file_path);
-//
-// ::strlcat (temp_file_path, ".command", sizeof (temp_file_path));
-//
-// StreamFile command_file;
-// command_file.GetFile().Open (temp_file_path,
-// File::eOpenOptionWrite |
-// File::eOpenOptionCanCreate,
-// lldb::eFilePermissionsDefault);
-//
-// if (!command_file.GetFile().IsValid())
-// return LLDB_INVALID_PROCESS_ID;
-//
-// FileSpec darwin_debug_file_spec;
-// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir,
-// darwin_debug_file_spec))
-// return LLDB_INVALID_PROCESS_ID;
-// darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
-//
-// if (!darwin_debug_file_spec.Exists())
-// return LLDB_INVALID_PROCESS_ID;
-//
-// char launcher_path[PATH_MAX];
-// darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
-// command_file.Printf("\"%s\" ", launcher_path);
-//
-// command_file.Printf("--unix-socket=%s ", unix_socket_name.c_str());
-//
-// if (arch_spec && arch_spec->IsValid())
-// {
-// command_file.Printf("--arch=%s ", arch_spec->GetArchitectureName());
-// }
-//
-// if (disable_aslr)
-// {
-// command_file.PutCString("--disable-aslr ");
-// }
-//
-// command_file.PutCString("-- ");
-//
-// if (argv)
-// {
-// for (size_t i=0; argv[i] != NULL; ++i)
-// {
-// command_file.Printf("\"%s\" ", argv[i]);
-// }
-// }
-// command_file.PutCString("\necho Process exited with status $?\n");
-// command_file.GetFile().Close();
-// if (::chmod (temp_file_path, S_IRWXU | S_IRWXG) != 0)
-// return LLDB_INVALID_PROCESS_ID;
-//
-// CFCMutableDictionary cf_env_dict;
-//
-// const bool can_create = true;
-// if (envp)
-// {
-// for (size_t i=0; envp[i] != NULL; ++i)
-// {
-// const char *env_entry = envp[i];
-// const char *equal_pos = strchr(env_entry, '=');
-// if (equal_pos)
-// {
-// std::string env_key (env_entry, equal_pos);
-// std::string env_val (equal_pos + 1);
-// CFCString cf_env_key (env_key.c_str(), kCFStringEncodingUTF8);
-// CFCString cf_env_val (env_val.c_str(), kCFStringEncodingUTF8);
-// cf_env_dict.AddValue (cf_env_key.get(), cf_env_val.get(),
-// can_create);
-// }
-// }
-// }
-//
-// LSApplicationParameters app_params;
-// ::memset (&app_params, 0, sizeof (app_params));
-// app_params.flags = kLSLaunchDontAddToRecents | kLSLaunchAsync;
-// app_params.argv = NULL;
-// app_params.environment = (CFDictionaryRef)cf_env_dict.get();
-//
-// CFCReleaser<CFURLRef> command_file_url
-// (::CFURLCreateFromFileSystemRepresentation (NULL,
-// (const UInt8 *)temp_file_path,
-// strlen(temp_file_path),
-// false));
-//
-// CFCMutableArray urls;
-//
-// // Terminal.app will open the ".command" file we have created
-// // and run our process inside it which will wait at the entry point
-// // for us to attach.
-// urls.AppendValue(command_file_url.get());
-//
-//
-// lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-//
-// Status lldb_error;
-// // Sleep and wait a bit for debugserver to start to listen...
-// char connect_url[128];
-// ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s",
-// unix_socket_name.c_str());
-//
-// // Spawn a new thread to accept incoming connection on the connect_url
-// // so we can grab the pid from the inferior
-// lldb::thread_t accept_thread = Host::ThreadCreate
-// (unix_socket_name.c_str(),
-// AcceptPIDFromInferior,
-// connect_url,
-// &lldb_error);
-//
-// ProcessSerialNumber psn;
-// error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params,
-// &psn, 1);
-// if (error == noErr)
-// {
-// thread_result_t accept_thread_result = NULL;
-// if (Host::ThreadJoin (accept_thread, &accept_thread_result,
-// &lldb_error))
-// {
-// if (accept_thread_result)
-// {
-// pid = (intptr_t)accept_thread_result;
-//
-// // Wait for process to be stopped the entry point by watching
-// // for the process status to be set to SSTOP which indicates
-// it it
-// // SIGSTOP'ed at the entry point
-// WaitForProcessToSIGSTOP (pid, 5);
-// }
-// }
-// }
-// else
-// {
-// Host::ThreadCancel (accept_thread, &lldb_error);
-// }
-//
-// return pid;
-//}
-
const char *applscript_in_new_tty = "tell application \"Terminal\"\n"
" activate\n"
" do script \"/bin/bash -c '%s';exit\"\n"
@@ -388,9 +217,8 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
}
StreamString command;
- FileSpec darwin_debug_file_spec;
- if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
- darwin_debug_file_spec)) {
+ FileSpec darwin_debug_file_spec = HostInfo::GetSupportExeDir();
+ if (!darwin_debug_file_spec) {
error.SetErrorString("can't locate the 'darwin-debug' executable");
return error;
}
@@ -431,33 +259,16 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
command.PutCString(" --disable-aslr");
// We are launching on this host in a terminal. So compare the environment on
- // the host
- // to what is supplied in the launch_info. Any items that aren't in the host
- // environment
- // need to be sent to darwin-debug. If we send all environment entries, we
- // might blow the
- // max command line length, so we only send user modified entries.
- const char **envp =
- launch_info.GetEnvironmentEntries().GetConstArgumentVector();
-
- StringList host_env;
- const size_t host_env_count = Host::GetEnvironment(host_env);
+ // the host to what is supplied in the launch_info. Any items that aren't in
+ // the host environment need to be sent to darwin-debug. If we send all
+ // environment entries, we might blow the max command line length, so we only
+ // send user modified entries.
+ Environment host_env = Host::GetEnvironment();
- if (envp && envp[0]) {
- const char *env_entry;
- for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx) {
- bool add_entry = true;
- for (size_t i = 0; i < host_env_count; ++i) {
- const char *host_env_entry = host_env.GetStringAtIndex(i);
- if (strcmp(env_entry, host_env_entry) == 0) {
- add_entry = false;
- break;
- }
- }
- if (add_entry) {
- command.Printf(" --env='%s'", env_entry);
- }
- }
+ for (const auto &KV : launch_info.GetEnvironment()) {
+ auto host_entry = host_env.find(KV.first());
+ if (host_entry == host_env.end() || host_entry->second != KV.second)
+ command.Format(" --env='{0}'", Environment::compose(KV));
}
command.PutCString(" -- ");
@@ -479,19 +290,8 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
StreamString applescript_source;
- // if (tty_name && tty_name[0])
- // {
- // applescript_source.Printf (applscript_in_existing_tty,
- // tty_command,
- // tty_name);
- // }
- // else
- // {
applescript_source.Printf(applscript_in_new_tty,
command.GetString().str().c_str());
- // }
-
- // puts (script_source);
NSAppleScript *applescript = [[NSAppleScript alloc]
initWithSource:[NSString stringWithCString:applescript_source.GetString()
.str()
@@ -641,14 +441,7 @@ bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = *_NSGetEnviron();
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(*_NSGetEnviron()); }
static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) {
if (process_info.ProcessIDIsValid()) {
@@ -748,7 +541,8 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
triple_arch == llvm::Triple::x86_64);
const char *cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (match_info_ptr == NULL ||
NameMatches(
@@ -770,7 +564,7 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
proc_args.AppendArgument(llvm::StringRef(cstr));
}
- Args &proc_env = process_info.GetEnvironmentEntries();
+ Environment &proc_env = process_info.GetEnvironment();
while ((cstr = data.GetCStr(&offset))) {
if (cstr[0] == '\0')
break;
@@ -785,7 +579,7 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
llvm::Triple::MacOSX);
}
- proc_env.AppendArgument(llvm::StringRef(cstr));
+ proc_env.insert(cstr);
}
return true;
}
@@ -939,6 +733,17 @@ static void PackageXPCArguments(xpc_object_t message, const char *prefix,
}
}
+static void PackageXPCEnvironment(xpc_object_t message, llvm::StringRef prefix,
+ const Environment &env) {
+ xpc_dictionary_set_int64(message, (prefix + "Count").str().c_str(),
+ env.size());
+ size_t i = 0;
+ for (const auto &KV : env) {
+ xpc_dictionary_set_string(message, (prefix + llvm::Twine(i)).str().c_str(),
+ Environment::compose(KV).c_str());
+ }
+}
+
/*
A valid authorizationRef means that
- there is the LaunchUsingXPCRightName rights in the /etc/authorization
@@ -1045,14 +850,11 @@ static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) {
if (g_use_close_on_exec_flag == eLazyBoolCalculate) {
g_use_close_on_exec_flag = eLazyBoolNo;
- uint32_t major, minor, update;
- if (HostInfo::GetOSVersion(major, minor, update)) {
+ llvm::VersionTuple version = HostInfo::GetOSVersion();
+ if (version > llvm::VersionTuple(10, 7)) {
// Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or
// earlier
- if (major > 10 || (major == 10 && minor > 7)) {
- // Only enable for 10.8 and later OS versions
- g_use_close_on_exec_flag = eLazyBoolYes;
- }
+ g_use_close_on_exec_flag = eLazyBoolYes;
}
}
#else
@@ -1141,8 +943,8 @@ static Status LaunchProcessXPC(const char *exe_path,
PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey,
launch_info.GetArguments());
- PackageXPCArguments(message, LauncherXPCServiceEnvPrefxKey,
- launch_info.GetEnvironmentEntries());
+ PackageXPCEnvironment(message, LauncherXPCServiceEnvPrefxKey,
+ launch_info.GetEnvironment());
// Posix spawn stuff.
xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey,
@@ -1294,10 +1096,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
return error;
}
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup(
- &attr, posix_spawnattr_destroy);
+ // Make sure we clean up the posix spawn attributes before exiting this scope.
+ CleanUp cleanup_attr(posix_spawnattr_destroy, &attr);
sigset_t no_signals;
sigset_t all_signals;
@@ -1356,8 +1156,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
const char *tmp_argv[2];
char *const *argv = const_cast<char *const *>(
launch_info.GetArguments().GetConstArgumentVector());
- char *const *envp = const_cast<char *const *>(
- launch_info.GetEnvironmentEntries().GetConstArgumentVector());
+ Environment::Envp envp = launch_info.GetEnvironment().getEnvp();
if (argv == NULL) {
// posix_spawn gets very unhappy if it doesn't have at least the program
// name in argv[0]. One of the side affects I have noticed is the
@@ -1400,11 +1199,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
return error;
}
- // Make a quick class that will cleanup the posix spawn attributes in case
- // we return in the middle of this function.
- lldb_utility::CleanUp<posix_spawn_file_actions_t *, int>
- posix_spawn_file_actions_cleanup(&file_actions,
- posix_spawn_file_actions_destroy);
+ // Make sure we clean up the posix file actions before exiting this scope.
+ CleanUp cleanup_fileact(posix_spawn_file_actions_destroy, &file_actions);
for (size_t i = 0; i < num_file_actions; ++i) {
const FileAction *launch_file_action =
@@ -1425,7 +1221,8 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
"error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', "
"file_actions = {3}, "
"attr = {4}, argv = {5}, envp = {6} )",
- error, result_pid, exe_path, &file_actions, &attr, argv, envp);
+ error, result_pid, exe_path, &file_actions, &attr, argv,
+ envp.get());
if (log) {
for (int ii = 0; argv[ii]; ++ii)
LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
@@ -1441,7 +1238,7 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
LLDB_LOG(log,
"error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', "
"file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )",
- error, result_pid, exe_path, &attr, argv, envp);
+ error, result_pid, exe_path, &attr, argv, envp.get());
if (log) {
for (int ii = 0; argv[ii]; ++ii)
LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
@@ -1476,36 +1273,28 @@ static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status error;
- char exe_path[PATH_MAX];
- PlatformSP host_platform_sp(Platform::GetHostPlatform());
-
- ModuleSpec exe_module_spec(launch_info.GetExecutableFile(),
- launch_info.GetArchitecture());
-
- if (!llvm::sys::fs::is_regular_file(
- exe_module_spec.GetFileSpec().GetPath())) {
- lldb::ModuleSP exe_module_sp;
- error = host_platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp,
- NULL);
-
- if (error.Fail())
- return error;
+ FileSpec exe_spec(launch_info.GetExecutableFile());
- if (exe_module_sp)
- exe_module_spec.GetFileSpec() = exe_module_sp->GetFileSpec();
+ llvm::sys::fs::file_status stats;
+ status(exe_spec.GetPath(), stats);
+ if (!exists(stats)) {
+ exe_spec.ResolvePath();
+ status(exe_spec.GetPath(), stats);
}
-
- if (exe_module_spec.GetFileSpec().Exists()) {
- exe_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- } else {
- launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
- error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
+ if (!exists(stats)) {
+ exe_spec.ResolveExecutableLocation();
+ status(exe_spec.GetPath(), stats);
+ }
+ if (!exists(stats)) {
+ error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
+ launch_info.GetExecutableFile());
return error;
}
if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
- return LaunchInNewTerminalWithAppleScript(exe_path, launch_info);
+ return LaunchInNewTerminalWithAppleScript(exe_spec.GetPath().c_str(),
+ launch_info);
#else
error.SetErrorString("launching a process in a new terminal is not "
"supported on iOS devices");
@@ -1516,9 +1305,10 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
if (ShouldLaunchUsingXPC(launch_info)) {
- error = LaunchProcessXPC(exe_path, launch_info, pid);
+ error = LaunchProcessXPC(exe_spec.GetPath().c_str(), launch_info, pid);
} else {
- error = LaunchProcessPosixSpawn(exe_path, launch_info, pid);
+ error =
+ LaunchProcessPosixSpawn(exe_spec.GetPath().c_str(), launch_info, pid);
}
if (pid != LLDB_INVALID_PROCESS_ID) {
@@ -1526,15 +1316,9 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
launch_info.SetProcessID(pid);
// Make sure we reap any processes we spawn or we will have zombies.
- if (!launch_info.MonitorProcess()) {
- const bool monitor_signals = false;
- Host::MonitorChildProcessCallback callback = nullptr;
-
- if (!launch_info.GetFlags().Test(lldb::eLaunchFlagDontSetExitStatus))
- callback = Process::SetProcessExitStatus;
-
- StartMonitoringChildProcess(callback, pid, monitor_signals);
- }
+ bool monitoring = launch_info.MonitorProcess();
+ UNUSED_IF_ASSERT_DISABLED(monitoring);
+ assert(monitoring);
} else {
// Invalid process ID, something didn't go well
if (error.Success())
@@ -1546,9 +1330,8 @@ Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir,
- expand_tool_spec)) {
+ FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
+ if (!expand_tool_spec) {
error.SetErrorString(
"could not get support executable directory for lldb-argdumper tool");
return error;
@@ -1583,7 +1366,8 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
launch_info.SetWorkingDirectory(working_dir);
}
}
- RunShellCommand(expand_command, cwd, &status, nullptr, &output, 10);
+ RunShellCommand(expand_command, cwd, &status, nullptr, &output,
+ std::chrono::seconds(10));
if (status != 0) {
error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
diff --git a/source/Host/macosx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 8774c76ef2dad..a39d26aa31ae4 100644
--- a/source/Host/macosx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -7,18 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#if !defined(LLDB_DISABLE_PYTHON)
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
-#endif
-
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Args.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/SafeMachO.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
// C++ Includes
@@ -30,7 +27,7 @@
#include <sys/syslimits.h>
#include <sys/types.h>
-// Objective C/C++ includes
+// Objective-C/C++ includes
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
#include <mach-o/dyld.h>
@@ -75,32 +72,21 @@ bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) {
return false;
}
-bool HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- static uint32_t g_major = 0;
- static uint32_t g_minor = 0;
- static uint32_t g_update = 0;
+llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
+ static llvm::VersionTuple g_version;
- if (g_major == 0) {
+ if (g_version.empty()) {
@autoreleasepool {
NSDictionary *version_info = [NSDictionary
dictionaryWithContentsOfFile:
@"/System/Library/CoreServices/SystemVersion.plist"];
NSString *version_value = [version_info objectForKey:@"ProductVersion"];
const char *version_str = [version_value UTF8String];
- if (version_str)
- Args::StringToVersion(llvm::StringRef(version_str), g_major, g_minor,
- g_update);
+ g_version.tryParse(version_str);
}
}
- if (g_major != 0) {
- major = g_major;
- minor = g_minor;
- update = g_update;
- return true;
- }
- return false;
+ return g_version;
}
FileSpec HostInfoMacOSX::GetProgramFileSpec() {
@@ -111,13 +97,15 @@ FileSpec HostInfoMacOSX::GetProgramFileSpec() {
uint32_t len = sizeof(program_fullpath);
int err = _NSGetExecutablePath(program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(program_fullpath, false);
+ g_program_filespec.SetFile(program_fullpath, false,
+ FileSpec::Style::native);
else if (err == -1) {
char *large_program_fullpath = (char *)::malloc(len + 1);
err = _NSGetExecutablePath(large_program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(large_program_fullpath, false);
+ g_program_filespec.SetFile(large_program_fullpath, false,
+ FileSpec::Style::native);
::free(large_program_fullpath);
}
@@ -126,8 +114,8 @@ FileSpec HostInfoMacOSX::GetProgramFileSpec() {
}
bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -179,8 +167,8 @@ bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -196,58 +184,9 @@ bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
return true;
}
-bool HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) {
-#ifndef LLDB_DISABLE_PYTHON
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos != std::string::npos) {
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Resources/Python");
- } else {
- llvm::SmallString<256> python_version_dir;
- llvm::raw_svector_ostream os(python_version_dir);
- os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION
- << "/site-packages";
-
- // We may get our string truncated. Should we protect this with an assert?
- raw_path.append(python_version_dir.c_str());
- }
- file_spec.GetDirectory().SetString(
- llvm::StringRef(raw_path.c_str(), raw_path.size()));
- return true;
-#else
- return false;
-#endif
-}
-
-bool HostInfoMacOSX::ComputeClangDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos == std::string::npos)
- return HostInfoPosix::ComputeClangDirectory(file_spec);
-
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Resources/Clang");
-
- file_spec.SetFile(raw_path.c_str(), true);
- return true;
-}
-
bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
diff --git a/source/Host/macosx/HostThreadMacOSX.mm b/source/Host/macosx/objcxx/HostThreadMacOSX.mm
index c5051cdf30d77..c5051cdf30d77 100644
--- a/source/Host/macosx/HostThreadMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostThreadMacOSX.mm
diff --git a/source/Host/netbsd/Host.cpp b/source/Host/netbsd/Host.cpp
index d927f95f06753..bfd5a74ffcc21 100644
--- a/source/Host/netbsd/Host.cpp
+++ b/source/Host/netbsd/Host.cpp
@@ -25,12 +25,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -48,14 +45,7 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
ProcessInstanceInfo &process_info) {
@@ -80,7 +70,8 @@ static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
if (!cstr)
return false;
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
@@ -202,9 +193,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
continue;
// Every thread is a process in NetBSD, but all the threads of a single
- // process have the same pid. Do not store the process info in the
- // result list if a process with given identifier is already registered
- // there.
+ // process have the same pid. Do not store the process info in the result
+ // list if a process with given identifier is already registered there.
if (proc_kinfo[i].p_nlwps > 1) {
bool already_registered = false;
for (size_t pi = 0; pi < process_infos.GetSize(); pi++) {
diff --git a/source/Host/netbsd/HostInfoNetBSD.cpp b/source/Host/netbsd/HostInfoNetBSD.cpp
index 428183bbe2c3f..dfbce310509dc 100644
--- a/source/Host/netbsd/HostInfoNetBSD.cpp
+++ b/source/Host/netbsd/HostInfoNetBSD.cpp
@@ -21,30 +21,26 @@
using namespace lldb_private;
-bool HostInfoNetBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoNetBSD::GetOSVersion() {
struct utsname un;
::memset(&un, 0, sizeof(un));
if (::uname(&un) < 0)
- return false;
+ return llvm::VersionTuple();
/* Accept versions like 7.99.21 and 6.1_STABLE */
+ uint32_t major, minor, update;
int status = ::sscanf(un.release, "%" PRIu32 ".%" PRIu32 ".%" PRIu32, &major,
&minor, &update);
switch (status) {
- case 0:
- return false;
case 1:
- minor = 0;
- /* FALLTHROUGH */
+ return llvm::VersionTuple(major);
case 2:
- update = 0;
- /* FALLTHROUGH */
+ return llvm::VersionTuple(major, minor);
case 3:
- default:
- return true;
+ return llvm::VersionTuple(major, minor, update);
}
+ return llvm::VersionTuple();
}
bool HostInfoNetBSD::GetOSBuildString(std::string &s) {
@@ -89,7 +85,7 @@ FileSpec HostInfoNetBSD::GetProgramFileSpec() {
len = sizeof(path);
if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) {
- g_program_filespec.SetFile(path, false);
+ g_program_filespec.SetFile(path, false, FileSpec::Style::native);
}
}
return g_program_filespec;
diff --git a/source/Host/openbsd/Host.cpp b/source/Host/openbsd/Host.cpp
index 0535256b9aa1f..49e9c290a027e 100644
--- a/source/Host/openbsd/Host.cpp
+++ b/source/Host/openbsd/Host.cpp
@@ -22,12 +22,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Module.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
-#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
@@ -45,16 +42,17 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
+Environment Host::GetEnvironment() {
+ Environment env;
char *v;
char **var = environ;
for (; var != NULL && *var != NULL; ++var) {
v = strchr(*var, (int)'-');
if (v == NULL)
continue;
- env.AppendString(v);
+ env.insert(v);
}
- return env.GetSize();
+ return env;
}
static bool
@@ -74,7 +72,8 @@ GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false);
+ process_info.GetExecutableFile().SetFile(cstr, false,
+ FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 3797650105ce3..c21bb786a8962 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -189,15 +189,14 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
}
#ifndef LLDB_DISABLE_POSIX
else if ((addr = GetURLAddress(path, FD_SCHEME))) {
- // Just passing a native file descriptor within this current process
- // that is already opened (possibly from a service or other source).
+ // Just passing a native file descriptor within this current process that
+ // is already opened (possibly from a service or other source).
int fd = -1;
if (!addr->getAsInteger(0, fd)) {
- // We have what looks to be a valid file descriptor, but we
- // should make sure it is. We currently are doing this by trying to
- // get the flags from the file descriptor and making sure it
- // isn't a bad fd.
+ // We have what looks to be a valid file descriptor, but we should make
+ // sure it is. We currently are doing this by trying to get the flags
+ // from the file descriptor and making sure it isn't a bad fd.
errno = 0;
int flags = ::fcntl(fd, F_GETFL, 0);
if (flags == -1 || errno == EBADF) {
@@ -208,20 +207,18 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
m_write_sp.reset();
return eConnectionStatusError;
} else {
- // Don't take ownership of a file descriptor that gets passed
- // to us since someone else opened the file descriptor and
- // handed it to us.
+ // Don't take ownership of a file descriptor that gets passed to us
+ // since someone else opened the file descriptor and handed it to us.
// TODO: Since are using a URL to open connection we should
- // eventually parse options using the web standard where we
- // have "fd://123?opt1=value;opt2=value" and we can have an
- // option be "owns=1" or "owns=0" or something like this to
- // allow us to specify this. For now, we assume we must
- // assume we don't own it.
+ // eventually parse options using the web standard where we have
+ // "fd://123?opt1=value;opt2=value" and we can have an option be
+ // "owns=1" or "owns=0" or something like this to allow us to specify
+ // this. For now, we assume we must assume we don't own it.
std::unique_ptr<TCPSocket> tcp_socket;
tcp_socket.reset(new TCPSocket(fd, false, false));
- // Try and get a socket option from this file descriptor to
- // see if this is a socket and set m_is_socket accordingly.
+ // Try and get a socket option from this file descriptor to see if
+ // this is a socket and set m_is_socket accordingly.
int resuse;
bool is_socket =
!!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse);
@@ -320,13 +317,11 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) {
m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
static_cast<Socket &>(*m_read_sp).PreDisconnect();
- // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is quite
- // likely
- // because somebody is doing a blocking read on our file 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.
+ // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is
+ // quite likely because somebody is doing a blocking read on our file
+ // 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;
@@ -430,11 +425,11 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len,
case EINVAL: // The pointer associated with fildes was negative.
case EIO: // An I/O error occurred while reading from the file system.
// The process group is orphaned.
- // The file is a regular file, nbyte is greater than 0,
- // the starting position is before the end-of-file, and
- // the starting position is greater than or equal to the
- // offset maximum established for the open file
- // descriptor associated with fildes.
+ // The file is a regular file, nbyte is greater than 0, the
+ // starting position is before the end-of-file, and the
+ // starting position is greater than or equal to the offset
+ // maximum established for the open file descriptor
+ // associated with fildes.
case EISDIR: // An attempt is made to read a directory.
case ENOBUFS: // An attempt to allocate a memory buffer fails.
case ENOMEM: // Insufficient memory is available.
@@ -550,15 +545,15 @@ ConnectionStatus
ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
Status *error_ptr) {
// Don't need to take the mutex here separately since we are only called from
- // Read. If we
- // ever get used more generally we will need to lock here as well.
+ // Read. If we ever get used more generally we will need to lock here as
+ // well.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION));
LLDB_LOG(log, "this = {0}, timeout = {1}", this, timeout);
- // Make a copy of the file descriptors to make sure we don't
- // have another thread change these values out from under us
- // and cause problems in the loop below where like in FS_SET()
+ // Make a copy of the file descriptors to make sure we don't have another
+ // thread change these values out from under us and cause problems in the
+ // loop below where like in FS_SET()
const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle();
const int pipe_fd = m_pipe.GetReadFileDescriptor();
@@ -570,10 +565,9 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
select_helper.FDSetRead(handle);
#if defined(_MSC_VER)
// 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 an error.
+ // needs to be converted over to using WaitForMultipleObjects and event
+ // HANDLEs, but for now at least this will allow ::select() to not return
+ // an error.
const bool have_pipe_fd = false;
#else
const bool have_pipe_fd = pipe_fd >= 0;
@@ -603,11 +597,10 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
return eConnectionStatusTimedOut;
case EAGAIN: // The kernel was (perhaps temporarily) unable to
- // allocate the requested number of file descriptors,
- // or we have non-blocking IO
+ // allocate the requested number of file descriptors, or
+ // we have non-blocking IO
case EINTR: // A signal was delivered before the time limit
- // expired and before any of the selected events
- // occurred.
+ // expired and before any of the selected events occurred.
break; // Lets keep reading to until we timeout
}
} else {
@@ -615,8 +608,8 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
return eConnectionStatusSuccess;
if (select_helper.FDIsSetRead(pipe_fd)) {
- // There is an interrupt or exit command in the command pipe
- // Read the data from that pipe:
+ // There is an interrupt or exit command in the command pipe Read the
+ // data from that pipe:
char c;
ssize_t bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1);
@@ -753,14 +746,10 @@ ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s,
return eConnectionStatusSuccess;
}
-uint16_t ConnectionFileDescriptor::GetListeningPort(uint32_t timeout_sec) {
- uint16_t bound_port = 0;
- if (timeout_sec == UINT32_MAX)
- m_port_predicate.WaitForValueNotEqualTo(0, bound_port);
- else
- m_port_predicate.WaitForValueNotEqualTo(0, bound_port,
- std::chrono::seconds(timeout_sec));
- return bound_port;
+uint16_t
+ConnectionFileDescriptor::GetListeningPort(const Timeout<std::micro> &timeout) {
+ auto Result = m_port_predicate.WaitForValueNotEqualTo(0, timeout);
+ return Result ? *Result : 0;
}
bool ConnectionFileDescriptor::GetChildProcessesInherit() const {
diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp
index 3ece0677f991d..60be642df6087 100644
--- a/source/Host/posix/FileSystem.cpp
+++ b/source/Host/posix/FileSystem.cpp
@@ -16,11 +16,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-#ifdef __linux__
-#include <linux/magic.h>
-#include <sys/mount.h>
-#include <sys/statfs.h>
-#endif
#if defined(__NetBSD__)
#include <sys/statvfs.h>
#endif
@@ -52,7 +47,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
error.SetErrorToErrno();
else {
buf[count] = '\0'; // Success
- dst.SetFile(buf, false);
+ dst.SetFile(buf, false, FileSpec::Style::native);
}
return error;
}
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index da9e1fb366cc2..62c70fa3edc12 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -7,15 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#if !defined(LLDB_DISABLE_PYTHON)
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
-#endif
-
#include "lldb/Host/posix/HostInfoPosix.h"
#include "lldb/Utility/Log.h"
-#include "clang/Basic/Version.h"
-#include "clang/Config/config.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Path.h"
@@ -103,8 +97,7 @@ const char *HostInfoPosix::LookupGroupName(uint32_t gid,
}
} else {
// The threadsafe version isn't currently working for me on darwin, but the
- // non-threadsafe version
- // is, so I am calling it below.
+ // non-threadsafe version is, so I am calling it below.
group_info_ptr = ::getgrgid(gid);
if (group_info_ptr) {
group_name.assign(group_info_ptr->gr_name);
@@ -132,8 +125,8 @@ bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec,
llvm::StringRef dir) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
+ FileSpec lldb_file_spec = GetShlibDir();
+ if (!lldb_file_spec)
return false;
std::string raw_path = lldb_file_spec.GetPath();
@@ -141,8 +134,8 @@ bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec,
llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
// Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with
- // */bin as the base directory for helper exe programs. This will fail if the
- // /lib and /bin directories are rooted in entirely different trees.
+ // */bin as the base directory for helper exe programs. This will fail if
+ // the /lib and /bin directories are rooted in entirely different trees.
if (log)
log->Printf("HostInfoPosix::ComputePathRelativeToLibrary() attempting to "
"derive the %s path from this path: %s",
@@ -169,59 +162,12 @@ bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {
return ComputePathRelativeToLibrary(file_spec, "/bin");
}
-bool HostInfoPosix::ComputeClangDirectory(FileSpec &file_spec) {
- return ComputePathRelativeToLibrary(
- file_spec, (llvm::Twine("/lib") + CLANG_LIBDIR_SUFFIX + "/clang/" +
- CLANG_VERSION_STRING)
- .str());
-}
-
bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) {
FileSpec temp_file("/opt/local/include/lldb", false);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
-bool HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec) {
-#ifndef LLDB_DISABLE_PYTHON
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
-
- char raw_path[PATH_MAX];
- lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
-
-#if defined(LLDB_PYTHON_RELATIVE_LIBDIR)
- // Build the path by backing out of the lib dir, then building
- // with whatever the real python interpreter uses. (e.g. lib
- // for most, lib64 on RHEL x86_64).
- char python_path[PATH_MAX];
- ::snprintf(python_path, sizeof(python_path), "%s/../%s", raw_path,
- LLDB_PYTHON_RELATIVE_LIBDIR);
-
- char final_path[PATH_MAX];
- realpath(python_path, final_path);
- file_spec.GetDirectory().SetCString(final_path);
-
- return true;
-#else
- llvm::SmallString<256> python_version_dir;
- llvm::raw_svector_ostream os(python_version_dir);
- os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION
- << "/site-packages";
-
- // We may get our string truncated. Should we protect this with an assert?
- ::strncat(raw_path, python_version_dir.c_str(),
- sizeof(raw_path) - strlen(raw_path) - 1);
-
- file_spec.GetDirectory().SetCString(raw_path);
- return true;
-#endif
-#else
- return false;
-#endif
-}
-
bool HostInfoPosix::GetEnvironmentVar(const std::string &var_name,
std::string &var) {
if (const char *pvar = ::getenv(var_name.c_str())) {
diff --git a/source/Host/posix/HostThreadPosix.cpp b/source/Host/posix/HostThreadPosix.cpp
index 71abb76dc600b..13de42f763ec7 100644
--- a/source/Host/posix/HostThreadPosix.cpp
+++ b/source/Host/posix/HostThreadPosix.cpp
@@ -41,14 +41,11 @@ Status HostThreadPosix::Join(lldb::thread_result_t *result) {
Status HostThreadPosix::Cancel() {
Status error;
if (IsJoinable()) {
-#ifndef __ANDROID__
#ifndef __FreeBSD__
llvm_unreachable("someone is calling HostThread::Cancel()");
-#endif
+#else
int err = ::pthread_cancel(m_thread);
error.SetError(err, eErrorTypePOSIX);
-#else
- error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
}
return error;
diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp
index da99fd702424e..b321cad642758 100644
--- a/source/Host/posix/PipePosix.cpp
+++ b/source/Host/posix/PipePosix.cpp
@@ -127,18 +127,14 @@ Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
llvm::SmallVectorImpl<char> &name) {
llvm::SmallString<PATH_MAX> named_pipe_path;
llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str());
- FileSpec tmpdir_file_spec;
- tmpdir_file_spec.Clear();
- if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- } else {
+ FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
+ if (!tmpdir_file_spec)
tmpdir_file_spec.AppendPathComponent("/tmp");
- tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str());
- }
+ tmpdir_file_spec.AppendPathComponent(pipe_spec);
// It's possible that another process creates the target path after we've
- // verified it's available but before we create it, in which case we
- // should try again.
+ // verified it's available but before we create it, in which case we should
+ // try again.
Status error;
do {
llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
diff --git a/source/Host/posix/ProcessLauncherPosixFork.cpp b/source/Host/posix/ProcessLauncherPosixFork.cpp
index ac1d9011c2b78..46ce3e3d224f6 100644
--- a/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -38,17 +38,12 @@
using namespace lldb;
using namespace lldb_private;
-static void FixupEnvironment(Args &env) {
+static void FixupEnvironment(Environment &env) {
#ifdef __ANDROID__
// If there is no PATH variable specified inside the environment then set the
// path to /system/bin. It is required because the default path used by
// execve() is wrong on android.
- static const char *path = "PATH=";
- for (auto &entry : env.entries()) {
- if (entry.ref.startswith(path))
- return;
- }
- env.AppendArgument(llvm::StringRef("PATH=/system/bin"));
+ env.try_emplace("PATH", "/system/bin");
#endif
}
@@ -95,10 +90,6 @@ static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
const ProcessLaunchInfo &info) {
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- ExitWithError(error_fd, "setgid");
-
if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) {
if (setpgid(0, 0) != 0)
ExitWithError(error_fd, "setpgid");
@@ -132,23 +123,26 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
ExitWithError(error_fd, "chdir");
DisableASLRIfRequested(error_fd, info);
- Args env = info.GetEnvironmentEntries();
+ Environment env = info.GetEnvironment();
FixupEnvironment(env);
- const char **envp = env.GetConstArgumentVector();
+ Environment::Envp envp = env.getEnvp();
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
+ // Clear the signal mask to prevent the child from being affected by any
+ // masking done by the parent.
sigset_t set;
if (sigemptyset(&set) != 0 ||
pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
ExitWithError(error_fd, "pthread_sigmask");
if (info.GetFlags().Test(eLaunchFlagDebug)) {
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ ExitWithError(error_fd, "setgid");
+
// HACK:
// Close everything besides stdin, stdout, and stderr that has no file
// action to avoid leaking. Only do this when debugging, as elsewhere we
- // actually rely on
- // passing open descriptors to child processes.
+ // actually rely on passing open descriptors to child processes.
for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
if (!info.GetFileActionForFD(fd) && fd != error_fd)
close(fd);
@@ -159,26 +153,20 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
}
// Execute. We should never return...
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
+ execve(argv[0], const_cast<char *const *>(argv), envp);
#if defined(__linux__)
if (errno == ETXTBSY) {
- // On android M and earlier we can get this error because the adb deamon can
- // hold a write
- // handle on the executable even after it has finished uploading it. This
- // state lasts
- // only a short time and happens only when there are many concurrent adb
- // commands being
- // issued, such as when running the test suite. (The file remains open when
- // someone does
- // an "adb shell" command in the fork() child before it has had a chance to
- // exec.) Since
- // this state should clear up quickly, wait a while and then give it one
- // more go.
+ // On android M and earlier we can get this error because the adb deamon
+ // can hold a write handle on the executable even after it has finished
+ // uploading it. This state lasts only a short time and happens only when
+ // there are many concurrent adb commands being issued, such as when
+ // running the test suite. (The file remains open when someone does an "adb
+ // shell" command in the fork() child before it has had a chance to exec.)
+ // Since this state should clear up quickly, wait a while and then give it
+ // one more go.
usleep(50000);
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
+ execve(argv[0], const_cast<char *const *>(argv), envp);
}
#endif
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
index 41bdb5f41fb6a..e59e190dcb2d5 100644
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ b/source/Host/windows/ConnectionGenericFileWindows.cpp
@@ -21,12 +21,10 @@ using namespace lldb_private;
namespace {
// This is a simple helper class to package up the information needed to return
-// from a Read/Write
-// operation function. Since there is a lot of code to be run before exit
-// regardless of whether the
-// operation succeeded or failed, combined with many possible return paths, this
-// is the cleanest
-// way to represent it.
+// from a Read/Write operation function. Since there is a lot of code to be
+// run before exit regardless of whether the operation succeeded or failed,
+// combined with many possible return paths, this is the cleanest way to
+// represent it.
class ReturnInfo {
public:
void Set(size_t bytes, ConnectionStatus status, DWORD error_code) {
@@ -78,11 +76,9 @@ void ConnectionGenericFile::InitializeEventHandles() {
m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE, NULL);
// Note, we should use a manual reset event for the hEvent argument of the
- // OVERLAPPED. This
- // is because both WaitForMultipleObjects and GetOverlappedResult (if you set
- // the bWait
- // argument to TRUE) will wait for the event to be signalled. If we use an
- // auto-reset event,
+ // OVERLAPPED. This is because both WaitForMultipleObjects and
+ // GetOverlappedResult (if you set the bWait argument to TRUE) will wait for
+ // the event to be signalled. If we use an auto-reset event,
// WaitForMultipleObjects will reset the event, return successfully, and then
// GetOverlappedResult will block since the event is no longer signalled.
m_event_handles[kBytesAvailableEvent] =
@@ -147,8 +143,7 @@ lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
return eConnectionStatusSuccess;
// Reset the handle so that after we unblock any pending reads, subsequent
- // calls to Read() will
- // see a disconnected state.
+ // calls to Read() will see a disconnected state.
HANDLE old_file = m_file;
m_file = INVALID_HANDLE_VALUE;
@@ -157,8 +152,7 @@ lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
::CancelIoEx(old_file, &m_overlapped);
// Close the file handle if we owned it, but don't close the event handles.
- // We could always
- // reconnect with the same Connection instance.
+ // We could always reconnect with the same Connection instance.
if (m_owns_file)
::CloseHandle(old_file);
@@ -190,8 +184,7 @@ size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
if (result || ::GetLastError() == ERROR_IO_PENDING) {
if (!result) {
// The expected return path. The operation is pending. Wait for the
- // operation to complete
- // or be interrupted.
+ // operation to complete or be interrupted.
DWORD milliseconds =
timeout
? std::chrono::duration_cast<std::chrono::milliseconds>(*timeout)
@@ -219,11 +212,9 @@ size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
// The data is ready. Figure out how much was read and return;
if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read, FALSE)) {
DWORD result_error = ::GetLastError();
- // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during a
- // blocking read.
- // This triggers a call to CancelIoEx, which causes the operation to
- // complete and the
- // result to be ERROR_OPERATION_ABORTED.
+ // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during
+ // a blocking read. This triggers a call to CancelIoEx, which causes the
+ // operation to complete and the result to be ERROR_OPERATION_ABORTED.
if (result_error == ERROR_HANDLE_EOF ||
result_error == ERROR_OPERATION_ABORTED ||
result_error == ERROR_BROKEN_PIPE)
@@ -250,9 +241,9 @@ finish:
if (error_ptr)
*error_ptr = return_info.GetError();
- // kBytesAvailableEvent is a manual reset event. Make sure it gets reset here
- // so that any
- // subsequent operations don't immediately see bytes available.
+ // kBytesAvailableEvent is a manual reset event. Make sure it gets reset
+ // here so that any subsequent operations don't immediately see bytes
+ // available.
ResetEvent(m_event_handles[kBytesAvailableEvent]);
IncrementFilePointer(return_info.GetBytes());
@@ -284,7 +275,8 @@ size_t ConnectionGenericFile::Write(const void *src, size_t src_len,
m_overlapped.hEvent = NULL;
- // Writes are not interruptible like reads are, so just block until it's done.
+ // Writes are not interruptible like reads are, so just block until it's
+ // done.
result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);
if (!result && ::GetLastError() != ERROR_IO_PENDING) {
return_info.Set(0, eConnectionStatusError, ::GetLastError());
diff --git a/source/Host/windows/EditLineWin.cpp b/source/Host/windows/EditLineWin.cpp
index 133cd62254679..3bccc4e1a2c9c 100644
--- a/source/Host/windows/EditLineWin.cpp
+++ b/source/Host/windows/EditLineWin.cpp
@@ -316,8 +316,8 @@ int el_get(EditLine *el, int code, ...) {
}
int el_source(EditLine *el, const char *file) {
- // init edit line by reading the contents of 'file'
- // nothing to do here on windows...
+ // init edit line by reading the contents of 'file' nothing to do here on
+ // windows...
return 0;
}
@@ -342,8 +342,8 @@ void history_end(History *) {
}
int history(History *, HistEvent *, int op, ...) {
- // perform operation 'op' on the history list with
- // optional arguments as needed by the operation.
+ // perform operation 'op' on the history list with optional arguments as
+ // needed by the operation.
return 0;
}
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index 02b7e550f86cd..9309b89f2baf8 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -75,7 +75,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
else if (!llvm::convertWideToUTF8(buf.data(), path))
error.SetErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(path, false);
+ dst.SetFile(path, false, FileSpec::Style::native);
::CloseHandle(h);
return error;
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
index 4458ce25e6079..cc6c454d36b11 100644
--- a/source/Host/windows/Host.cpp
+++ b/source/Host/windows/Host.cpp
@@ -35,8 +35,7 @@ using namespace lldb_private;
namespace {
bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
// Open the PE File as a binary file, and parse just enough information to
- // determine the
- // machine type.
+ // determine the machine type.
File imageBinary(executable.GetPath().c_str(), File::eOpenOptionRead,
lldb::eFilePermissionsUserRead);
imageBinary.SeekFromStart(0x3c);
@@ -63,8 +62,8 @@ bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
}
bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
- // Get the process image path. MAX_PATH isn't long enough, paths can actually
- // be up to 32KB.
+ // Get the process image path. MAX_PATH isn't long enough, paths can
+ // actually be up to 32KB.
std::vector<wchar_t> buffer(PATH_MAX);
DWORD dwSize = buffer.size();
if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
@@ -75,10 +74,9 @@ bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
void GetProcessExecutableAndTriple(const AutoHandle &handle,
ProcessInstanceInfo &process) {
// We may not have permissions to read the path from the process. So start
- // off by
- // setting the executable file to whatever Toolhelp32 gives us, and then try
- // to
- // enhance this with more detailed information, but fail gracefully.
+ // off by setting the executable file to whatever Toolhelp32 gives us, and
+ // then try to enhance this with more detailed information, but fail
+ // gracefully.
std::string executable;
llvm::Triple triple;
triple.setVendor(llvm::Triple::PC);
@@ -124,7 +122,7 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
std::string path;
if (!llvm::convertWideToUTF8(buffer.data(), path))
return module_filespec;
- module_filespec.SetFile(path, false);
+ module_filespec.SetFile(path, false, FileSpec::Style::native);
return module_filespec;
}
@@ -184,9 +182,8 @@ HostThread Host::StartMonitoringChildProcess(
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec;
- if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir,
- expand_tool_spec)) {
+ FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
+ if (!expand_tool_spec) {
error.SetErrorString("could not find support executable directory for "
"the lldb-argdumper tool");
return error;
@@ -209,7 +206,7 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
std::string output;
std::string command = expand_command.GetString();
RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(), &status,
- nullptr, &output, 10);
+ nullptr, &output, std::chrono::seconds(10));
if (status != 0) {
error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
@@ -258,13 +255,12 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return error;
}
-size_t Host::GetEnvironment(StringList &env) {
+Environment Host::GetEnvironment() {
+ Environment env;
// The environment block on Windows is a contiguous buffer of NULL terminated
- // strings,
- // where the end of the environment block is indicated by two consecutive
- // NULLs.
+ // strings, where the end of the environment block is indicated by two
+ // consecutive NULLs.
LPWCH environment_block = ::GetEnvironmentStringsW();
- env.Clear();
while (*environment_block != L'\0') {
std::string current_var;
auto current_var_size = wcslen(environment_block) + 1;
@@ -273,9 +269,9 @@ size_t Host::GetEnvironment(StringList &env) {
continue;
}
if (current_var[0] != '=')
- env.AppendString(current_var);
+ env.insert(current_var);
environment_block += current_var_size;
}
- return env.GetSize();
+ return env;
}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
index 53a24ad1893ec..bd3f74f2e2f38 100644
--- a/source/Host/windows/HostInfoWindows.cpp
+++ b/source/Host/windows/HostInfoWindows.cpp
@@ -42,39 +42,33 @@ size_t HostInfoWindows::GetPageSize() {
return systemInfo.dwPageSize;
}
-bool HostInfoWindows::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
+llvm::VersionTuple HostInfoWindows::GetOSVersion() {
OSVERSIONINFOEX info;
ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
#pragma warning(push)
#pragma warning(disable : 4996)
- // Starting with Microsoft SDK for Windows 8.1, this function is deprecated in
- // favor of the
- // new Windows Version Helper APIs. Since we don't specify a minimum SDK
- // version, it's easier
- // to simply disable the warning rather than try to support both APIs.
- if (GetVersionEx((LPOSVERSIONINFO)&info) == 0) {
- return false;
- }
+ // Starting with Microsoft SDK for Windows 8.1, this function is deprecated
+ // in favor of the new Windows Version Helper APIs. Since we don't specify a
+ // minimum SDK version, it's easier to simply disable the warning rather than
+ // try to support both APIs.
+ if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
+ return llvm::VersionTuple();
#pragma warning(pop)
- major = info.dwMajorVersion;
- minor = info.dwMinorVersion;
- update = info.wServicePackMajor;
-
- return true;
+ return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion,
+ info.wServicePackMajor);
}
bool HostInfoWindows::GetOSBuildString(std::string &s) {
s.clear();
- uint32_t major, minor, update;
- if (!GetOSVersion(major, minor, update))
+ llvm::VersionTuple version = GetOSVersion();
+ if (version.empty())
return false;
llvm::raw_string_ostream stream(s);
- stream << "Windows NT " << major << "." << minor << "." << update;
+ stream << "Windows NT " << version.getAsString();
return true;
}
@@ -98,27 +92,20 @@ FileSpec HostInfoWindows::GetProgramFileSpec() {
::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
std::string path;
llvm::convertWideToUTF8(buffer.data(), path);
- m_program_filespec.SetFile(path, false);
+ m_program_filespec.SetFile(path, false, FileSpec::Style::native);
});
return m_program_filespec;
}
FileSpec HostInfoWindows::GetDefaultShell() {
+ // Try to retrieve ComSpec from the environment. On the rare occasion
+ // that it fails, try a well-known path for ComSpec instead.
+
std::string shell;
- GetEnvironmentVar("ComSpec", shell);
- return FileSpec(shell, false);
-}
+ if (GetEnvironmentVar("ComSpec", shell))
+ return FileSpec(shell, false);
-bool HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec;
- if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
- return false;
- llvm::SmallString<64> path(lldb_file_spec.GetDirectory().AsCString());
- llvm::sys::path::remove_filename(path);
- llvm::sys::path::append(path, "lib", "site-packages");
- std::replace(path.begin(), path.end(), '\\', '/');
- file_spec.GetDirectory().SetString(path.c_str());
- return true;
+ return FileSpec("C:\\Windows\\system32\\cmd.exe", false);
}
bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name,
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
index 49d42ce054223..ce75c14cdcf4e 100644
--- a/source/Host/windows/HostProcessWindows.cpp
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -57,7 +57,7 @@ Status HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
std::string path;
if (llvm::convertWideToUTF8(wpath.data(), path))
- file_spec.SetFile(path, false);
+ file_spec.SetFile(path, false, FileSpec::Style::native);
else
error.SetErrorString("Error converting path to UTF-8");
} else
@@ -88,8 +88,8 @@ HostThread HostProcessWindows::StartMonitoring(
info->callback = callback;
// Since the life of this HostProcessWindows instance and the life of the
- // process may be different, duplicate the handle so that
- // the monitor thread can have ownership over its own copy of the handle.
+ // process may be different, duplicate the handle so that the monitor thread
+ // can have ownership over its own copy of the handle.
HostThread result;
if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
&info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
index e8f4753d11e2c..1951c9ca193ad 100644
--- a/source/Host/windows/PipeWindows.cpp
+++ b/source/Host/windows/PipeWindows.cpp
@@ -40,11 +40,9 @@ PipeWindows::PipeWindows() {
PipeWindows::~PipeWindows() { Close(); }
Status PipeWindows::CreateNew(bool child_process_inherit) {
- // Even for anonymous pipes, we open a named pipe. This is because you cannot
- // get
- // overlapped i/o on Windows without using a named pipe. So we synthesize a
- // unique
- // name.
+ // Even for anonymous pipes, we open a named pipe. This is because you
+ // cannot get overlapped i/o on Windows without using a named pipe. So we
+ // synthesize a unique name.
uint32_t serial = g_pipe_serial.fetch_add(1);
std::string pipe_name;
llvm::raw_string_ostream pipe_name_stream(pipe_name);
@@ -65,8 +63,8 @@ Status PipeWindows::CreateNew(llvm::StringRef name,
std::string pipe_path = "\\\\.\\Pipe\\";
pipe_path.append(name);
- // Always open for overlapped i/o. We implement blocking manually in Read and
- // Write.
+ // Always open for overlapped i/o. We implement blocking manually in Read
+ // and Write.
DWORD read_mode = FILE_FLAG_OVERLAPPED;
m_read = ::CreateNamedPipeA(
pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode,
@@ -250,12 +248,10 @@ Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
if (wait_result != WAIT_OBJECT_0) {
// The operation probably failed. However, if it timed out, we need to
- // cancel the I/O.
- // Between the time we returned from WaitForSingleObject and the time we
- // call CancelIoEx,
- // the operation may complete. If that hapens, CancelIoEx will fail and
- // return ERROR_NOT_FOUND.
- // If that happens, the original operation should be considered to have been
+ // cancel the I/O. Between the time we returned from WaitForSingleObject
+ // and the time we call CancelIoEx, the operation may complete. If that
+ // hapens, CancelIoEx will fail and return ERROR_NOT_FOUND. If that
+ // happens, the original operation should be considered to have been
// successful.
bool failed = true;
DWORD failure_error = ::GetLastError();
@@ -268,9 +264,8 @@ Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
return Status(failure_error, eErrorTypeWin32);
}
- // Now we call GetOverlappedResult setting bWait to false, since we've already
- // waited
- // as long as we're willing to.
+ // Now we call GetOverlappedResult setting bWait to false, since we've
+ // already waited as long as we're willing to.
if (!GetOverlappedResult(m_read, &m_read_overlapped, &sys_bytes_read, FALSE))
return Status(::GetLastError(), eErrorTypeWin32);
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
index 56089742f0932..553dd9d286da8 100644
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/source/Host/windows/ProcessLauncherWindows.cpp
@@ -21,14 +21,15 @@ using namespace lldb;
using namespace lldb_private;
namespace {
-void CreateEnvironmentBuffer(const Args &env, std::vector<char> &buffer) {
- if (env.GetArgumentCount() == 0)
+void CreateEnvironmentBuffer(const Environment &env,
+ std::vector<char> &buffer) {
+ if (env.size() == 0)
return;
// Environment buffer is a null terminated list of null terminated strings
- for (auto &entry : env.entries()) {
+ for (const auto &KV : env) {
std::wstring warg;
- if (llvm::ConvertUTF8toWide(entry.ref, warg)) {
+ if (llvm::ConvertUTF8toWide(Environment::compose(KV), warg)) {
buffer.insert(buffer.end(), (char *)warg.c_str(),
(char *)(warg.c_str() + warg.size() + 1));
}
@@ -75,9 +76,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
- auto &env = const_cast<Args &>(launch_info.GetEnvironmentEntries());
LPVOID env_block = nullptr;
- ::CreateEnvironmentBuffer(env, environment);
+ ::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment);
if (!environment.empty())
env_block = environment.data();
@@ -96,6 +96,12 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
&startupinfo, &pi);
+
+ if (!result) {
+ // Call GetLastError before we make any other system calls.
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ }
+
if (result) {
// Do not call CloseHandle on pi.hProcess, since we want to pass that back
// through the HostProcess.
@@ -110,7 +116,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
::CloseHandle(stderr_handle);
if (!result)
- error.SetError(::GetLastError(), eErrorTypeWin32);
+ return HostProcess();
+
return HostProcess(pi.hProcess);
}