aboutsummaryrefslogtreecommitdiff
path: root/source/Target
diff options
context:
space:
mode:
Diffstat (limited to 'source/Target')
-rw-r--r--source/Target/ABI.cpp1
-rw-r--r--source/Target/ExecutionContext.cpp35
-rw-r--r--source/Target/FileAction.cpp23
-rw-r--r--source/Target/LanguageRuntime.cpp84
-rw-r--r--source/Target/Memory.cpp139
-rw-r--r--source/Target/ObjCLanguageRuntime.cpp47
-rw-r--r--source/Target/Platform.cpp498
-rw-r--r--source/Target/Process.cpp570
-rw-r--r--source/Target/ProcessLaunchInfo.cpp119
-rw-r--r--source/Target/StackFrame.cpp8
-rw-r--r--source/Target/StackFrameList.cpp17
-rw-r--r--source/Target/StopInfo.cpp48
-rw-r--r--source/Target/Target.cpp567
-rw-r--r--source/Target/TargetList.cpp43
-rw-r--r--source/Target/Thread.cpp37
-rw-r--r--source/Target/ThreadList.cpp6
-rw-r--r--source/Target/ThreadPlan.cpp4
-rw-r--r--source/Target/ThreadPlanCallFunction.cpp4
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp4
-rw-r--r--source/Target/ThreadPlanPython.cpp3
-rw-r--r--source/Target/ThreadPlanRunToAddress.cpp1
-rw-r--r--source/Target/ThreadPlanStepInRange.cpp3
-rw-r--r--source/Target/ThreadPlanStepInstruction.cpp1
-rw-r--r--source/Target/ThreadPlanStepOut.cpp2
-rw-r--r--source/Target/ThreadPlanStepOverBreakpoint.cpp1
-rw-r--r--source/Target/ThreadPlanStepOverRange.cpp6
-rw-r--r--source/Target/ThreadPlanStepRange.cpp9
-rw-r--r--source/Target/ThreadPlanStepThrough.cpp1
-rw-r--r--source/Target/ThreadPlanStepUntil.cpp1
-rw-r--r--source/Target/ThreadPlanTracer.cpp8
30 files changed, 1730 insertions, 560 deletions
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
index e02f360680fb..8809c1e51d0c 100644
--- a/source/Target/ABI.cpp
+++ b/source/Target/ABI.cpp
@@ -11,6 +11,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp
index e03a560bd063..03714728559c 100644
--- a/source/Target/ExecutionContext.cpp
+++ b/source/Target/ExecutionContext.cpp
@@ -119,31 +119,42 @@ ExecutionContext::ExecutionContext (const lldb::StackFrameWP &frame_wp) :
}
ExecutionContext::ExecutionContext (Target* t, bool fill_current_process_thread_frame) :
- m_target_sp (t->shared_from_this()),
+ m_target_sp (),
m_process_sp (),
m_thread_sp (),
m_frame_sp ()
{
- if (t && fill_current_process_thread_frame)
+ if (t)
{
- m_process_sp = t->GetProcessSP();
- if (m_process_sp)
+ m_target_sp = t->shared_from_this();
+ if (fill_current_process_thread_frame)
{
- m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
- if (m_thread_sp)
- m_frame_sp = m_thread_sp->GetSelectedFrame();
+ m_process_sp = t->GetProcessSP();
+ if (m_process_sp)
+ {
+ m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
+ if (m_thread_sp)
+ m_frame_sp = m_thread_sp->GetSelectedFrame();
+ }
}
}
}
ExecutionContext::ExecutionContext(Process* process, Thread *thread, StackFrame *frame) :
m_target_sp (),
- m_process_sp (process->shared_from_this()),
- m_thread_sp (thread->shared_from_this()),
- m_frame_sp (frame->shared_from_this())
+ m_process_sp (),
+ m_thread_sp (),
+ m_frame_sp ()
{
if (process)
+ {
+ m_process_sp = process->shared_from_this();
m_target_sp = process->GetTarget().shared_from_this();
+ }
+ if (thread)
+ m_thread_sp = thread->shared_from_this();
+ if (frame)
+ m_frame_sp = frame->shared_from_this();
}
ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
@@ -238,9 +249,9 @@ uint32_t
ExecutionContext::GetAddressByteSize() const
{
if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
- m_target_sp->GetArchitecture().GetAddressByteSize();
+ return m_target_sp->GetArchitecture().GetAddressByteSize();
if (m_process_sp)
- m_process_sp->GetAddressByteSize();
+ return m_process_sp->GetAddressByteSize();
return sizeof(void *);
}
diff --git a/source/Target/FileAction.cpp b/source/Target/FileAction.cpp
index 8611ff5f2d2c..21c37e8e6f85 100644
--- a/source/Target/FileAction.cpp
+++ b/source/Target/FileAction.cpp
@@ -26,7 +26,7 @@ FileAction::FileAction() :
m_action(eFileActionNone),
m_fd(-1),
m_arg(-1),
- m_path()
+ m_file_spec()
{
}
@@ -36,21 +36,25 @@ FileAction::Clear()
m_action = eFileActionNone;
m_fd = -1;
m_arg = -1;
- m_path.clear();
+ m_file_spec.Clear();
}
const char *
FileAction::GetPath() const
{
- if (m_path.empty())
- return NULL;
- return m_path.c_str();
+ return m_file_spec.GetCString();
+}
+
+const FileSpec &
+FileAction::GetFileSpec() const
+{
+ return m_file_spec;
}
bool
-FileAction::Open(int fd, const char *path, bool read, bool write)
+FileAction::Open(int fd, const FileSpec &file_spec, bool read, bool write)
{
- if ((read || write) && fd >= 0 && path && path[0])
+ if ((read || write) && fd >= 0 && file_spec)
{
m_action = eFileActionOpen;
m_fd = fd;
@@ -60,7 +64,7 @@ FileAction::Open(int fd, const char *path, bool read, bool write)
m_arg = O_NOCTTY | O_RDONLY;
else
m_arg = O_NOCTTY | O_CREAT | O_WRONLY;
- m_path.assign(path);
+ m_file_spec = file_spec;
return true;
}
else
@@ -111,7 +115,8 @@ FileAction::Dump(Stream &stream) const
stream.PutCString("no action");
break;
case eFileActionOpen:
- stream.Printf("open fd %d with '%s', OFLAGS = 0x%x", m_fd, m_path.c_str(), m_arg);
+ stream.Printf("open fd %d with '%s', OFLAGS = 0x%x",
+ m_fd, m_file_spec.GetCString(), m_arg);
break;
}
}
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index 123ee93d322f..9c7b441d4c53 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/source/Target/LanguageRuntime.cpp
@@ -8,9 +8,11 @@
//===----------------------------------------------------------------------===//
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/SearchFilter.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
using namespace lldb;
using namespace lldb_private;
@@ -277,6 +279,23 @@ LanguageRuntime::~LanguageRuntime()
{
}
+Breakpoint::BreakpointPreconditionSP
+LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp)
+{
+ switch (language)
+ {
+ case eLanguageTypeObjC:
+ if (throw_bp)
+ return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
+ break;
+ default:
+ break;
+ }
+ return Breakpoint::BreakpointPreconditionSP();
+}
+
BreakpointSP
LanguageRuntime::CreateExceptionBreakpoint (Target &target,
lldb::LanguageType language,
@@ -289,8 +308,15 @@ LanguageRuntime::CreateExceptionBreakpoint (Target &target,
bool hardware = false;
bool resolve_indirect_functions = false;
BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
- if (is_internal)
- exc_breakpt_sp->SetBreakpointKind("exception");
+ if (exc_breakpt_sp)
+ {
+ Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
+ if (precondition_sp)
+ exc_breakpt_sp->SetPrecondition(precondition_sp);
+
+ if (is_internal)
+ exc_breakpt_sp->SetBreakpointKind("exception");
+ }
return exc_breakpt_sp;
}
@@ -340,6 +366,9 @@ struct language_name_pair language_names[] =
{ "c++14", eLanguageTypeC_plus_plus_14 },
{ "fortran03", eLanguageTypeFortran03 },
{ "fortran08", eLanguageTypeFortran08 },
+ // Vendor Extensions
+ { "mipsassem", eLanguageTypeMipsAssembler },
+ { "renderscript", eLanguageTypeExtRenderScript},
// Now synonyms, in arbitrary order
{ "objc", eLanguageTypeObjC },
{ "objc++", eLanguageTypeObjC_plus_plus }
@@ -367,6 +396,57 @@ LanguageRuntime::GetNameForLanguageType (LanguageType language)
return language_names[eLanguageTypeUnknown].name;
}
+void
+LanguageRuntime::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
+{
+ for (uint32_t i = 1; i < num_languages; i++)
+ {
+ s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
+ }
+}
+
+bool
+LanguageRuntime::LanguageIsCPlusPlus (LanguageType language)
+{
+ switch (language)
+ {
+ case eLanguageTypeC_plus_plus:
+ case eLanguageTypeC_plus_plus_03:
+ case eLanguageTypeC_plus_plus_11:
+ case eLanguageTypeC_plus_plus_14:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void
+LanguageRuntime::InitializeCommands (CommandObject* parent)
+{
+ if (!parent)
+ return;
+
+ if (!parent->IsMultiwordObject())
+ return;
+
+ LanguageRuntimeCreateInstance create_callback;
+
+ for (uint32_t idx = 0;
+ (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
+ ++idx)
+ {
+ if (LanguageRuntimeGetCommandObject command_callback =
+ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
+ {
+ CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
+ if (command)
+ {
+ parent->LoadSubCommand(command->GetCommandName(), command);
+ }
+ }
+ }
+}
+
lldb::SearchFilterSP
LanguageRuntime::CreateExceptionSearchFilter ()
{
diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp
index 934bc967b68b..e61b3ab91e7b 100644
--- a/source/Target/Memory.cpp
+++ b/source/Target/Memory.cpp
@@ -14,8 +14,9 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
using namespace lldb;
@@ -25,11 +26,12 @@ using namespace lldb_private;
// MemoryCache constructor
//----------------------------------------------------------------------
MemoryCache::MemoryCache(Process &process) :
- m_process (process),
- m_cache_line_byte_size (process.GetMemoryCacheLineSize()),
m_mutex (Mutex::eMutexTypeRecursive),
- m_cache (),
- m_invalid_ranges ()
+ m_L1_cache (),
+ m_L2_cache (),
+ m_invalid_ranges (),
+ m_process (process),
+ m_L2_cache_line_byte_size (process.GetMemoryCacheLineSize())
{
}
@@ -44,10 +46,24 @@ void
MemoryCache::Clear(bool clear_invalid_ranges)
{
Mutex::Locker locker (m_mutex);
- m_cache.clear();
+ m_L1_cache.clear();
+ m_L2_cache.clear();
if (clear_invalid_ranges)
m_invalid_ranges.Clear();
- m_cache_line_byte_size = m_process.GetMemoryCacheLineSize();
+ m_L2_cache_line_byte_size = m_process.GetMemoryCacheLineSize();
+}
+
+void
+MemoryCache::AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len)
+{
+ AddL1CacheData(addr,DataBufferSP (new DataBufferHeap(DataBufferHeap(src, src_len))));
+}
+
+void
+MemoryCache::AddL1CacheData(lldb::addr_t addr, const DataBufferSP &data_buffer_sp)
+{
+ Mutex::Locker locker (m_mutex);
+ m_L1_cache[addr] = data_buffer_sp;
}
void
@@ -57,29 +73,44 @@ MemoryCache::Flush (addr_t addr, size_t size)
return;
Mutex::Locker locker (m_mutex);
- if (m_cache.empty())
- return;
- const uint32_t cache_line_byte_size = m_cache_line_byte_size;
- const addr_t end_addr = (addr + size - 1);
- const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size);
- const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size);
- // Watch for overflow where size will cause us to go off the end of the
- // 64 bit address space
- uint32_t num_cache_lines;
- if (last_cache_line_addr >= first_cache_line_addr)
- num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1;
- else
- num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
-
- uint32_t cache_idx = 0;
- for (addr_t curr_addr = first_cache_line_addr;
- cache_idx < num_cache_lines;
- curr_addr += cache_line_byte_size, ++cache_idx)
+ // Erase any blocks from the L1 cache that intersect with the flush range
+ if (!m_L1_cache.empty())
{
- BlockMap::iterator pos = m_cache.find (curr_addr);
- if (pos != m_cache.end())
- m_cache.erase(pos);
+ AddrRange flush_range(addr, size);
+ BlockMap::iterator pos = m_L1_cache.lower_bound(addr);
+ while (pos != m_L1_cache.end())
+ {
+ AddrRange chunk_range(pos->first, pos->second->GetByteSize());
+ if (!chunk_range.DoesIntersect(flush_range))
+ break;
+ pos = m_L1_cache.erase(pos);
+ }
+ }
+
+ if (!m_L2_cache.empty())
+ {
+ const uint32_t cache_line_byte_size = m_L2_cache_line_byte_size;
+ const addr_t end_addr = (addr + size - 1);
+ const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size);
+ const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size);
+ // Watch for overflow where size will cause us to go off the end of the
+ // 64 bit address space
+ uint32_t num_cache_lines;
+ if (last_cache_line_addr >= first_cache_line_addr)
+ num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1;
+ else
+ num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
+
+ uint32_t cache_idx = 0;
+ for (addr_t curr_addr = first_cache_line_addr;
+ cache_idx < num_cache_lines;
+ curr_addr += cache_line_byte_size, ++cache_idx)
+ {
+ BlockMap::iterator pos = m_L2_cache.find (curr_addr);
+ if (pos != m_L2_cache.end())
+ m_L2_cache.erase(pos);
+ }
}
}
@@ -122,6 +153,39 @@ MemoryCache::Read (addr_t addr,
{
size_t bytes_left = dst_len;
+ // Check the L1 cache for a range that contain the entire memory read.
+ // If we find a range in the L1 cache that does, we use it. Else we fall
+ // back to reading memory in m_L2_cache_line_byte_size byte sized chunks.
+ // The L1 cache contains chunks of memory that are not required to be
+ // m_L2_cache_line_byte_size bytes in size, so we don't try anything
+ // tricky when reading from them (no partial reads from the L1 cache).
+
+ Mutex::Locker locker(m_mutex);
+ if (!m_L1_cache.empty())
+ {
+ AddrRange read_range(addr, dst_len);
+ BlockMap::iterator pos = m_L1_cache.lower_bound(addr);
+ if (pos != m_L1_cache.end())
+ {
+ AddrRange chunk_range(pos->first, pos->second->GetByteSize());
+ bool match = chunk_range.Contains(read_range);
+ if (!match && pos != m_L1_cache.begin())
+ {
+ --pos;
+ chunk_range.SetRangeBase(pos->first);
+ chunk_range.SetByteSize(pos->second->GetByteSize());
+ match = chunk_range.Contains(read_range);
+ }
+
+ if (match)
+ {
+ memcpy(dst, pos->second->GetBytes() + addr - chunk_range.GetRangeBase(), dst_len);
+ return dst_len;
+ }
+ }
+ }
+
+
// If this memory read request is larger than the cache line size, then
// we (1) try to read as much of it at once as possible, and (2) don't
// add the data to the memory cache. We don't want to split a big read
@@ -129,19 +193,22 @@ MemoryCache::Read (addr_t addr,
// request, it is unlikely that the caller function will ask for the next
// 4 bytes after the large memory read - so there's little benefit to saving
// it in the cache.
- if (dst && dst_len > m_cache_line_byte_size)
+ if (dst && dst_len > m_L2_cache_line_byte_size)
{
- return m_process.ReadMemoryFromInferior (addr, dst, dst_len, error);
+ size_t bytes_read = m_process.ReadMemoryFromInferior (addr, dst, dst_len, error);
+ // Add this non block sized range to the L1 cache if we actually read anything
+ if (bytes_read > 0)
+ AddL1CacheData(addr, dst, bytes_read);
+ return bytes_read;
}
if (dst && bytes_left > 0)
{
- const uint32_t cache_line_byte_size = m_cache_line_byte_size;
+ const uint32_t cache_line_byte_size = m_L2_cache_line_byte_size;
uint8_t *dst_buf = (uint8_t *)dst;
addr_t curr_addr = addr - (addr % cache_line_byte_size);
addr_t cache_offset = addr - curr_addr;
- Mutex::Locker locker (m_mutex);
-
+
while (bytes_left > 0)
{
if (m_invalid_ranges.FindEntryThatContains(curr_addr))
@@ -150,8 +217,8 @@ MemoryCache::Read (addr_t addr,
return dst_len - bytes_left;
}
- BlockMap::const_iterator pos = m_cache.find (curr_addr);
- BlockMap::const_iterator end = m_cache.end ();
+ BlockMap::const_iterator pos = m_L2_cache.find (curr_addr);
+ BlockMap::const_iterator end = m_L2_cache.end ();
if (pos != end)
{
@@ -208,7 +275,7 @@ MemoryCache::Read (addr_t addr,
if (process_bytes_read != cache_line_byte_size)
data_buffer_heap_ap->SetByteSize (process_bytes_read);
- m_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release());
+ m_L2_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release());
// We have read data and put it into the cache, continue through the
// loop again to get the data out of the cache...
}
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index 3d7a9021343a..e54dd5b4920a 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -43,7 +44,6 @@ ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
m_complete_class_cache(),
m_negative_complete_class_cache()
{
-
}
bool
@@ -497,6 +497,18 @@ ObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name)
return end;
}
+std::pair<ObjCLanguageRuntime::ISAToDescriptorIterator,ObjCLanguageRuntime::ISAToDescriptorIterator>
+ObjCLanguageRuntime::GetDescriptorIteratorPair (bool update_if_needed)
+{
+ if (update_if_needed)
+ UpdateISAToDescriptorMapIfNeeded();
+
+ return std::pair<ObjCLanguageRuntime::ISAToDescriptorIterator,
+ ObjCLanguageRuntime::ISAToDescriptorIterator>(
+ m_isa_to_descriptor.begin(),
+ m_isa_to_descriptor.end());
+}
+
ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
@@ -670,3 +682,36 @@ ObjCLanguageRuntime::GetTypeBitSize (const ClangASTType& clang_type,
return found;
}
+
+//------------------------------------------------------------------
+// Exception breakpoint Precondition class for ObjC:
+//------------------------------------------------------------------
+void
+ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(const char *class_name)
+{
+ m_class_names.insert(class_name);
+}
+
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition()
+{
+}
+
+bool
+ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition(StoppointCallbackContext &context)
+{
+ return true;
+}
+
+void
+ObjCLanguageRuntime::ObjCExceptionPrecondition::DescribePrecondition(Stream &stream, lldb::DescriptionLevel level)
+{
+}
+
+Error
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition(Args &args)
+{
+ Error error;
+ if (args.GetArgumentCount() > 0)
+ error.SetErrorString("The ObjC Exception breakpoint doesn't support extra options.");
+ return error;
+}
diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp
index 09c9efc14b08..6758ecf7e22e 100644
--- a/source/Target/Platform.cpp
+++ b/source/Target/Platform.cpp
@@ -10,25 +10,47 @@
#include "lldb/Target/Platform.h"
// C Includes
+
// C++ Includes
+#include <algorithm>
+#include <fstream>
+#include <vector>
+
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointIDList.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
+#include "llvm/Support/FileSystem.h"
+
+#include "Utility/ModuleCache.h"
+
+// Define these constants from POSIX mman.h rather than include the file
+// so that they will be correct even when compiled on Linux.
+#define MAP_PRIVATE 2
+#define MAP_ANON 0x1000
using namespace lldb;
using namespace lldb_private;
-
+
+static uint32_t g_initialize_count = 0;
+
// Use a singleton function for g_local_platform_sp to avoid init
// constructors since LLDB is often part of a shared library
static PlatformSP&
@@ -44,6 +66,73 @@ Platform::GetHostPlatformName ()
return "host";
}
+namespace {
+
+ PropertyDefinition
+ g_properties[] =
+ {
+ { "use-module-cache" , OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "Use module cache." },
+ { "module-cache-directory", OptionValue::eTypeFileSpec, true, 0 , nullptr, nullptr, "Root directory for cached modules." },
+ { nullptr , OptionValue::eTypeInvalid , false, 0, nullptr, nullptr, nullptr }
+ };
+
+ enum
+ {
+ ePropertyUseModuleCache,
+ ePropertyModuleCacheDirectory
+ };
+
+} // namespace
+
+
+ConstString
+PlatformProperties::GetSettingName ()
+{
+ static ConstString g_setting_name("platform");
+ return g_setting_name;
+}
+
+PlatformProperties::PlatformProperties ()
+{
+ m_collection_sp.reset (new OptionValueProperties (GetSettingName ()));
+ m_collection_sp->Initialize (g_properties);
+
+ auto module_cache_dir = GetModuleCacheDirectory ();
+ if (!module_cache_dir)
+ {
+ if (!HostInfo::GetLLDBPath (ePathTypeGlobalLLDBTempSystemDir, module_cache_dir))
+ module_cache_dir = FileSpec ("/tmp/lldb", false);
+ module_cache_dir.AppendPathComponent ("module_cache");
+ SetModuleCacheDirectory (module_cache_dir);
+ }
+}
+
+bool
+PlatformProperties::GetUseModuleCache () const
+{
+ const auto idx = ePropertyUseModuleCache;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
+PlatformProperties::SetUseModuleCache (bool use_module_cache)
+{
+ return m_collection_sp->SetPropertyAtIndexAsBoolean (nullptr, ePropertyUseModuleCache, use_module_cache);
+}
+
+FileSpec
+PlatformProperties::GetModuleCacheDirectory () const
+{
+ return m_collection_sp->GetPropertyAtIndexAsFileSpec (nullptr, ePropertyModuleCacheDirectory);
+}
+
+bool
+PlatformProperties::SetModuleCacheDirectory (const FileSpec& dir_spec)
+{
+ return m_collection_sp->SetPropertyAtIndexAsFileSpec (nullptr, ePropertyModuleCacheDirectory, dir_spec);
+}
+
//------------------------------------------------------------------
/// Get the native host platform plug-in.
///
@@ -75,6 +164,32 @@ GetPlatformListMutex ()
}
void
+Platform::Initialize ()
+{
+ g_initialize_count++;
+}
+
+void
+Platform::Terminate ()
+{
+ if (g_initialize_count > 0)
+ {
+ if (--g_initialize_count == 0)
+ {
+ Mutex::Locker locker(GetPlatformListMutex ());
+ GetPlatformList().clear();
+ }
+ }
+}
+
+const PlatformPropertiesSP &
+Platform::GetGlobalPlatformProperties ()
+{
+ static const auto g_settings_sp (std::make_shared<PlatformProperties> ());
+ return g_settings_sp;
+}
+
+void
Platform::SetHostPlatform (const lldb::PlatformSP &platform_sp)
{
// The native platform should use its static void Platform::Initialize()
@@ -137,25 +252,43 @@ Platform::LocateExecutableScriptingResources (Target *target, Module &module, St
Error
Platform::GetSharedModule (const ModuleSpec &module_spec,
+ Process* process,
ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr,
bool *did_create_ptr)
{
- // Don't do any path remapping for the default implementation
- // of the platform GetSharedModule function, just call through
- // to our static ModuleList function. Platform subclasses that
- // implement remote debugging, might have a developer kits
- // installed that have cached versions of the files for the
- // remote target, or might implement a download and cache
- // locally implementation.
- const bool always_create = false;
- return ModuleList::GetSharedModule (module_spec,
- module_sp,
- module_search_paths_ptr,
- old_module_sp_ptr,
- did_create_ptr,
- always_create);
+ if (IsHost ())
+ return ModuleList::GetSharedModule (module_spec,
+ module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr,
+ did_create_ptr,
+ false);
+
+ return GetRemoteSharedModule (module_spec,
+ process,
+ module_sp,
+ [&](const ModuleSpec &spec)
+ {
+ return ModuleList::GetSharedModule (
+ spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr, false);
+ },
+ did_create_ptr);
+}
+
+bool
+Platform::GetModuleSpec (const FileSpec& module_file_spec,
+ const ArchSpec& arch,
+ ModuleSpec &module_spec)
+{
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications (module_file_spec, 0, 0, module_specs) == 0)
+ return false;
+
+ ModuleSpec matched_module_spec;
+ return module_specs.FindMatchingModuleSpec (ModuleSpec (module_file_spec, arch),
+ module_spec);
}
PlatformSP
@@ -298,7 +431,8 @@ Platform::Platform (bool is_host) :
m_ssh_opts (),
m_ignores_remote_hostname (false),
m_trap_handlers(),
- m_calculated_trap_handlers (false)
+ m_calculated_trap_handlers (false),
+ m_module_cache (llvm::make_unique<ModuleCache> ())
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
@@ -476,16 +610,16 @@ Platform::AddClangModuleCompilationOptions (Target *target, std::vector<std::str
}
-ConstString
+FileSpec
Platform::GetWorkingDirectory ()
{
if (IsHost())
{
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)))
- return ConstString(cwd);
+ return FileSpec{cwd, true};
else
- return ConstString();
+ return FileSpec{};
}
else
{
@@ -524,11 +658,11 @@ RecurseCopy_Callback (void *baton,
FileSpec dst_dir = rc_baton->dst;
if (!dst_dir.GetFilename())
dst_dir.GetFilename() = src.GetLastPathComponent();
- std::string dst_dir_path (dst_dir.GetPath());
- Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir_path.c_str(), lldb::eFilePermissionsDirectoryDefault);
+ Error error = rc_baton->platform_ptr->MakeDirectory(dst_dir, lldb::eFilePermissionsDirectoryDefault);
if (error.Fail())
{
- rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end", dst_dir_path.c_str());
+ rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",
+ dst_dir.GetCString());
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
}
@@ -556,15 +690,15 @@ RecurseCopy_Callback (void *baton,
FileSpec dst_file = rc_baton->dst;
if (!dst_file.GetFilename())
dst_file.GetFilename() = src.GetFilename();
-
- char buf[PATH_MAX];
- rc_baton->error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
+ FileSpec src_resolved;
+
+ rc_baton->error = FileSystem::Readlink(src, src_resolved);
if (rc_baton->error.Fail())
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
-
- rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file.GetPath().c_str(), buf);
+
+ rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved);
if (rc_baton->error.Fail())
return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
@@ -611,7 +745,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
if (!fixed_dst.GetFilename())
fixed_dst.GetFilename() = src.GetFilename();
- ConstString working_dir = GetWorkingDirectory();
+ FileSpec working_dir = GetWorkingDirectory();
if (dst)
{
@@ -631,8 +765,8 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
std::string path;
if (working_dir)
{
- relative_spec.SetFile(working_dir.GetCString(), false);
- relative_spec.AppendPathComponent(dst.GetPath().c_str());
+ relative_spec = working_dir;
+ relative_spec.AppendPathComponent(dst.GetPath());
fixed_dst.GetDirectory() = relative_spec.GetDirectory();
}
else
@@ -646,7 +780,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
{
if (working_dir)
{
- fixed_dst.GetDirectory() = working_dir;
+ fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
}
else
{
@@ -659,7 +793,7 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
{
if (working_dir)
{
- fixed_dst.GetDirectory() = working_dir;
+ fixed_dst.GetDirectory().SetCString(working_dir.GetCString());
}
else
{
@@ -682,18 +816,17 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
case FileSpec::eFileTypeDirectory:
{
if (GetFileExists (fixed_dst))
- Unlink (fixed_dst.GetPath().c_str());
+ Unlink(fixed_dst);
uint32_t permissions = src.GetPermissions();
if (permissions == 0)
permissions = eFilePermissionsDirectoryDefault;
- std::string dst_dir_path(fixed_dst.GetPath());
- error = MakeDirectory(dst_dir_path.c_str(), permissions);
+ error = MakeDirectory(fixed_dst, permissions);
if (error.Success())
{
// Make a filespec that only fills in the directory of a FileSpec so
// when we enumerate we can quickly fill in the filename for dst copies
FileSpec recurse_dst;
- recurse_dst.GetDirectory().SetCString(dst_dir_path.c_str());
+ recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString());
std::string src_dir_path (src.GetPath());
RecurseCopyBaton baton = { recurse_dst, this, Error() };
FileSpec::EnumerateDirectory(src_dir_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
@@ -704,18 +837,18 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
case FileSpec::eFileTypeRegular:
if (GetFileExists (fixed_dst))
- Unlink (fixed_dst.GetPath().c_str());
+ Unlink(fixed_dst);
error = PutFile(src, fixed_dst);
break;
case FileSpec::eFileTypeSymbolicLink:
{
if (GetFileExists (fixed_dst))
- Unlink (fixed_dst.GetPath().c_str());
- char buf[PATH_MAX];
- error = FileSystem::Readlink(src.GetPath().c_str(), buf, sizeof(buf));
+ Unlink(fixed_dst);
+ FileSpec src_resolved;
+ error = FileSystem::Readlink(src, src_resolved);
if (error.Success())
- error = CreateSymlink(dst.GetPath().c_str(), buf);
+ error = CreateSymlink(dst, src_resolved);
}
break;
case FileSpec::eFileTypePipe:
@@ -735,37 +868,33 @@ Platform::Install (const FileSpec& src, const FileSpec& dst)
}
bool
-Platform::SetWorkingDirectory (const ConstString &path)
+Platform::SetWorkingDirectory(const FileSpec &file_spec)
{
if (IsHost())
{
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
- log->Printf("Platform::SetWorkingDirectory('%s')", path.GetCString());
-#ifdef _WIN32
- // Not implemented on Windows
- return false;
-#else
- if (path)
+ log->Printf("Platform::SetWorkingDirectory('%s')",
+ file_spec.GetCString());
+ if (file_spec)
{
- if (chdir(path.GetCString()) == 0)
+ if (::chdir(file_spec.GetCString()) == 0)
return true;
}
return false;
-#endif
}
else
{
m_working_dir.Clear();
- return SetRemoteWorkingDirectory(path);
+ return SetRemoteWorkingDirectory(file_spec);
}
}
Error
-Platform::MakeDirectory (const char *path, uint32_t permissions)
+Platform::MakeDirectory(const FileSpec &file_spec, uint32_t permissions)
{
if (IsHost())
- return FileSystem::MakeDirectory(path, permissions);
+ return FileSystem::MakeDirectory(file_spec, permissions);
else
{
Error error;
@@ -775,10 +904,10 @@ Platform::MakeDirectory (const char *path, uint32_t permissions)
}
Error
-Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
+Platform::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
{
if (IsHost())
- return FileSystem::GetFilePermissions(path, file_permissions);
+ return FileSystem::GetFilePermissions(file_spec, file_permissions);
else
{
Error error;
@@ -788,10 +917,10 @@ Platform::GetFilePermissions (const char *path, uint32_t &file_permissions)
}
Error
-Platform::SetFilePermissions (const char *path, uint32_t file_permissions)
+Platform::SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
{
if (IsHost())
- return FileSystem::SetFilePermissions(path, file_permissions);
+ return FileSystem::SetFilePermissions(file_spec, file_permissions);
else
{
Error error;
@@ -818,12 +947,13 @@ Platform::GetHostname ()
}
bool
-Platform::SetRemoteWorkingDirectory(const ConstString &path)
+Platform::SetRemoteWorkingDirectory(const FileSpec &working_dir)
{
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
if (log)
- log->Printf("Platform::SetRemoteWorkingDirectory('%s')", path.GetCString());
- m_working_dir = path;
+ log->Printf("Platform::SetRemoteWorkingDirectory('%s')",
+ working_dir.GetCString());
+ m_working_dir = working_dir;
return true;
}
@@ -1092,6 +1222,12 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
num_resumes))
return error;
}
+ else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments))
+ {
+ error = ShellExpandArguments(launch_info);
+ if (error.Fail())
+ return error;
+ }
if (log)
log->Printf ("Platform::%s final launch_info resume count: %" PRIu32, __FUNCTION__, launch_info.GetResumeCount ());
@@ -1104,16 +1240,41 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
}
Error
+Platform::ShellExpandArguments (ProcessLaunchInfo &launch_info)
+{
+ if (IsHost())
+ return Host::ShellExpandArguments(launch_info);
+ return Error("base lldb_private::Platform class can't expand arguments");
+}
+
+Error
Platform::KillProcess (const lldb::pid_t pid)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
if (log)
log->Printf ("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
- if (!IsHost ())
- return Error ("base lldb_private::Platform class can't launch remote processes");
+ // Try to find a process plugin to handle this Kill request. If we can't, fall back to
+ // the default OS implementation.
+ size_t num_debuggers = Debugger::GetNumDebuggers();
+ for (size_t didx = 0; didx < num_debuggers; ++didx)
+ {
+ DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx);
+ lldb_private::TargetList &targets = debugger->GetTargetList();
+ for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx)
+ {
+ ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP();
+ if (process->GetID() == pid)
+ return process->Destroy(true);
+ }
+ }
- Host::Kill (pid, SIGTERM);
+ if (!IsHost())
+ {
+ return Error("base lldb_private::Platform class can't kill remote processes unless "
+ "they are controlled by a process plugin");
+ }
+ Host::Kill(pid, SIGTERM);
return Error();
}
@@ -1251,7 +1412,7 @@ Platform::PutFile (const FileSpec& source,
if (log)
log->Printf("[PutFile] Using block by block transfer....\n");
- uint32_t source_open_options = File::eOpenOptionRead;
+ uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink)
source_open_options |= File::eOpenoptionDontFollowSymlinks;
@@ -1266,7 +1427,8 @@ Platform::PutFile (const FileSpec& source,
lldb::user_id_t dest_file = OpenFile (destination,
File::eOpenOptionCanCreate |
File::eOpenOptionWrite |
- File::eOpenOptionTruncate,
+ File::eOpenOptionTruncate |
+ File::eOpenOptionCloseOnExec,
permissions,
error);
if (log)
@@ -1309,43 +1471,52 @@ Platform::PutFile (const FileSpec& source,
}
Error
-Platform::GetFile (const FileSpec& source,
- const FileSpec& destination)
+Platform::GetFile(const FileSpec &source,
+ const FileSpec &destination)
{
Error error("unimplemented");
return error;
}
Error
-Platform::CreateSymlink (const char *src, // The name of the link is in src
- const char *dst)// The symlink points to dst
+Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src
+ const FileSpec &dst) // The symlink points to dst
{
Error error("unimplemented");
return error;
}
bool
-Platform::GetFileExists (const lldb_private::FileSpec& file_spec)
+Platform::GetFileExists(const lldb_private::FileSpec &file_spec)
{
return false;
}
Error
-Platform::Unlink (const char *path)
+Platform::Unlink(const FileSpec &path)
{
Error error("unimplemented");
return error;
}
-
+uint64_t
+Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch, unsigned flags)
+{
+ uint64_t flags_platform = 0;
+ if (flags & eMmapFlagsPrivate)
+ flags_platform |= MAP_PRIVATE;
+ if (flags & eMmapFlagsAnon)
+ flags_platform |= MAP_ANON;
+ return flags_platform;
+}
lldb_private::Error
-Platform::RunShellCommand (const char *command, // Shouldn't be NULL
- const char *working_dir, // Pass NULL to use the current working directory
- int *status_ptr, // Pass NULL if you don't want the process exit status
- int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
- std::string *command_output, // Pass NULL if you don't want the command output
- uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
+Platform::RunShellCommand(const char *command, // Shouldn't be NULL
+ const FileSpec &working_dir, // Pass empty FileSpec to use the current working directory
+ int *status_ptr, // Pass NULL if you don't want the process exit status
+ int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
+ std::string *command_output, // Pass NULL if you don't want the command output
+ uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish
{
if (IsHost())
return Host::RunShellCommand (command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec);
@@ -1609,3 +1780,174 @@ Platform::GetTrapHandlerSymbolNames ()
return m_trap_handlers;
}
+Error
+Platform::GetCachedExecutable (ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform)
+{
+ const auto platform_spec = module_spec.GetFileSpec ();
+ const auto error = LoadCachedExecutable (module_spec,
+ module_sp,
+ module_search_paths_ptr,
+ remote_platform);
+ if (error.Success ())
+ {
+ module_spec.GetFileSpec () = module_sp->GetFileSpec ();
+ module_spec.GetPlatformFileSpec () = platform_spec;
+ }
+
+ return error;
+}
+
+Error
+Platform::LoadCachedExecutable (const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ Platform &remote_platform)
+{
+ return GetRemoteSharedModule (module_spec,
+ nullptr,
+ module_sp,
+ [&](const ModuleSpec &spec)
+ {
+ return remote_platform.ResolveExecutable (
+ spec, module_sp, module_search_paths_ptr);
+ },
+ nullptr);
+}
+
+Error
+Platform::GetRemoteSharedModule (const ModuleSpec &module_spec,
+ Process* process,
+ lldb::ModuleSP &module_sp,
+ const ModuleResolver &module_resolver,
+ bool *did_create_ptr)
+{
+ // Get module information from a target.
+ ModuleSpec resolved_module_spec;
+ bool got_module_spec = false;
+ if (process)
+ {
+ // Try to get module information from the process
+ if (process->GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
+ got_module_spec = true;
+ }
+
+ if (!got_module_spec)
+ {
+ // Get module information from a target.
+ if (!GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
+ return module_resolver (module_spec);
+ }
+
+ // Trying to find a module by UUID on local file system.
+ const auto error = module_resolver (resolved_module_spec);
+ if (error.Fail ())
+ {
+ if (GetCachedSharedModule (resolved_module_spec, module_sp, did_create_ptr))
+ return Error ();
+ }
+
+ return error;
+}
+
+bool
+Platform::GetCachedSharedModule (const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ bool *did_create_ptr)
+{
+ if (IsHost() ||
+ !GetGlobalPlatformProperties ()->GetUseModuleCache ())
+ return false;
+
+ Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+
+ // Check local cache for a module.
+ auto error = m_module_cache->GetAndPut (
+ GetModuleCacheRoot (),
+ GetCacheHostname (),
+ module_spec,
+ [=](const ModuleSpec &module_spec, const FileSpec &tmp_download_file_spec)
+ {
+ return DownloadModuleSlice (module_spec.GetFileSpec (),
+ module_spec.GetObjectOffset (),
+ module_spec.GetObjectSize (),
+ tmp_download_file_spec);
+
+ },
+ module_sp,
+ did_create_ptr);
+ if (error.Success ())
+ return true;
+
+ if (log)
+ log->Printf("Platform::%s - module %s not found in local cache: %s",
+ __FUNCTION__, module_spec.GetUUID ().GetAsString ().c_str (), error.AsCString ());
+ return false;
+}
+
+Error
+Platform::DownloadModuleSlice (const FileSpec& src_file_spec,
+ const uint64_t src_offset,
+ const uint64_t src_size,
+ const FileSpec& dst_file_spec)
+{
+ Error error;
+
+ std::ofstream dst (dst_file_spec.GetPath(), std::ios::out | std::ios::binary);
+ if (!dst.is_open())
+ {
+ error.SetErrorStringWithFormat ("unable to open destination file: %s", dst_file_spec.GetPath ().c_str ());
+ return error;
+ }
+
+ auto src_fd = OpenFile (src_file_spec,
+ File::eOpenOptionRead,
+ lldb::eFilePermissionsFileDefault,
+ error);
+
+ if (error.Fail ())
+ {
+ error.SetErrorStringWithFormat ("unable to open source file: %s", error.AsCString ());
+ return error;
+ }
+
+ std::vector<char> buffer (1024);
+ auto offset = src_offset;
+ uint64_t total_bytes_read = 0;
+ while (total_bytes_read < src_size)
+ {
+ const auto to_read = std::min (static_cast<uint64_t>(buffer.size ()), src_size - total_bytes_read);
+ const uint64_t n_read = ReadFile (src_fd, offset, &buffer[0], to_read, error);
+ if (error.Fail ())
+ break;
+ if (n_read == 0)
+ {
+ error.SetErrorString ("read 0 bytes");
+ break;
+ }
+ offset += n_read;
+ total_bytes_read += n_read;
+ dst.write (&buffer[0], n_read);
+ }
+
+ Error close_error;
+ CloseFile (src_fd, close_error); // Ignoring close error.
+
+ return error;
+}
+
+FileSpec
+Platform::GetModuleCacheRoot ()
+{
+ auto dir_spec = GetGlobalPlatformProperties ()->GetModuleCacheDirectory ();
+ dir_spec.AppendPathComponent (GetName ().AsCString ());
+ return dir_spec;
+}
+
+const char *
+Platform::GetCacheHostname ()
+{
+ return GetHostname ();
+}
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index f7a26f676aba..41942829ca55 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -7,22 +7,19 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/Process.h"
-
-#include "lldb/lldb-private-log.h"
-
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -30,11 +27,15 @@
#include "lldb/Host/Terminal.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/JITLoader.h"
+#include "lldb/Target/JITLoaderList.h"
#include "lldb/Target/MemoryHistory.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"
@@ -48,7 +49,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanBase.h"
-#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/NameMatches.h"
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
using namespace lldb;
@@ -430,7 +432,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'i': // STDIN for read only
{
FileAction action;
- if (action.Open (STDIN_FILENO, option_arg, true, false))
+ if (action.Open(STDIN_FILENO, FileSpec{option_arg, false}, true, false))
launch_info.AppendFileAction (action);
break;
}
@@ -438,7 +440,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'o': // Open STDOUT for write only
{
FileAction action;
- if (action.Open (STDOUT_FILENO, option_arg, false, true))
+ if (action.Open(STDOUT_FILENO, FileSpec{option_arg, false}, false, true))
launch_info.AppendFileAction (action);
break;
}
@@ -446,7 +448,7 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'e': // STDERR for write only
{
FileAction action;
- if (action.Open (STDERR_FILENO, option_arg, false, true))
+ if (action.Open(STDERR_FILENO, FileSpec{option_arg, false}, false, true))
launch_info.AppendFileAction (action);
break;
}
@@ -458,17 +460,18 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
case 'n': // Disable STDIO
{
FileAction action;
- if (action.Open (STDIN_FILENO, "/dev/null", true, false))
+ const FileSpec dev_null{"/dev/null", false};
+ if (action.Open(STDIN_FILENO, dev_null, true, false))
launch_info.AppendFileAction (action);
- if (action.Open (STDOUT_FILENO, "/dev/null", false, true))
+ if (action.Open(STDOUT_FILENO, dev_null, false, true))
launch_info.AppendFileAction (action);
- if (action.Open (STDERR_FILENO, "/dev/null", false, true))
+ if (action.Open(STDERR_FILENO, dev_null, false, true))
launch_info.AppendFileAction (action);
break;
}
case 'w':
- launch_info.SetWorkingDirectory (option_arg);
+ launch_info.SetWorkingDirectory(FileSpec{option_arg, false});
break;
case 't': // Open process in new terminal window
@@ -491,6 +494,17 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
break;
}
+ case 'X': // shell expand args.
+ {
+ bool success;
+ const bool expand_args = Args::StringToBoolean (option_arg, true, &success);
+ if (success)
+ launch_info.SetShellExpandArguments(expand_args);
+ else
+ error.SetErrorStringWithFormat ("Invalid boolean value for shell-expand-args option: '%s'", option_arg ? option_arg : "<null>");
+ break;
+ }
+
case 'c':
if (option_arg && option_arg[0])
launch_info.SetShell (FileSpec(option_arg, false));
@@ -518,7 +532,7 @@ ProcessLaunchCommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
{ LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."},
{ LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_ALL, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."},
{ LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>."},
{ LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>."},
@@ -527,7 +541,7 @@ ProcessLaunchCommandOptions::g_option_table[] =
{ LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."},
{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
-
+{ LLDB_OPT_SET_4, false, "shell-expand-args", 'X', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching."},
{ 0 , false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
@@ -688,7 +702,7 @@ Process::Process(Target &target, Listener &listener) :
Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_signals_sp) :
ProcessProperties (this),
UserID (LLDB_INVALID_PROCESS_ID),
- Broadcaster (&(target.GetDebugger()), "lldb.process"),
+ Broadcaster (&(target.GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()),
m_target (target),
m_public_state (eStateUnloaded),
m_private_state (eStateUnloaded),
@@ -720,12 +734,12 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s
m_process_input_reader (),
m_stdio_communication ("process.stdio"),
m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
- m_stdio_disable(true),
+ m_stdin_forward (false),
m_stdout_data (),
m_stderr_data (),
m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
m_profile_data (),
- m_iohandler_sync (false),
+ m_iohandler_sync (0),
m_memory_cache (*this),
m_allocated_memory_cache (*this),
m_should_detach (false),
@@ -734,9 +748,10 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s
m_private_run_lock (),
m_currently_handling_event(false),
m_stop_info_override_callback (NULL),
- m_finalize_called(false),
+ m_finalizing (false),
+ m_finalize_called (false),
m_clear_thread_plans_on_stop (false),
- m_force_next_event_delivery(false),
+ m_force_next_event_delivery (false),
m_last_broadcast_state (eStateInvalid),
m_destroy_in_process (false),
m_can_jit(eCanJITDontKnow)
@@ -807,6 +822,9 @@ Process::GetGlobalProperties()
void
Process::Finalize()
{
+ m_finalizing = true;
+
+ // Destroy this process if needed
switch (GetPrivateState())
{
case eStateConnected:
@@ -817,14 +835,7 @@ Process::Finalize()
case eStateStepping:
case eStateCrashed:
case eStateSuspended:
- if (GetShouldDetach())
- {
- // FIXME: This will have to be a process setting:
- bool keep_stopped = false;
- Detach(keep_stopped);
- }
- else
- Destroy();
+ Destroy(false);
break;
case eStateInvalid:
@@ -862,6 +873,9 @@ Process::Finalize()
m_instrumentation_runtimes.clear();
m_next_event_action_ap.reset();
m_stop_info_override_callback = NULL;
+ // Clear the last natural stop ID since it has a strong
+ // reference to this process
+ m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
//#ifdef LLDB_CONFIGURATION_DEBUG
// StreamFile s(stdout, false);
// EventSP event_sp;
@@ -937,33 +951,21 @@ Process::GetNextEvent (EventSP &event_sp)
return state;
}
-bool
-Process::SyncIOHandler (uint64_t timeout_msec)
+void
+Process::SyncIOHandler (uint32_t iohandler_id, uint64_t timeout_msec)
{
- bool timed_out = false;
-
// don't sync (potentially context switch) in case where there is no process IO
- if (m_process_input_reader)
- {
- TimeValue timeout = TimeValue::Now();
- timeout.OffsetWithMicroSeconds(timeout_msec*1000);
-
- m_iohandler_sync.WaitForValueEqualTo(true, &timeout, &timed_out);
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
- if(log)
- {
- if(timed_out)
- log->Printf ("Process::%s pid %" PRIu64 " (timeout=%" PRIu64 "ms): FAIL", __FUNCTION__, GetID (), timeout_msec);
- else
- log->Printf ("Process::%s pid %" PRIu64 ": SUCCESS", __FUNCTION__, GetID ());
- }
+ if (! m_process_input_reader)
+ return;
- // reset sync one-shot so it will be ready for next launch
- m_iohandler_sync.SetValue(false, eBroadcastNever);
- }
+ TimeValue timeout = TimeValue::Now();
+ timeout.OffsetWithMicroSeconds(timeout_msec*1000);
+ uint32_t new_iohandler_id = 0;
+ m_iohandler_sync.WaitForValueNotEqualTo(iohandler_id, new_iohandler_id, &timeout);
- return !timed_out;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("Process::%s waited for m_iohandler_sync to change from %u, new value is %u", __FUNCTION__, iohandler_id, new_iohandler_id);
}
StateType
@@ -991,10 +993,15 @@ Process::WaitForProcessToStop (const TimeValue *timeout,
if (!wait_always &&
StateIsStoppedState(state, true) &&
- StateIsStoppedState(GetPrivateState(), true)) {
+ StateIsStoppedState(GetPrivateState(), true))
+ {
if (log)
log->Printf("Process::%s returning without waiting for events; process private and public states are already 'stopped'.",
__FUNCTION__);
+ // We need to toggle the run lock as this won't get done in
+ // SetPublicState() if the process is hijacked.
+ if (hijack_listener)
+ m_public_run_lock.SetStopped();
return state;
}
@@ -1422,6 +1429,9 @@ Process::GetExitDescription ()
bool
Process::SetExitStatus (int status, const char *cstr)
{
+ // Use a mutex to protect setting the exit status.
+ Mutex::Locker locker (m_exit_status_mutex);
+
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("Process::SetExitStatus (status=%i (0x%8.8x), description=%s%s%s)",
@@ -1437,21 +1447,35 @@ Process::SetExitStatus (int status, const char *cstr)
log->Printf("Process::SetExitStatus () ignoring exit status because state was already set to eStateExited");
return false;
}
-
- // use a mutex to protect the status and string during updating
- {
- Mutex::Locker locker (m_exit_status_mutex);
- m_exit_status = status;
- if (cstr)
- m_exit_string = cstr;
- else
- m_exit_string.clear();
+ m_exit_status = status;
+ if (cstr)
+ m_exit_string = cstr;
+ else
+ m_exit_string.clear();
+
+ // When we exit, we no longer need to the communication channel
+ m_stdio_communication.Disconnect();
+ m_stdio_communication.StopReadThread();
+ m_stdin_forward = false;
+
+ // And we don't need the input reader anymore as well
+ if (m_process_input_reader)
+ {
+ m_process_input_reader->SetIsDone(true);
+ m_process_input_reader->Cancel();
+ m_process_input_reader.reset();
}
- DidExit ();
+ // Clear the last natural stop ID since it has a strong
+ // reference to this process
+ m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
SetPrivateState (eStateExited);
+
+ // Allow subclasses to do some cleanup
+ DidExit ();
+
return true;
}
@@ -1531,10 +1555,24 @@ Process::UpdateThreadListIfNeeded ()
for (size_t i=0; i<num_old_threads; ++i)
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
+ // Turn off dynamic types to ensure we don't run any expressions. Objective C
+ // can run an expression to determine if a SBValue is a dynamic type or not
+ // and we need to avoid this. OperatingSystem plug-ins can't run expressions
+ // that require running code...
+
+ Target &target = GetTarget();
+ const lldb::DynamicValueType saved_prefer_dynamic = target.GetPreferDynamicValue ();
+ if (saved_prefer_dynamic != lldb::eNoDynamicValues)
+ target.SetPreferDynamicValue(lldb::eNoDynamicValues);
+
// Now let the OperatingSystem plug-in update the thread list
+
os->UpdateThreadList (old_thread_list, // Old list full of threads created by OS plug-in
real_thread_list, // The actual thread list full of threads created by each lldb_private::Process subclass
new_thread_list); // The new thread list that we will show to the user that gets filled in
+
+ if (saved_prefer_dynamic != lldb::eNoDynamicValues)
+ target.SetPreferDynamicValue(saved_prefer_dynamic);
}
else
{
@@ -1714,15 +1752,17 @@ Process::ResumeSynchronous (Stream *stream)
HijackProcessEvents(listener_sp.get());
Error error = PrivateResume();
-
- StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp.get(), stream);
+ if (error.Success())
+ {
+ StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp.get(), stream);
+ const bool must_be_alive = false; // eStateExited is ok, so this must be false
+ if (!StateIsStoppedState(state, must_be_alive))
+ error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
+ }
// Undo the hijacking of process events...
RestoreProcessEvents();
- if (error.Success() && !StateIsStoppedState(state, false))
- error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
-
return error;
}
@@ -1763,6 +1803,7 @@ Process::SetPrivateState (StateType new_state)
if (state_changed)
{
m_private_state.SetValueNoLock (new_state);
+ EventSP event_sp (new Event (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state)));
if (StateIsStoppedState(new_state, false))
{
// Note, this currently assumes that all threads in the list
@@ -1779,15 +1820,18 @@ Process::SetPrivateState (StateType new_state)
m_thread_list.DidStop();
m_mod_id.BumpStopID();
+ if (!m_mod_id.IsLastResumeForUserExpression())
+ m_mod_id.SetStopEventForLastNaturalStopID(event_sp);
m_memory_cache.Clear();
if (log)
log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_mod_id.GetStopID());
}
+
// Use our target to get a shared pointer to ourselves...
if (m_finalize_called && PrivateStateThreadIsValid() == false)
- BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+ BroadcastEvent (event_sp);
else
- m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+ m_private_state_broadcaster.BroadcastEvent (event_sp);
}
else
{
@@ -1819,6 +1863,12 @@ Process::GetImageInfoAddress()
uint32_t
Process::LoadImage (const FileSpec &image_spec, Error &error)
{
+ if (m_finalizing)
+ {
+ error.SetErrorString("process is tearing itself down");
+ return LLDB_INVALID_IMAGE_TOKEN;
+ }
+
char path[PATH_MAX];
image_spec.GetPath(path, sizeof(path));
@@ -1938,6 +1988,13 @@ Error
Process::UnloadImage (uint32_t image_token)
{
Error error;
+
+ if (m_finalizing)
+ {
+ error.SetErrorString("process is tearing itself down");
+ return error;
+ }
+
if (image_token < m_image_tokens.size())
{
const addr_t image_addr = m_image_tokens[image_token];
@@ -2020,6 +2077,9 @@ Process::GetABI()
LanguageRuntime *
Process::GetLanguageRuntime(lldb::LanguageType language, bool retry_if_null)
{
+ if (m_finalizing)
+ return nullptr;
+
LanguageRuntimeCollection::iterator pos;
pos = m_language_runtimes.find (language);
if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second))
@@ -2054,6 +2114,9 @@ Process::GetObjCLanguageRuntime (bool retry_if_null)
bool
Process::IsPossibleDynamicValue (ValueObject& in_value)
{
+ if (m_finalizing)
+ return false;
+
if (in_value.IsDynamic())
return false;
LanguageType known_type = in_value.GetObjectRuntimeLanguage();
@@ -2072,6 +2135,12 @@ Process::IsPossibleDynamicValue (ValueObject& in_value)
return objc_runtime ? objc_runtime->CouldHaveDynamicValue(in_value) : false;
}
+void
+Process::SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers)
+{
+ m_dynamic_checkers_ap.reset(dynamic_checkers);
+}
+
BreakpointSiteList &
Process::GetBreakpointSiteList()
{
@@ -2177,11 +2246,12 @@ Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardw
if (symbol && symbol->IsIndirect())
{
Error error;
- load_addr = ResolveIndirectFunction (&symbol->GetAddress(), error);
+ Address symbol_address = symbol->GetAddress();
+ load_addr = ResolveIndirectFunction (&symbol_address, error);
if (!error.Success() && show_error)
{
m_target.GetDebugger().GetErrorFile()->Printf ("warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
- symbol->GetAddress().GetLoadAddress(&m_target),
+ symbol->GetLoadAddress(&m_target),
owner->GetBreakpoint().GetID(),
owner->GetID(),
error.AsCString() ? error.AsCString() : "unknown error");
@@ -2403,7 +2473,7 @@ Process::DisableSoftwareBreakpoint (BreakpointSite *bp_site)
if (DoReadMemory (bp_addr, curr_break_op, break_op_size, error) == break_op_size)
{
bool verify = false;
- // Make sure we have the a breakpoint opcode exists at this address
+ // Make sure the breakpoint opcode exists at this address
if (::memcmp (curr_break_op, break_op, break_op_size) == 0)
{
break_op_found = true;
@@ -2968,6 +3038,33 @@ Process::ReadModuleFromMemory (const FileSpec& file_spec,
return ModuleSP();
}
+bool
+Process::GetLoadAddressPermissions (lldb::addr_t load_addr, uint32_t &permissions)
+{
+ MemoryRegionInfo range_info;
+ permissions = 0;
+ Error error (GetMemoryRegionInfo (load_addr, range_info));
+ if (!error.Success())
+ return false;
+ if (range_info.GetReadable() == MemoryRegionInfo::eDontKnow
+ || range_info.GetWritable() == MemoryRegionInfo::eDontKnow
+ || range_info.GetExecutable() == MemoryRegionInfo::eDontKnow)
+ {
+ return false;
+ }
+
+ if (range_info.GetReadable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsReadable;
+
+ if (range_info.GetWritable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsWritable;
+
+ if (range_info.GetExecutable() == MemoryRegionInfo::eYes)
+ permissions |= lldb::ePermissionsExecutable;
+
+ return true;
+}
+
Error
Process::EnableWatchpoint (Watchpoint *watchpoint, bool notify)
{
@@ -3090,8 +3187,9 @@ Process::Launch (ProcessLaunchInfo &launch_info)
{
// We were able to launch the process, but we failed to
// catch the initial stop.
+ error.SetErrorString ("failed to catch stop after launch");
SetExitStatus (0, "failed to catch stop after launch");
- Destroy();
+ Destroy(false);
}
else if (state == eStateStopped || state == eStateCrashed)
{
@@ -3125,7 +3223,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
// Target was stopped at entry as was intended. Need to notify the listeners
// about it.
- if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == true)
+ if (state == eStateStopped && launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
HandlePrivateEvent(event_sp);
}
else if (state == eStateExited)
@@ -3152,6 +3250,9 @@ Process::LoadCore ()
Error error = DoLoadCore();
if (error.Success())
{
+ Listener listener ("lldb.process.load_core_listener");
+ HijackProcessEvents(&listener);
+
if (PrivateStateThreadIsValid ())
ResumePrivateStateThread ();
else
@@ -3172,7 +3273,20 @@ Process::LoadCore ()
// show all of the threads in the core file and explore the crashed
// state.
SetPrivateState (eStateStopped);
-
+
+ // Wait indefinitely for a stopped event since we just posted one above...
+ lldb::EventSP event_sp;
+ listener.WaitForEvent (NULL, event_sp);
+ StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
+
+ if (!StateIsStoppedState (state, false))
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("Process::Halt() failed to stop, state is: %s", StateAsCString(state));
+ error.SetErrorString ("Did not get stopped event after loading the core file.");
+ }
+ RestoreProcessEvents ();
}
return error;
}
@@ -3230,6 +3344,9 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp)
switch (state)
{
+ case eStateAttaching:
+ return eEventActionSuccess;
+
case eStateRunning:
case eStateConnected:
return eEventActionRetry;
@@ -3702,7 +3819,7 @@ Process::Halt (bool clear_thread_plans)
RestorePrivateProcessEvents();
restored_process_events = true;
SetExitStatus(SIGKILL, "Cancelled async attach.");
- Destroy ();
+ Destroy (false);
}
else
{
@@ -3876,13 +3993,23 @@ Process::Detach (bool keep_stopped)
}
Error
-Process::Destroy ()
+Process::Destroy (bool force_kill)
{
// Tell ourselves we are in the process of destroying the process, so that we don't do any unnecessary work
// that might hinder the destruction. Remember to set this back to false when we are done. That way if the attempt
// failed and the process stays around for some reason it won't be in a confused state.
+
+ if (force_kill)
+ m_should_detach = false;
+ if (GetShouldDetach())
+ {
+ // FIXME: This will have to be a process setting:
+ bool keep_stopped = false;
+ Detach(keep_stopped);
+ }
+
m_destroy_in_process = true;
Error error (WillDestroy());
@@ -3910,9 +4037,9 @@ Process::Destroy ()
DidDestroy();
StopPrivateStateThread();
}
- m_stdio_communication.StopReadThread();
m_stdio_communication.Disconnect();
- m_stdio_disable = true;
+ m_stdio_communication.StopReadThread();
+ m_stdin_forward = false;
if (m_process_input_reader)
{
@@ -3954,6 +4081,20 @@ Process::Signal (int signal)
return error;
}
+void
+Process::SetUnixSignals (const UnixSignalsSP &signals_sp)
+{
+ assert (signals_sp && "null signals_sp");
+ m_unix_signals_sp = signals_sp;
+}
+
+UnixSignals &
+Process::GetUnixSignals ()
+{
+ assert (m_unix_signals_sp && "null m_unix_signals_sp");
+ return *m_unix_signals_sp;
+}
+
lldb::ByteOrder
Process::GetByteOrder () const
{
@@ -3976,12 +4117,14 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
switch (state)
{
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
case eStateDetached:
case eStateExited:
case eStateUnloaded:
+ m_stdio_communication.SynchronizeWithReadThread();
+ // fall-through
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
// These events indicate changes in the state of the debugging session, always report them.
return_value = true;
break;
@@ -4041,6 +4184,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
// If we aren't going to stop, let the thread plans decide if we're going to report this event.
// If no thread has an opinion, we don't report it.
+ m_stdio_communication.SynchronizeWithReadThread();
RefreshStateAfterStop ();
if (ProcessEventData::GetInterruptedFromEvent (event_ptr))
{
@@ -4128,7 +4272,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr)
bool
-Process::StartPrivateStateThread (bool force)
+Process::StartPrivateStateThread (bool is_secondary_thread)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
@@ -4136,7 +4280,7 @@ Process::StartPrivateStateThread (bool force)
if (log)
log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread");
- if (!force && already_running)
+ if (!is_secondary_thread && already_running)
return true;
// Create a thread that watches our internal state and controls which
@@ -4160,7 +4304,8 @@ Process::StartPrivateStateThread (bool force)
}
// Create the private state thread, and start it running.
- m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, this, NULL);
+ PrivateStateThreadArgs args = {this, is_secondary_thread};
+ m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL);
if (m_private_state_thread.IsJoinable())
{
ResumePrivateStateThread();
@@ -4324,13 +4469,17 @@ Process::HandlePrivateEvent (EventSP &event_sp)
// Only push the input handler if we aren't fowarding events,
// as this means the curses GUI is in use...
// Or don't push it if we are launching since it will come up stopped.
- if (!GetTarget().GetDebugger().IsForwardingEvents() && new_state != eStateLaunching)
+ if (!GetTarget().GetDebugger().IsForwardingEvents() && new_state != eStateLaunching &&
+ new_state != eStateAttaching)
+ {
PushProcessIOHandler ();
- m_iohandler_sync.SetValue(true, eBroadcastAlways);
+ m_iohandler_sync.SetValue(m_iohandler_sync.GetValue()+1, eBroadcastAlways);
+ if (log)
+ log->Printf("Process::%s updated m_iohandler_sync to %d", __FUNCTION__, m_iohandler_sync.GetValue());
+ }
}
else if (StateIsStoppedState(new_state, false))
{
- m_iohandler_sync.SetValue(false, eBroadcastNever);
if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
{
// If the lldb_private::Debugger is handling the events, we don't
@@ -4386,13 +4535,13 @@ Process::HandlePrivateEvent (EventSP &event_sp)
thread_result_t
Process::PrivateStateThread (void *arg)
{
- Process *proc = static_cast<Process*> (arg);
- thread_result_t result = proc->RunPrivateStateThread();
+ PrivateStateThreadArgs *real_args = static_cast<PrivateStateThreadArgs *> (arg);
+ thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread);
return result;
}
thread_result_t
-Process::RunPrivateStateThread ()
+Process::RunPrivateStateThread (bool is_secondary_thread)
{
bool control_only = true;
m_private_state_control_wait.SetValue (false, eBroadcastNever);
@@ -4484,7 +4633,11 @@ Process::RunPrivateStateThread ()
log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...",
__FUNCTION__, static_cast<void*>(this), GetID());
- m_public_run_lock.SetStopped();
+ // If we are a secondary thread, then the primary thread we are working for will have already
+ // acquired the public_run_lock, and isn't done with what it was doing yet, so don't
+ // try to change it on the way out.
+ if (!is_secondary_thread)
+ m_public_run_lock.SetStopped();
m_private_state_control_wait.SetValue (true, eBroadcastAlways);
m_private_state_thread.Reset();
return NULL;
@@ -4496,7 +4649,7 @@ Process::RunPrivateStateThread ()
Process::ProcessEventData::ProcessEventData () :
EventData (),
- m_process_sp (),
+ m_process_wp (),
m_state (eStateInvalid),
m_restarted (false),
m_update_state (0),
@@ -4506,12 +4659,14 @@ Process::ProcessEventData::ProcessEventData () :
Process::ProcessEventData::ProcessEventData (const ProcessSP &process_sp, StateType state) :
EventData (),
- m_process_sp (process_sp),
+ m_process_wp (),
m_state (state),
m_restarted (false),
m_update_state (0),
m_interrupted (false)
{
+ if (process_sp)
+ m_process_wp = process_sp;
}
Process::ProcessEventData::~ProcessEventData()
@@ -4534,6 +4689,11 @@ Process::ProcessEventData::GetFlavor () const
void
Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
{
+ ProcessSP process_sp(m_process_wp.lock());
+
+ if (!process_sp)
+ return;
+
// This function gets called twice for each event, once when the event gets pulled
// off of the private process event queue, and then any number of times, first when it gets pulled off of
// the public event queue, then other times when we're pretending that this is where we stopped at the
@@ -4543,7 +4703,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
if (m_update_state != 1)
return;
- m_process_sp->SetPublicState (m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
+ process_sp->SetPublicState (m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr));
// If this is a halt event, even if the halt stopped with some reason other than a plain interrupt (e.g. we had
// already stopped for a breakpoint when the halt request came through) don't do the StopInfo actions, as they may
@@ -4554,7 +4714,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
// If we're stopped and haven't restarted, then do the StopInfo actions here:
if (m_state == eStateStopped && ! m_restarted)
{
- ThreadList &curr_thread_list = m_process_sp->GetThreadList();
+ ThreadList &curr_thread_list = process_sp->GetThreadList();
uint32_t num_threads = curr_thread_list.GetSize();
uint32_t idx;
@@ -4584,7 +4744,7 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
for (idx = 0; idx < num_threads; ++idx)
{
- curr_thread_list = m_process_sp->GetThreadList();
+ curr_thread_list = process_sp->GetThreadList();
if (curr_thread_list.GetSize() != num_threads)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS));
@@ -4647,14 +4807,14 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
SetRestarted(true);
// Use the public resume method here, since this is just
// extending a public resume.
- m_process_sp->PrivateResume();
+ process_sp->PrivateResume();
}
else
{
// If we didn't restart, run the Stop Hooks here:
// They might also restart the target, so watch for that.
- m_process_sp->GetTarget().RunStopHooks();
- if (m_process_sp->GetPrivateState() == eStateRunning)
+ process_sp->GetTarget().RunStopHooks();
+ if (process_sp->GetPrivateState() == eStateRunning)
SetRestarted(true);
}
}
@@ -4664,9 +4824,13 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr)
void
Process::ProcessEventData::Dump (Stream *s) const
{
- if (m_process_sp)
+ ProcessSP process_sp(m_process_wp.lock());
+
+ if (process_sp)
s->Printf(" process = %p (pid = %" PRIu64 "), ",
- static_cast<void*>(m_process_sp.get()), m_process_sp->GetID());
+ static_cast<void*>(process_sp.get()), process_sp->GetID());
+ else
+ s->PutCString(" process = NULL, ");
s->Printf("state = %s", StateAsCString(GetState()));
}
@@ -4946,6 +5110,7 @@ public:
m_write_file (write_fd, false),
m_pipe ()
{
+ m_pipe.CreateNew(false);
m_read_file.SetDescriptor(GetInputFD(), false);
}
@@ -4955,130 +5120,93 @@ public:
}
- bool
- OpenPipes ()
- {
- if (m_pipe.CanRead() && m_pipe.CanWrite())
- return true;
- Error result = m_pipe.CreateNew(false);
- return result.Success();
- }
-
- void
- ClosePipes()
- {
- m_pipe.Close();
- }
-
// Each IOHandler gets to run until it is done. It should read data
// from the "in" and place output into "out" and "err and return
// when done.
- virtual void
- Run ()
+ void
+ Run () override
{
- if (m_read_file.IsValid() && m_write_file.IsValid())
+ if (!m_read_file.IsValid() || !m_write_file.IsValid() || !m_pipe.CanRead() || !m_pipe.CanWrite())
{
- SetIsDone(false);
- if (OpenPipes())
- {
- const int read_fd = m_read_file.GetDescriptor();
- const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
- TerminalState terminal_state;
- terminal_state.Save (read_fd, false);
- Terminal terminal(read_fd);
- terminal.SetCanonical(false);
- terminal.SetEcho(false);
+ SetIsDone(true);
+ return;
+ }
+
+ SetIsDone(false);
+ const int read_fd = m_read_file.GetDescriptor();
+ TerminalState terminal_state;
+ terminal_state.Save (read_fd, false);
+ Terminal terminal(read_fd);
+ terminal.SetCanonical(false);
+ terminal.SetEcho(false);
// FD_ZERO, FD_SET are not supported on windows
#ifndef _WIN32
- while (!GetIsDone())
+ const int pipe_read_fd = m_pipe.GetReadFileDescriptor();
+ while (!GetIsDone())
+ {
+ fd_set read_fdset;
+ FD_ZERO (&read_fdset);
+ FD_SET (read_fd, &read_fdset);
+ FD_SET (pipe_read_fd, &read_fdset);
+ const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1;
+ int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL);
+ if (num_set_fds < 0)
+ {
+ const int select_errno = errno;
+
+ if (select_errno != EINTR)
+ SetIsDone(true);
+ }
+ else if (num_set_fds > 0)
+ {
+ char ch = 0;
+ size_t n;
+ if (FD_ISSET (read_fd, &read_fdset))
{
- fd_set read_fdset;
- FD_ZERO (&read_fdset);
- FD_SET (read_fd, &read_fdset);
- FD_SET (pipe_read_fd, &read_fdset);
- const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1;
- int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL);
- if (num_set_fds < 0)
+ n = 1;
+ if (m_read_file.Read(&ch, n).Success() && n == 1)
{
- const int select_errno = errno;
-
- if (select_errno != EINTR)
+ if (m_write_file.Write(&ch, n).Fail() || n != 1)
SetIsDone(true);
}
- else if (num_set_fds > 0)
+ else
+ SetIsDone(true);
+ }
+ if (FD_ISSET (pipe_read_fd, &read_fdset))
+ {
+ size_t bytes_read;
+ // Consume the interrupt byte
+ Error error = m_pipe.Read(&ch, 1, bytes_read);
+ if (error.Success())
{
- char ch = 0;
- size_t n;
- if (FD_ISSET (read_fd, &read_fdset))
+ switch (ch)
{
- n = 1;
- if (m_read_file.Read(&ch, n).Success() && n == 1)
- {
- if (m_write_file.Write(&ch, n).Fail() || n != 1)
- SetIsDone(true);
- }
- else
+ case 'q':
SetIsDone(true);
- }
- if (FD_ISSET (pipe_read_fd, &read_fdset))
- {
- size_t bytes_read;
- // Consume the interrupt byte
- Error error = m_pipe.Read(&ch, 1, bytes_read);
- if (error.Success())
- {
- switch (ch)
- {
- case 'q':
- SetIsDone(true);
- break;
- case 'i':
- if (StateIsRunningState(m_process->GetState()))
- m_process->Halt();
- break;
- }
- }
+ break;
+ case 'i':
+ if (StateIsRunningState(m_process->GetState()))
+ m_process->Halt();
+ break;
}
}
}
-#endif
- terminal_state.Restore();
-
}
- else
- SetIsDone(true);
}
- else
- SetIsDone(true);
- }
-
- // Hide any characters that have been displayed so far so async
- // output can be displayed. Refresh() will be called after the
- // output has been displayed.
- virtual void
- Hide ()
- {
-
- }
- // Called when the async output has been received in order to update
- // the input reader (refresh the prompt and redisplay any current
- // line(s) that are being edited
- virtual void
- Refresh ()
- {
-
+#endif
+ terminal_state.Restore();
}
- virtual void
- Cancel ()
+ void
+ Cancel () override
{
char ch = 'q'; // Send 'q' for quit
size_t bytes_written = 0;
m_pipe.Write(&ch, 1, bytes_written);
}
- virtual bool
- Interrupt ()
+ bool
+ Interrupt () override
{
// Do only things that are safe to do in an interrupt context (like in
// a SIGINT handler), like write 1 byte to a file descriptor. This will
@@ -5111,8 +5239,8 @@ public:
return false;
}
- virtual void
- GotEOF()
+ void
+ GotEOF() override
{
}
@@ -5161,6 +5289,10 @@ Process::PushProcessIOHandler ()
IOHandlerSP io_handler_sp (m_process_input_reader);
if (io_handler_sp)
{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("Process::%s pushing IO handler", __FUNCTION__);
+
io_handler_sp->SetIsDone(false);
m_target.GetDebugger().PushIOHandler (io_handler_sp);
return true;
@@ -6252,6 +6384,15 @@ Process::ClearPreResumeActions ()
m_pre_resume_actions.clear();
}
+ProcessRunLock &
+Process::GetRunLock()
+{
+ if (m_private_state_thread.EqualsThread(Host::GetCurrentThread()))
+ return m_private_run_lock;
+ else
+ return m_public_run_lock;
+}
+
void
Process::Flush ()
{
@@ -6351,13 +6492,29 @@ Process::ModulesDidLoad (ModuleList &module_list)
runtime->ModulesDidLoad(module_list);
}
+ // Let any language runtimes we have already created know
+ // about the modules that loaded.
+
+ // Iterate over a copy of this language runtime list in case
+ // the language runtime ModulesDidLoad somehow causes the language
+ // riuntime to be unloaded.
+ LanguageRuntimeCollection language_runtimes(m_language_runtimes);
+ for (const auto &pair: language_runtimes)
+ {
+ // We must check language_runtime_sp to make sure it is not
+ // NULL as we might cache the fact that we didn't have a
+ // language runtime for a language.
+ LanguageRuntimeSP language_runtime_sp = pair.second;
+ if (language_runtime_sp)
+ language_runtime_sp->ModulesDidLoad(module_list);
+ }
}
ThreadCollectionSP
Process::GetHistoryThreads(lldb::addr_t addr)
{
ThreadCollectionSP threads;
-
+
const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(shared_from_this());
if (! memory_history.get()) {
@@ -6381,3 +6538,12 @@ Process::GetInstrumentationRuntime(lldb::InstrumentationRuntimeType type)
else
return (*pos).second;
}
+
+bool
+Process::GetModuleSpec(const FileSpec& module_file_spec,
+ const ArchSpec& arch,
+ ModuleSpec& module_spec)
+{
+ module_spec.Clear();
+ return false;
+}
diff --git a/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp
index b841b2c066a3..30c5aee63cad 100644
--- a/source/Target/ProcessLaunchInfo.cpp
+++ b/source/Target/ProcessLaunchInfo.cpp
@@ -15,6 +15,10 @@
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Target.h"
+#if !defined(_WIN32)
+#include <limits.h>
+#endif
+
using namespace lldb;
using namespace lldb_private;
@@ -38,8 +42,11 @@ ProcessLaunchInfo::ProcessLaunchInfo () :
{
}
-ProcessLaunchInfo::ProcessLaunchInfo(const char *stdin_path, const char *stdout_path, const char *stderr_path,
- const char *working_directory, uint32_t launch_flags) :
+ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
+ const FileSpec &stdout_file_spec,
+ const FileSpec &stderr_file_spec,
+ const FileSpec &working_directory,
+ uint32_t launch_flags) :
ProcessInfo(),
m_working_dir(),
m_plugin_name(),
@@ -53,28 +60,28 @@ ProcessLaunchInfo::ProcessLaunchInfo(const char *stdin_path, const char *stdout_
m_listener_sp (),
m_hijack_listener_sp()
{
- if (stdin_path)
+ if (stdin_file_spec)
{
FileAction file_action;
const bool read = true;
const bool write = false;
- if (file_action.Open(STDIN_FILENO, stdin_path, read, write))
+ if (file_action.Open(STDIN_FILENO, stdin_file_spec, read, write))
AppendFileAction (file_action);
}
- if (stdout_path)
+ if (stdout_file_spec)
{
FileAction file_action;
const bool read = false;
const bool write = true;
- if (file_action.Open(STDOUT_FILENO, stdout_path, read, write))
+ if (file_action.Open(STDOUT_FILENO, stdout_file_spec, read, write))
AppendFileAction (file_action);
}
- if (stderr_path)
+ if (stderr_file_spec)
{
FileAction file_action;
const bool read = false;
const bool write = true;
- if (file_action.Open(STDERR_FILENO, stderr_path, read, write))
+ if (file_action.Open(STDERR_FILENO, stderr_file_spec, read, write))
AppendFileAction (file_action);
}
if (working_directory)
@@ -106,10 +113,11 @@ ProcessLaunchInfo::AppendDuplicateFileAction (int fd, int dup_fd)
}
bool
-ProcessLaunchInfo::AppendOpenFileAction (int fd, const char *path, bool read, bool write)
+ProcessLaunchInfo::AppendOpenFileAction(int fd, const FileSpec &file_spec,
+ bool read, bool write)
{
FileAction file_action;
- if (file_action.Open (fd, path, read, write))
+ if (file_action.Open(fd, file_spec, read, write))
{
AppendFileAction (file_action);
return true;
@@ -121,7 +129,7 @@ bool
ProcessLaunchInfo::AppendSuppressFileAction (int fd, bool read, bool write)
{
FileAction file_action;
- if (file_action.Open (fd, "/dev/null", read, write))
+ if (file_action.Open(fd, FileSpec{"/dev/null", false}, read, write))
{
AppendFileAction (file_action);
return true;
@@ -148,21 +156,16 @@ ProcessLaunchInfo::GetFileActionForFD(int fd) const
return NULL;
}
-const char *
-ProcessLaunchInfo::GetWorkingDirectory () const
+const FileSpec &
+ProcessLaunchInfo::GetWorkingDirectory() const
{
- if (m_working_dir.empty())
- return NULL;
- return m_working_dir.c_str();
+ return m_working_dir;
}
void
-ProcessLaunchInfo::SetWorkingDirectory (const char *working_dir)
+ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir)
{
- if (working_dir && working_dir[0])
- m_working_dir.assign (working_dir);
- else
- m_working_dir.clear();
+ m_working_dir = working_dir;
}
const char *
@@ -208,14 +211,22 @@ ProcessLaunchInfo::SetLaunchInSeparateProcessGroup (bool separate)
m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup);
else
m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup);
+}
+void
+ProcessLaunchInfo::SetShellExpandArguments (bool expand)
+{
+ if (expand)
+ m_flags.Set(lldb::eLaunchFlagShellExpandArguments);
+ else
+ m_flags.Clear(lldb::eLaunchFlagShellExpandArguments);
}
void
ProcessLaunchInfo::Clear ()
{
ProcessInfo::Clear();
- m_working_dir.clear();
+ m_working_dir.Clear();
m_plugin_name.clear();
m_shell.Clear();
m_flags.Clear();
@@ -288,57 +299,53 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
// (lldb) settings set target.input-path
// (lldb) settings set target.output-path
// (lldb) settings set target.error-path
- FileSpec in_path;
- FileSpec out_path;
- FileSpec err_path;
+ FileSpec in_file_spec;
+ FileSpec out_file_spec;
+ FileSpec err_file_spec;
if (target)
{
// Only override with the target settings if we don't already have
// an action for in, out or error
if (GetFileActionForFD(STDIN_FILENO) == NULL)
- in_path = target->GetStandardInputPath();
+ in_file_spec = target->GetStandardInputPath();
if (GetFileActionForFD(STDOUT_FILENO) == NULL)
- out_path = target->GetStandardOutputPath();
+ out_file_spec = target->GetStandardOutputPath();
if (GetFileActionForFD(STDERR_FILENO) == NULL)
- err_path = target->GetStandardErrorPath();
+ err_file_spec = target->GetStandardErrorPath();
}
if (log)
log->Printf ("ProcessLaunchInfo::%s target stdin='%s', target stdout='%s', stderr='%s'",
__FUNCTION__,
- in_path ? in_path.GetPath().c_str () : "<null>",
- out_path ? out_path.GetPath().c_str () : "<null>",
- err_path ? err_path.GetPath().c_str () : "<null>");
+ in_file_spec ? in_file_spec.GetCString() : "<null>",
+ out_file_spec ? out_file_spec.GetCString() : "<null>",
+ err_file_spec ? err_file_spec.GetCString() : "<null>");
- char path[PATH_MAX];
- if (in_path && in_path.GetPath(path, sizeof(path)))
+ if (in_file_spec)
{
- AppendOpenFileAction(STDIN_FILENO, path, true, false);
+ AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stdin open file action for %s",
- __FUNCTION__,
- in_path.GetPath().c_str ());
+ __FUNCTION__, in_file_spec.GetCString());
}
- if (out_path && out_path.GetPath(path, sizeof(path)))
+ if (out_file_spec)
{
- AppendOpenFileAction(STDOUT_FILENO, path, false, true);
+ AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stdout open file action for %s",
- __FUNCTION__,
- out_path.GetPath().c_str ());
+ __FUNCTION__, out_file_spec.GetCString());
}
- if (err_path && err_path.GetPath(path, sizeof(path)))
+ if (err_file_spec)
{
+ AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);
if (log)
log->Printf ("ProcessLaunchInfo::%s appended stderr open file action for %s",
- __FUNCTION__,
- err_path.GetPath().c_str ());
- AppendOpenFileAction(STDERR_FILENO, path, false, true);
+ __FUNCTION__, err_file_spec.GetCString());
}
- if (default_to_use_pty && (!in_path || !out_path || !err_path))
+ if (default_to_use_pty && (!in_file_spec || !out_file_spec || !err_file_spec))
{
if (log)
log->Printf ("ProcessLaunchInfo::%s default_to_use_pty is set, and at least one stdin/stderr/stdout is unset, so generating a pty to use for it",
@@ -353,27 +360,27 @@ ProcessLaunchInfo::FinalizeFileActions (Target *target, bool default_to_use_pty)
#endif
if (m_pty->OpenFirstAvailableMaster(open_flags, NULL, 0))
{
- const char *slave_path = m_pty->GetSlaveName(NULL, 0);
+ const FileSpec slave_file_spec{m_pty->GetSlaveName(NULL, 0), false};
// Only use the slave tty if we don't have anything specified for
// input and don't have an action for stdin
- if (!in_path && GetFileActionForFD(STDIN_FILENO) == NULL)
+ if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == NULL)
{
- AppendOpenFileAction(STDIN_FILENO, slave_path, true, false);
+ AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false);
}
// Only use the slave tty if we don't have anything specified for
// output and don't have an action for stdout
- if (!out_path && GetFileActionForFD(STDOUT_FILENO) == NULL)
+ if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == NULL)
{
- AppendOpenFileAction(STDOUT_FILENO, slave_path, false, true);
+ AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true);
}
// Only use the slave tty if we don't have anything specified for
// error and don't have an action for stderr
- if (!err_path && GetFileActionForFD(STDERR_FILENO) == NULL)
+ if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == NULL)
{
- AppendOpenFileAction(STDERR_FILENO, slave_path, false, true);
+ AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true);
}
}
}
@@ -416,18 +423,18 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
// is a relative path.
const char *argv0 = argv[0];
FileSpec arg_spec(argv0, false);
- if (arg_spec.IsRelativeToCurrentWorkingDirectory())
+ if (arg_spec.IsRelative())
{
// We have a relative path to our executable which may not work if
// we just try to run "a.out" (without it being converted to "./a.out")
- const char *working_dir = GetWorkingDirectory();
+ FileSpec working_dir = GetWorkingDirectory();
// Be sure to put quotes around PATH's value in case any paths have spaces...
std::string new_path("PATH=\"");
const size_t empty_path_len = new_path.size();
- if (working_dir && working_dir[0])
+ if (working_dir)
{
- new_path += working_dir;
+ new_path += working_dir.GetPath();
}
else
{
diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index 01a8c9ab88f2..7c5b022dac7c 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/StackFrame.h"
// C Includes
@@ -920,7 +918,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
}
else
{
- child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
+ child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
if (!child_valobj_sp)
{
valobj_sp->GetExpressionPath (var_expr_path_strm, false);
@@ -1406,13 +1404,15 @@ StackFrame::Dump (Stream *strm, bool show_frame_index, bool show_fullpaths)
const bool show_module = true;
const bool show_inline = true;
const bool show_function_arguments = true;
+ const bool show_function_name = true;
m_sc.DumpStopContext (strm,
exe_ctx.GetBestExecutionContextScope(),
GetFrameCodeAddress(),
show_fullpaths,
show_module,
show_inline,
- show_function_arguments);
+ show_function_arguments,
+ show_function_name);
}
void
diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp
index 9a132618288d..05923d70ce42 100644
--- a/source/Target/StackFrameList.cpp
+++ b/source/Target/StackFrameList.cpp
@@ -343,6 +343,7 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
m_frames.push_back (unwind_frame_sp);
}
+ assert(unwind_frame_sp);
SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock | eSymbolContextFunction);
Block *unwind_block = unwind_sc.block;
if (unwind_block)
@@ -354,7 +355,21 @@ StackFrameList::GetFramesUpTo(uint32_t end_idx)
// address, else we decrement the address by one to get the correct
// location.
if (idx > 0)
- curr_frame_address.Slide(-1);
+ {
+ if (curr_frame_address.GetOffset() == 0)
+ {
+ // If curr_frame_address points to the first address in a section then after
+ // adjustment it will point to an other section. In that case resolve the
+ // address again to the correct section plus offset form.
+ TargetSP target = m_thread.CalculateTarget();
+ addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress(target.get());
+ curr_frame_address.SetOpcodeLoadAddress(load_addr - 1, target.get());
+ }
+ else
+ {
+ curr_frame_address.Slide(-1);
+ }
+ }
SymbolContext next_frame_sc;
Address next_frame_address;
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 457b94c1dc20..76e5f374f952 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/StopInfo.h"
// C Includes
@@ -24,6 +22,7 @@
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
@@ -39,6 +38,7 @@ StopInfo::StopInfo (Thread &thread, uint64_t value) :
m_stop_id (thread.GetProcess()->GetStopID()),
m_resume_id (thread.GetProcess()->GetResumeID()),
m_value (value),
+ m_description (),
m_override_should_notify (eLazyBoolCalculate),
m_override_should_stop (eLazyBoolCalculate),
m_extended_info()
@@ -111,7 +111,6 @@ class StopInfoBreakpoint : public StopInfo
public:
StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
StopInfo (thread, break_id),
- m_description(),
m_should_stop (false),
m_should_stop_is_valid (false),
m_should_perform_action (true),
@@ -124,7 +123,6 @@ public:
StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
StopInfo (thread, break_id),
- m_description(),
m_should_stop (should_stop),
m_should_stop_is_valid (true),
m_should_perform_action (true),
@@ -162,6 +160,19 @@ public:
{
}
+ virtual bool
+ IsValidForOperatingSystemThread (Thread &thread)
+ {
+ ProcessSP process_sp (thread.GetProcess());
+ if (process_sp)
+ {
+ BreakpointSiteSP bp_site_sp (process_sp->GetBreakpointSiteList().FindByID (m_value));
+ if (bp_site_sp)
+ return bp_site_sp->ValidForThisThread (&thread);
+ }
+ return false;
+ }
+
virtual StopReason
GetStopReason () const
{
@@ -335,6 +346,7 @@ protected:
}
BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
+ std::unordered_set<break_id_t> precondition_breakpoints;
if (bp_site_sp)
{
@@ -346,7 +358,9 @@ protected:
}
else
{
- // We go through each location, and test first its condition. If the condition says to stop,
+ // We go through each location, and test first its precondition - this overrides everything. Note,
+ // we only do this once per breakpoint - not once per location...
+ // Then check the condition. If the condition says to stop,
// then we run the callback for that location. If that callback says to stop as well, then
// we set m_should_stop to true; we are going to stop.
// But we still want to give all the breakpoints whose conditions say we are going to stop a
@@ -442,7 +456,19 @@ protected:
}
continue;
}
- // First run the condition for the breakpoint. If that says we should stop, then we'll run
+
+ // First run the precondition, but since the precondition is per breakpoint, only run it once
+ // per breakpoint.
+ std::pair<std::unordered_set<break_id_t>::iterator, bool> result
+ = precondition_breakpoints.insert(bp_loc_sp->GetBreakpoint().GetID());
+ if (!result.second)
+ continue;
+
+ bool precondition_result = bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context);
+ if (!precondition_result)
+ continue;
+
+ // Next run the condition for the breakpoint. If that says we should stop, then we'll run
// the callback for the breakpoint. If the callback says we shouldn't stop that will win.
if (bp_loc_sp->GetConditionText() != NULL)
@@ -539,7 +565,6 @@ protected:
}
private:
- std::string m_description;
bool m_should_stop;
bool m_should_stop_is_valid;
bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
@@ -592,7 +617,6 @@ public:
StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
StopInfo(thread, watch_id),
- m_description(),
m_should_stop(false),
m_should_stop_is_valid(false)
{
@@ -831,7 +855,6 @@ protected:
}
private:
- std::string m_description;
bool m_should_stop;
bool m_should_stop_is_valid;
};
@@ -846,9 +869,10 @@ class StopInfoUnixSignal : public StopInfo
{
public:
- StopInfoUnixSignal (Thread &thread, int signo) :
+ StopInfoUnixSignal (Thread &thread, int signo, const char *description) :
StopInfo (thread, signo)
{
+ SetDescription (description);
}
virtual ~StopInfoUnixSignal ()
@@ -1136,9 +1160,9 @@ StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
}
StopInfoSP
-StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
+StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo, const char *description)
{
- return StopInfoSP (new StopInfoUnixSignal (thread, signo));
+ return StopInfoSP (new StopInfoUnixSignal (thread, signo, description));
}
StopInfoSP
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index e9393d1be0b4..6ba09f4ee948 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/Target.h"
// C Includes
@@ -34,7 +32,9 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/ClangASTSource.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -42,8 +42,10 @@
#include "lldb/Interpreter/OptionGroupWatchpoint.h"
#include "lldb/Interpreter/OptionValues.h"
#include "lldb/Interpreter/Property.h"
-#include "lldb/lldb-private-log.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
@@ -83,7 +85,7 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
m_scratch_ast_context_ap (),
m_scratch_ast_source_ap (),
m_ast_importer_ap (),
- m_persistent_variables (),
+ m_persistent_variables (new ClangPersistentVariables),
m_source_manager_ap(),
m_stop_hooks (),
m_stop_hook_next_id (0),
@@ -175,6 +177,7 @@ Target::CleanupProcess ()
this->GetWatchpointList().GetListMutex(locker);
DisableAllWatchpoints(false);
ClearAllWatchpointHitCounts();
+ ClearAllWatchpointHistoricValues();
}
void
@@ -184,7 +187,7 @@ Target::DeleteCurrentProcess ()
{
m_section_load_history.Clear();
if (m_process_sp->IsAlive())
- m_process_sp->Destroy();
+ m_process_sp->Destroy(false);
m_process_sp->Finalize();
@@ -225,7 +228,7 @@ Target::Destroy()
m_last_created_watchpoint.reset();
m_search_filter_sp.reset();
m_image_search_paths.Clear(notify);
- m_persistent_variables.Clear();
+ m_persistent_variables->Clear();
m_stop_hooks.clear();
m_stop_hook_next_id = 0;
m_suppress_stop_hooks = false;
@@ -268,10 +271,13 @@ Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
const FileSpecList *source_file_spec_list,
RegularExpression &source_regex,
bool internal,
- bool hardware)
+ bool hardware,
+ LazyBool move_to_nearest_code)
{
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
- BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex));
+ if (move_to_nearest_code == eLazyBoolCalculate)
+ move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
+ BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex, !static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -283,7 +289,8 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
LazyBool check_inlines,
LazyBool skip_prologue,
bool internal,
- bool hardware)
+ bool hardware,
+ LazyBool move_to_nearest_code)
{
if (check_inlines == eLazyBoolCalculate)
{
@@ -320,12 +327,15 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
}
if (skip_prologue == eLazyBoolCalculate)
skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+ if (move_to_nearest_code == eLazyBoolCalculate)
+ move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL,
file,
line_no,
check_inlines,
- skip_prologue));
+ skip_prologue,
+ !static_cast<bool>(move_to_nearest_code)));
return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
}
@@ -518,11 +528,23 @@ Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
}
lldb::BreakpointSP
-Target::CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal)
+Target::CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal, Args *additional_args, Error *error)
{
- return LanguageRuntime::CreateExceptionBreakpoint (*this, language, catch_bp, throw_bp, internal);
+ BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint (*this, language, catch_bp, throw_bp, internal);
+ if (exc_bkpt_sp && additional_args)
+ {
+ Breakpoint::BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();
+ if (precondition_sp && additional_args)
+ {
+ if (error)
+ *error = precondition_sp->ConfigurePrecondition(*additional_args);
+ else
+ precondition_sp->ConfigurePrecondition(*additional_args);
+ }
+ }
+ return exc_bkpt_sp;
}
-
+
BreakpointSP
Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols)
{
@@ -907,6 +929,26 @@ Target::ClearAllWatchpointHitCounts ()
return true; // Success!
}
+// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
+bool
+Target::ClearAllWatchpointHistoricValues ()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
+ if (log)
+ log->Printf ("Target::%s\n", __FUNCTION__);
+
+ size_t num_watchpoints = m_watchpoint_list.GetSize();
+ for (size_t i = 0; i < num_watchpoints; ++i)
+ {
+ WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
+ if (!wp_sp)
+ return false;
+
+ wp_sp->ResetHistoricValues();
+ }
+ return true; // Success!
+}
+
// Assumption: Caller holds the list mutex lock for m_watchpoint_list
// during these operations.
bool
@@ -1020,13 +1062,24 @@ Target::IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count)
ModuleSP
Target::GetExecutableModule ()
{
- return m_images.GetModuleAtIndex(0);
+ // search for the first executable in the module list
+ for (size_t i = 0; i < m_images.GetSize(); ++i)
+ {
+ ModuleSP module_sp = m_images.GetModuleAtIndex (i);
+ lldb_private::ObjectFile * obj = module_sp->GetObjectFile();
+ if (obj == nullptr)
+ continue;
+ if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
+ return module_sp;
+ }
+ // as fall back return the first module loaded
+ return m_images.GetModuleAtIndex (0);
}
Module*
Target::GetExecutableModulePointer ()
{
- return m_images.GetModulePointerAtIndex(0);
+ return GetExecutableModule().get();
}
static void
@@ -1163,6 +1216,30 @@ Target::SetArchitecture (const ArchSpec &arch_spec)
return false;
}
+bool
+Target::MergeArchitecture (const ArchSpec &arch_spec)
+{
+ if (arch_spec.IsValid())
+ {
+ if (m_arch.IsCompatibleMatch(arch_spec))
+ {
+ // The current target arch is compatible with "arch_spec", see if we
+ // can improve our current architecture using bits from "arch_spec"
+
+ // Merge bits from arch_spec into "merged_arch" and set our architecture
+ ArchSpec merged_arch (m_arch);
+ merged_arch.MergeFrom (arch_spec);
+ return SetArchitecture(merged_arch);
+ }
+ else
+ {
+ // The new architecture is different, we just need to replace it
+ return SetArchitecture(arch_spec);
+ }
+ }
+ return false;
+}
+
void
Target::WillClearList (const ModuleList& module_list)
{
@@ -1211,8 +1288,7 @@ Target::ModulesDidLoad (ModuleList &module_list)
{
m_process_sp->ModulesDidLoad (module_list);
}
- // TODO: make event data that packages up the module_list
- BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
+ BroadcastEvent (eBroadcastBitModulesLoaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
@@ -1232,7 +1308,7 @@ Target::SymbolsDidLoad (ModuleList &module_list)
}
m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
- BroadcastEvent(eBroadcastBitSymbolsLoaded, NULL);
+ BroadcastEvent (eBroadcastBitSymbolsLoaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
@@ -1243,8 +1319,7 @@ Target::ModulesDidUnload (ModuleList &module_list, bool delete_locations)
{
UnloadModuleSections (module_list);
m_breakpoint_list.UpdateBreakpoints (module_list, false, delete_locations);
- // TODO: make event data that packages up the module_list
- BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
+ BroadcastEvent (eBroadcastBitModulesUnloaded, new TargetEventData (this->shared_from_this(), module_list));
}
}
@@ -1662,9 +1737,9 @@ Target::GetSharedModule (const ModuleSpec &module_spec, Error *error_ptr)
// module in the shared module cache.
if (m_platform_sp)
{
- FileSpec platform_file_spec;
- error = m_platform_sp->GetSharedModule (module_spec,
- module_sp,
+ error = m_platform_sp->GetSharedModule (module_spec,
+ m_process_sp.get(),
+ module_sp,
&GetExecutableSearchPaths(),
&old_module_sp,
&did_create_module);
@@ -1856,6 +1931,15 @@ Target::GetDefaultDebugFileSearchPaths ()
return FileSpecList();
}
+FileSpecList
+Target::GetDefaultClangModuleSearchPaths ()
+{
+ TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
+ if (properties_sp)
+ return properties_sp->GetClangModuleSearchPaths();
+ return FileSpecList();
+}
+
ArchSpec
Target::GetDefaultArchitecture ()
{
@@ -1932,7 +2016,7 @@ Target::EvaluateExpression
lldb::ClangExpressionVariableSP persistent_var_sp;
// Only check for persistent variables the expression starts with a '$'
if (expr_cstr[0] == '$')
- persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
+ persistent_var_sp = m_persistent_variables->GetVariable (expr_cstr);
if (persistent_var_sp)
{
@@ -1956,6 +2040,12 @@ Target::EvaluateExpression
return execution_results;
}
+ClangPersistentVariables &
+Target::GetPersistentVariables()
+{
+ return *m_persistent_variables;
+}
+
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const
{
@@ -2292,8 +2382,8 @@ Target::Install (ProcessLaunchInfo *launch_info)
if (is_main_executable) // TODO: add setting for always installing main executable???
{
// Always install the main executable
- remote_file.GetDirectory() = platform_sp->GetWorkingDirectory();
- remote_file.GetFilename() = module_sp->GetFileSpec().GetFilename();
+ remote_file = platform_sp->GetRemoteWorkingDirectory();
+ remote_file.AppendPathComponent(module_sp->GetFileSpec().GetFilename().GetCString());
}
}
if (remote_file)
@@ -2304,6 +2394,7 @@ Target::Install (ProcessLaunchInfo *launch_info)
module_sp->SetPlatformFileSpec(remote_file);
if (is_main_executable)
{
+ platform_sp->SetFilePermissions(remote_file, 0700);
if (launch_info)
launch_info->SetExecutableFile(remote_file, false);
}
@@ -2486,10 +2577,24 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
if (log)
log->Printf ("Target::%s asking the platform to debug the process", __FUNCTION__);
+ // Get a weak pointer to the previous process if we have one
+ ProcessWP process_wp;
+ if (m_process_sp)
+ process_wp = m_process_sp;
m_process_sp = GetPlatform()->DebugProcess (launch_info,
debugger,
this,
error);
+
+ // Cleanup the old process since someone might still have a strong
+ // reference to this process and we would like to allow it to cleanup
+ // as much as it can without the object being destroyed. We try to
+ // lock the shared pointer and if that works, then someone else still
+ // has a strong reference to the process.
+
+ ProcessSP old_process_sp(process_wp.lock());
+ if (old_process_sp)
+ old_process_sp->Finalize();
}
else
{
@@ -2521,41 +2626,46 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
if (error.Success())
{
- if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
+ if (synchronous_execution || launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
{
ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
+ if (!hijack_listener_sp)
+ {
+ hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack"));
+ launch_info.SetHijackListener(hijack_listener_sp);
+ m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
+ }
StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false, hijack_listener_sp.get(), NULL);
if (state == eStateStopped)
{
- if (!synchronous_execution)
- m_process_sp->RestoreProcessEvents ();
-
- error = m_process_sp->PrivateResume();
-
- if (error.Success())
+ if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
{
- // there is a race condition where this thread will return up the call stack to the main command
- // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
- // a chance to call PushProcessIOHandler()
- m_process_sp->SyncIOHandler(2000);
-
if (synchronous_execution)
{
- state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get(), stream);
- const bool must_be_alive = false; // eStateExited is ok, so this must be false
- if (!StateIsStoppedState(state, must_be_alive))
+ error = m_process_sp->PrivateResume();
+ if (error.Success())
{
- error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
+ state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get(), stream);
+ const bool must_be_alive = false; // eStateExited is ok, so this must be false
+ if (!StateIsStoppedState(state, must_be_alive))
+ {
+ error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
+ }
}
}
- }
- else
- {
- Error error2;
- error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
- error = error2;
+ else
+ {
+ m_process_sp->RestoreProcessEvents();
+ error = m_process_sp->PrivateResume();
+ }
+ if (!error.Success())
+ {
+ Error error2;
+ error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
+ error = error2;
+ }
}
}
else if (state == eStateExited)
@@ -2594,6 +2704,83 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
}
return error;
}
+
+Error
+Target::Attach (ProcessAttachInfo &attach_info, Stream *stream)
+{
+ auto state = eStateInvalid;
+ auto process_sp = GetProcessSP ();
+ if (process_sp)
+ {
+ state = process_sp->GetState ();
+ if (process_sp->IsAlive () && state != eStateConnected)
+ {
+ if (state == eStateAttaching)
+ return Error ("process attach is in progress");
+ return Error ("a process is already being debugged");
+ }
+ }
+
+ ListenerSP hijack_listener_sp (new Listener ("lldb.Target.Attach.attach.hijack"));
+ attach_info.SetHijackListener (hijack_listener_sp);
+
+ const ModuleSP old_exec_module_sp = GetExecutableModule ();
+
+ // If no process info was specified, then use the target executable
+ // name as the process to attach to by default
+ if (!attach_info.ProcessInfoSpecified ())
+ {
+ if (old_exec_module_sp)
+ attach_info.GetExecutableFile ().GetFilename () = old_exec_module_sp->GetPlatformFileSpec ().GetFilename ();
+
+ if (!attach_info.ProcessInfoSpecified ())
+ {
+ return Error ("no process specified, create a target with a file, or specify the --pid or --name");
+ }
+ }
+
+ const auto platform_sp = GetDebugger ().GetPlatformList ().GetSelectedPlatform ();
+
+ Error error;
+ if (state != eStateConnected && platform_sp != nullptr && platform_sp->CanDebugProcess ())
+ {
+ SetPlatform (platform_sp);
+ process_sp = platform_sp->Attach (attach_info, GetDebugger (), this, error);
+ }
+ else
+ {
+ if (state != eStateConnected)
+ {
+ const char *plugin_name = attach_info.GetProcessPluginName ();
+ process_sp = CreateProcess (attach_info.GetListenerForProcess (GetDebugger ()), plugin_name, nullptr);
+ if (process_sp == nullptr)
+ {
+ error.SetErrorStringWithFormat ("failed to create process using plugin %s", (plugin_name) ? plugin_name : "null");
+ return error;
+ }
+ }
+ process_sp->HijackProcessEvents (hijack_listener_sp.get ());
+ error = process_sp->Attach (attach_info);
+ }
+
+ if (error.Success () && process_sp)
+ {
+ state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener ().get (), stream);
+ process_sp->RestoreProcessEvents ();
+
+ if (state != eStateStopped)
+ {
+ const char *exit_desc = process_sp->GetExitDescription ();
+ if (exit_desc)
+ error.SetErrorStringWithFormat ("attach failed: %s", exit_desc);
+ else
+ error.SetErrorString ("attach failed: process did not stop (no such process or permission problem?)");
+ process_sp->Destroy (false);
+ }
+ }
+ return error;
+}
+
//--------------------------------------------------------------
// Target::StopHook
//--------------------------------------------------------------
@@ -2625,6 +2812,12 @@ Target::StopHook::~StopHook ()
}
void
+Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier)
+{
+ m_specifier_sp.reset(specifier);
+}
+
+void
Target::StopHook::SetThreadSpecifier (ThreadSpec *specifier)
{
m_thread_spec_ap.reset (specifier);
@@ -2744,6 +2937,7 @@ static PropertyDefinition
g_properties[] =
{
{ "default-arch" , OptionValue::eTypeArch , true , 0 , NULL, NULL, "Default architecture to choose, when there's a choice." },
+ { "move-to-nearest-code" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "Move breakpoints to nearest code." },
{ "expr-prefix" , OptionValue::eTypeFileSpec , false, 0 , NULL, NULL, "Path to a file containing expressions to be prepended to all expressions." },
{ "prefer-dynamic-value" , OptionValue::eTypeEnum , false, eDynamicDontRunTarget , NULL, g_dynamic_value_types, "Should printed values be shown as their dynamic value." },
{ "enable-synthetic-value" , OptionValue::eTypeBoolean , false, true , NULL, NULL, "Should synthetic values be used by default whenever available." },
@@ -2755,6 +2949,8 @@ g_properties[] =
"Each element of the array is checked in order and the first one that results in a match wins." },
{ "exec-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , NULL, NULL, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
{ "debug-file-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , NULL, NULL, "List of directories to be searched when locating debug symbol files." },
+ { "clang-module-search-paths" , OptionValue::eTypeFileSpecList, false, 0 , NULL, NULL, "List of directories to be searched when locating modules for Clang." },
+ { "auto-import-clang-modules" , OptionValue::eTypeBoolean , false, false , NULL, NULL, "Automatically load Clang modules referred to by the program." },
{ "max-children-count" , OptionValue::eTypeSInt64 , false, 256 , NULL, NULL, "Maximum number of children to expand in any level of depth." },
{ "max-string-summary-length" , OptionValue::eTypeSInt64 , false, 1024 , NULL, NULL, "Maximum number of characters to show when using %s in summary strings." },
{ "max-memory-read-size" , OptionValue::eTypeSInt64 , false, 1024 , NULL, NULL, "Maximum number of bytes that 'memory read' will fetch before --force must be specified." },
@@ -2771,7 +2967,7 @@ g_properties[] =
{ "disable-stdio" , OptionValue::eTypeBoolean , false, false , NULL, NULL, "Disable stdin/stdout for process (e.g. for a GUI application)" },
{ "inline-breakpoint-strategy" , OptionValue::eTypeEnum , false, eInlineBreakpointsAlways , NULL, g_inline_breakpoint_enums, "The strategy to use when settings breakpoints by file and line. "
"Breakpoint locations can end up being inlined by the compiler, so that a compile unit 'a.c' might contain an inlined function from another source file. "
- "Usually this is limitted to breakpoint locations from inlined functions from header or other include files, or more accurately non-implementation source files. "
+ "Usually this is limited to breakpoint locations from inlined functions from header or other include files, or more accurately non-implementation source files. "
"Sometimes code might #include implementation files and cause inlined breakpoint locations in inlined implementation files. "
"Always checking for inlined breakpoint locations can be expensive (memory and time), so if you have a project with many headers "
"and find that setting breakpoints is slow, then you can change this setting to headers. "
@@ -2791,11 +2987,15 @@ g_properties[] =
"'minimal' is the fastest setting and will load section data with no symbols, but should rarely be used as stack frames in these memory regions will be inaccurate and not provide any context (fastest). " },
{ "display-expression-in-crashlogs" , OptionValue::eTypeBoolean , false, false, NULL, NULL, "Expressions that crash will show up in crash logs if the host system supports executable specific crash log strings and this setting is set to true." },
{ "trap-handler-names" , OptionValue::eTypeArray , true, OptionValue::eTypeString, NULL, NULL, "A list of trap handler function names, e.g. a common Unix user process one is _sigtramp." },
+ { "display-runtime-support-values" , OptionValue::eTypeBoolean , false, false, NULL, NULL, "If true, LLDB will show variables that are meant to support the operation of a language's runtime support." },
+ { "non-stop-mode" , OptionValue::eTypeBoolean , false, 0, NULL, NULL, "Disable lock-step debugging, instead control threads independently." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
+
enum
{
ePropertyDefaultArch,
+ ePropertyMoveToNearestCode,
ePropertyExprPrefix,
ePropertyPreferDynamic,
ePropertyEnableSynthetic,
@@ -2803,6 +3003,8 @@ enum
ePropertySourceMap,
ePropertyExecutableSearchPaths,
ePropertyDebugFileSearchPaths,
+ ePropertyClangModuleSearchPaths,
+ ePropertyAutoImportClangModules,
ePropertyMaxChildrenCount,
ePropertyMaxSummaryLength,
ePropertyMaxMemReadSize,
@@ -2825,7 +3027,9 @@ enum
ePropertyLoadScriptFromSymbolFile,
ePropertyMemoryModuleLoadLevel,
ePropertyDisplayExpressionsInCrashlogs,
- ePropertyTrapHandlerNames
+ ePropertyTrapHandlerNames,
+ ePropertyDisplayRuntimeSupportValues,
+ ePropertyNonStopModeEnabled
};
@@ -2939,11 +3143,34 @@ protected:
// TargetProperties
//----------------------------------------------------------------------
TargetProperties::TargetProperties (Target *target) :
- Properties ()
+ Properties (),
+ m_launch_info ()
{
if (target)
{
m_collection_sp.reset (new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
+
+ // Set callbacks to update launch_info whenever "settins set" updated any of these properties
+ m_collection_sp->SetValueChangedCallback(ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyRunArgs, TargetProperties::RunArgsValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyEnvVars, TargetProperties::EnvVarsValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyInputPath, TargetProperties::InputPathValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyOutputPath, TargetProperties::OutputPathValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyErrorPath, TargetProperties::ErrorPathValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, TargetProperties::DetachOnErrorValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback, this);
+ m_collection_sp->SetValueChangedCallback(ePropertyDisableSTDIO, TargetProperties::DisableSTDIOValueChangedCallback, this);
+
+ // Update m_launch_info once it was created
+ Arg0ValueChangedCallback(this, NULL);
+ RunArgsValueChangedCallback(this, NULL);
+ //EnvVarsValueChangedCallback(this, NULL); // FIXME: cause segfault in Target::GetPlatform()
+ InputPathValueChangedCallback(this, NULL);
+ OutputPathValueChangedCallback(this, NULL);
+ ErrorPathValueChangedCallback(this, NULL);
+ DetachOnErrorValueChangedCallback(this, NULL);
+ DisableASLRValueChangedCallback(this, NULL);
+ DisableSTDIOValueChangedCallback(this, NULL);
}
else
{
@@ -2954,6 +3181,7 @@ TargetProperties::TargetProperties (Target *target) :
true,
Process::GetGlobalProperties()->GetValueProperties());
}
+
}
TargetProperties::~TargetProperties ()
@@ -2976,6 +3204,13 @@ TargetProperties::SetDefaultArchitecture (const ArchSpec& arch)
return value->SetCurrentValue(arch, true);
}
+bool
+TargetProperties::GetMoveToNearestCode() const
+{
+ const uint32_t idx = ePropertyMoveToNearestCode;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
lldb::DynamicValueType
TargetProperties::GetPreferDynamicValue() const
{
@@ -2984,6 +3219,14 @@ TargetProperties::GetPreferDynamicValue() const
}
bool
+TargetProperties::SetPreferDynamicValue (lldb::DynamicValueType d)
+{
+ const uint32_t idx = ePropertyPreferDynamic;
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(NULL, idx, d);
+}
+
+
+bool
TargetProperties::GetDisableASLR () const
{
const uint32_t idx = ePropertyDisableASLR;
@@ -3055,6 +3298,7 @@ TargetProperties::SetArg0 (const char *arg)
{
const uint32_t idx = ePropertyArg0;
m_collection_sp->SetPropertyAtIndexAsString (NULL, idx, arg);
+ m_launch_info.SetArg0(arg);
}
bool
@@ -3069,6 +3313,7 @@ TargetProperties::SetRunArguments (const Args &args)
{
const uint32_t idx = ePropertyRunArgs;
m_collection_sp->SetPropertyAtIndexFromArgs (NULL, idx, args);
+ m_launch_info.GetArguments() = args;
}
size_t
@@ -3078,6 +3323,14 @@ TargetProperties::GetEnvironmentAsArgs (Args &env) const
return m_collection_sp->GetPropertyAtIndexAsArgs (NULL, idx, env);
}
+void
+TargetProperties::SetEnvironmentFromArgs (const Args &env)
+{
+ const uint32_t idx = ePropertyEnvVars;
+ m_collection_sp->SetPropertyAtIndexFromArgs (NULL, idx, env);
+ m_launch_info.GetEnvironmentEntries() = env;
+}
+
bool
TargetProperties::GetSkipPrologue() const
{
@@ -3112,6 +3365,22 @@ TargetProperties::GetDebugFileSearchPaths ()
return option_value->GetCurrentValue();
}
+FileSpecList &
+TargetProperties::GetClangModuleSearchPaths ()
+{
+ const uint32_t idx = ePropertyClangModuleSearchPaths;
+ OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList (NULL, false, idx);
+ assert(option_value);
+ return option_value->GetCurrentValue();
+}
+
+bool
+TargetProperties::GetEnableAutoImportClangModules() const
+{
+ const uint32_t idx = ePropertyAutoImportClangModules;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
bool
TargetProperties::GetEnableSyntheticValue () const
{
@@ -3260,49 +3529,182 @@ TargetProperties::SetUserSpecifiedTrapHandlerNames (const Args &args)
m_collection_sp->SetPropertyAtIndexFromArgs (NULL, idx, args);
}
-//----------------------------------------------------------------------
-// Target::TargetEventData
-//----------------------------------------------------------------------
-const ConstString &
-Target::TargetEventData::GetFlavorString ()
+bool
+TargetProperties::GetDisplayRuntimeSupportValues () const
{
- static ConstString g_flavor ("Target::TargetEventData");
- return g_flavor;
+ const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, false);
}
-const ConstString &
-Target::TargetEventData::GetFlavor () const
+void
+TargetProperties::SetDisplayRuntimeSupportValues (bool b)
{
- return TargetEventData::GetFlavorString ();
+ const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
+ m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
}
-Target::TargetEventData::TargetEventData (const lldb::TargetSP &new_target_sp) :
- EventData(),
- m_target_sp (new_target_sp)
+bool
+TargetProperties::GetNonStopModeEnabled () const
{
+ const uint32_t idx = ePropertyNonStopModeEnabled;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, false);
}
-Target::TargetEventData::~TargetEventData()
+void
+TargetProperties::SetNonStopModeEnabled (bool b)
{
+ const uint32_t idx = ePropertyNonStopModeEnabled;
+ m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
+}
+const ProcessLaunchInfo &
+TargetProperties::GetProcessLaunchInfo ()
+{
+ m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work
+ return m_launch_info;
}
void
-Target::TargetEventData::Dump (Stream *s) const
+TargetProperties::SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info)
{
+ m_launch_info = launch_info;
+ SetArg0(launch_info.GetArg0());
+ SetRunArguments(launch_info.GetArguments());
+ SetEnvironmentFromArgs(launch_info.GetEnvironmentEntries());
+ const FileAction *input_file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+ if (input_file_action)
+ {
+ const char *input_path = input_file_action->GetPath();
+ if (input_path)
+ SetStandardInputPath(input_path);
+ }
+ const FileAction *output_file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+ if (output_file_action)
+ {
+ const char *output_path = output_file_action->GetPath();
+ if (output_path)
+ SetStandardOutputPath(output_path);
+ }
+ const FileAction *error_file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+ if (error_file_action)
+ {
+ const char *error_path = error_file_action->GetPath();
+ if (error_path)
+ SetStandardErrorPath(error_path);
+ }
+ SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
+ SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
+ SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
+}
+void
+TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ this_->m_launch_info.SetArg0(this_->GetArg0());
}
-const TargetSP
-Target::TargetEventData::GetTargetFromEvent (const lldb::EventSP &event_sp)
+void
+TargetProperties::RunArgsValueChangedCallback(void *target_property_ptr, OptionValue *)
{
- TargetSP target_sp;
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ Args args;
+ if (this_->GetRunArguments(args))
+ this_->m_launch_info.GetArguments() = args;
+}
- const TargetEventData *data = GetEventDataFromEvent (event_sp.get());
- if (data)
- target_sp = data->m_target_sp;
+void
+TargetProperties::EnvVarsValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ Args args;
+ if (this_->GetEnvironmentAsArgs(args))
+ this_->m_launch_info.GetEnvironmentEntries() = args;
+}
- return target_sp;
+void
+TargetProperties::InputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ this_->m_launch_info.AppendOpenFileAction(STDIN_FILENO, this_->GetStandardInputPath(), true, false);
+}
+
+void
+TargetProperties::OutputPathValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ this_->m_launch_info.AppendOpenFileAction(STDOUT_FILENO, this_->GetStandardOutputPath(), false, true);
+}
+
+void
+TargetProperties::ErrorPathValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ this_->m_launch_info.AppendOpenFileAction(STDERR_FILENO, this_->GetStandardErrorPath(), false, true);
+}
+
+void
+TargetProperties::DetachOnErrorValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ if (this_->GetDetachOnError())
+ this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);
+ else
+ this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);
+}
+
+void
+TargetProperties::DisableASLRValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ if (this_->GetDisableASLR())
+ this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);
+ else
+ this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);
+}
+
+void
+TargetProperties::DisableSTDIOValueChangedCallback(void *target_property_ptr, OptionValue *)
+{
+ TargetProperties *this_ = reinterpret_cast<TargetProperties *>(target_property_ptr);
+ if (this_->GetDisableSTDIO())
+ this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
+ else
+ this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);
+}
+
+//----------------------------------------------------------------------
+// Target::TargetEventData
+//----------------------------------------------------------------------
+
+Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp) :
+ EventData (),
+ m_target_sp (target_sp),
+ m_module_list ()
+{
+}
+
+Target::TargetEventData::TargetEventData (const lldb::TargetSP &target_sp, const ModuleList &module_list) :
+ EventData (),
+ m_target_sp (target_sp),
+ m_module_list (module_list)
+{
+}
+
+Target::TargetEventData::~TargetEventData()
+{
+}
+
+const ConstString &
+Target::TargetEventData::GetFlavorString ()
+{
+ static ConstString g_flavor ("Target::TargetEventData");
+ return g_flavor;
+}
+
+void
+Target::TargetEventData::Dump (Stream *s) const
+{
}
const Target::TargetEventData *
@@ -3317,3 +3719,22 @@ Target::TargetEventData::GetEventDataFromEvent (const Event *event_ptr)
return NULL;
}
+TargetSP
+Target::TargetEventData::GetTargetFromEvent (const Event *event_ptr)
+{
+ TargetSP target_sp;
+ const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
+ if (event_data)
+ target_sp = event_data->m_target_sp;
+ return target_sp;
+}
+
+ModuleList
+Target::TargetEventData::GetModuleListFromEvent (const Event *event_ptr)
+{
+ ModuleList module_list;
+ const TargetEventData *event_data = GetEventDataFromEvent (event_ptr);
+ if (event_data)
+ module_list = event_data->m_module_list;
+ return module_list;
+}
diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp
index bbed0fb0bc12..552e951496f2 100644
--- a/source/Target/TargetList.cpp
+++ b/source/Target/TargetList.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -293,32 +291,27 @@ TargetList::CreateTargetInternal (Debugger &debugger,
}
}
- if (!platform_sp)
+ // If we have a valid architecture, make sure the current platform is
+ // compatible with that architecture
+ if (!prefer_platform_arch && arch.IsValid())
{
- // Get the current platform and make sure it is compatible with the
- // current architecture if we have a valid architecture.
- platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
-
- if (!prefer_platform_arch && arch.IsValid())
+ if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
{
- if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
- {
- platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
- if (platform_sp)
- debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
- }
+ platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
+ if (!is_dummy_target && platform_sp)
+ debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
}
- else if (platform_arch.IsValid())
+ }
+ else if (platform_arch.IsValid())
+ {
+ // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
+ // a single architecture which should be used
+ ArchSpec fixed_platform_arch;
+ if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
{
- // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
- // a single architecture which should be used
- ArchSpec fixed_platform_arch;
- if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
- {
- platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
- if (platform_sp)
- debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
- }
+ platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
+ if (!is_dummy_target && platform_sp)
+ debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
}
}
@@ -419,7 +412,7 @@ TargetList::CreateTargetInternal (Debugger &debugger,
if (file.GetFileType() == FileSpec::eFileTypeDirectory)
user_exe_path_is_bundle = true;
- if (file.IsRelativeToCurrentWorkingDirectory() && user_exe_path)
+ if (file.IsRelative() && user_exe_path)
{
// Ignore paths that start with "./" and "../"
if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 6fd5cdf0d15c..29ba86a7e84d 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
-#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
@@ -20,7 +17,10 @@
#include "lldb/Core/RegularExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Property.h"
#include "lldb/Symbol/Function.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -655,11 +655,6 @@ Thread::SetupForResume ()
// telling the current plan it will resume, since we might change what the current
// plan is.
-// StopReason stop_reason = lldb::eStopReasonInvalid;
-// StopInfoSP stop_info_sp = GetStopInfo();
-// if (stop_info_sp.get())
-// stop_reason = stop_info_sp->GetStopReason();
-// if (stop_reason == lldb::eStopReasonBreakpoint)
lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
if (reg_ctx_sp)
{
@@ -725,7 +720,7 @@ Thread::ShouldResume (StateType resume_state)
// the target, 'cause that slows down single stepping. So assume that if we got to the point where
// we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
// about the fact that we are resuming...
- const uint32_t process_stop_id = GetProcess()->GetStopID();
+ const uint32_t process_stop_id = GetProcess()->GetStopID();
if (m_stop_info_stop_id == process_stop_id &&
(m_stop_info_sp && m_stop_info_sp->IsValid()))
{
@@ -1211,7 +1206,7 @@ Thread::GetReturnValueObject ()
ValueObjectSP return_valobj_sp;
return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject();
if (return_valobj_sp)
- return return_valobj_sp;
+ return return_valobj_sp;
}
}
return ValueObjectSP();
@@ -1227,7 +1222,7 @@ Thread::GetExpressionVariable ()
ClangExpressionVariableSP expression_variable_sp;
expression_variable_sp = m_completed_plan_stack[i]->GetExpressionVariable();
if (expression_variable_sp)
- return expression_variable_sp;
+ return expression_variable_sp;
}
}
return ClangExpressionVariableSP();
@@ -2207,8 +2202,7 @@ Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool print_j
strm.Printf("\n");
StructuredData::ObjectSP thread_info = GetExtendedInfo();
- StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo();
-
+
if (print_json_thread || print_json_stopinfo)
{
if (thread_info && print_json_thread)
@@ -2216,13 +2210,17 @@ Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool print_j
thread_info->Dump (strm);
strm.Printf("\n");
}
-
- if (stop_info && print_json_stopinfo)
+
+ if (print_json_stopinfo && m_stop_info_sp)
{
- stop_info->Dump (strm);
- strm.Printf("\n");
+ StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo();
+ if (stop_info)
+ {
+ stop_info->Dump (strm);
+ strm.Printf("\n");
+ }
}
-
+
return true;
}
@@ -2315,7 +2313,10 @@ Thread::GetUnwinder ()
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::thumb:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::hexagon:
diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp
index db4407b4b579..d581a7c96060 100644
--- a/source/Target/ThreadList.cpp
+++ b/source/Target/ThreadList.cpp
@@ -17,6 +17,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConvertEnum.h"
using namespace lldb;
using namespace lldb_private;
@@ -246,8 +247,8 @@ ThreadList::ShouldStop (Event *event_ptr)
// figuring out whether the thread plan conditions are met. So we don't want
// to keep the ThreadList locked the whole time we are doing this.
// FIXME: It is possible that running code could cause new threads
- // to be created. If that happens we will miss asking them whether
- // then should stop. This is not a big deal, since we haven't had
+ // to be created. If that happens, we will miss asking them whether
+ // they should stop. This is not a big deal since we haven't had
// a chance to hang any interesting operations on those threads yet.
collection threads_copy;
@@ -581,6 +582,7 @@ ThreadList::WillResume ()
if (thread_sp == GetSelectedThread())
{
+ // If the currently selected thread wants to run on its own, always let it.
run_only_current_thread = true;
run_me_only_list.Clear();
run_me_only_list.AddThread (thread_sp);
diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp
index 2c9b7fce7c24..094a6bff3722 100644
--- a/source/Target/ThreadPlan.cpp
+++ b/source/Target/ThreadPlan.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/ThreadPlan.h"
// C Includes
@@ -22,6 +20,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/ConvertEnum.h"
using namespace lldb;
using namespace lldb_private;
@@ -156,6 +155,7 @@ ThreadPlan::WillResume (StateType resume_state, bool current_plan)
if (log)
{
RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
+ assert (reg_ctx);
addr_t pc = reg_ctx->GetPC();
addr_t sp = reg_ctx->GetSP();
addr_t fp = reg_ctx->GetFP();
diff --git a/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp
index 5a3ebd7b1284..e742ece7ec50 100644
--- a/source/Target/ThreadPlanCallFunction.cpp
+++ b/source/Target/ThreadPlanCallFunction.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
@@ -22,6 +21,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -407,7 +407,7 @@ ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
// signal that is set not to stop. Check that here first. We just say we explain the stop
// but aren't done and everything will continue on from there.
- if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
+ if (m_real_stop_info_sp && m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
{
SetPlanComplete(false);
if (m_subplan_sp)
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index 90b8cf81171f..1773777cc4da 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -14,13 +14,13 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
@@ -41,7 +41,7 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression (Thread &thread,
Address &function,
llvm::ArrayRef<lldb::addr_t> args,
const EvaluateExpressionOptions &options,
- ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
+ lldb::ClangUserExpressionSP &user_expression_sp) :
ThreadPlanCallFunction (thread, function, ClangASTType(), args, options),
m_user_expression_sp (user_expression_sp)
{
diff --git a/source/Target/ThreadPlanPython.cpp b/source/Target/ThreadPlanPython.cpp
index e196d81c897a..8cb3ada428e2 100644
--- a/source/Target/ThreadPlanPython.cpp
+++ b/source/Target/ThreadPlanPython.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/ThreadPlan.h"
// C Includes
@@ -20,7 +18,6 @@
#include "lldb/Core/State.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
diff --git a/source/Target/ThreadPlanRunToAddress.cpp b/source/Target/ThreadPlanRunToAddress.cpp
index e2f85c0c5f5f..54ae1dc22981 100644
--- a/source/Target/ThreadPlanRunToAddress.cpp
+++ b/source/Target/ThreadPlanRunToAddress.cpp
@@ -13,7 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/Target.h"
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index e5f057c183fb..3ee57928b1db 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -13,8 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
@@ -526,6 +524,7 @@ ThreadPlanStepInRange::DoPlanExplainsStop (Event *event_ptr)
bool
ThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_plan)
{
+ m_virtual_step = false;
if (resume_state == eStateStepping && current_plan)
{
// See if we are about to step over a virtual inlined call.
diff --git a/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp
index 0f6d7b78a9ce..1ce26df78fe6 100644
--- a/source/Target/ThreadPlanStepInstruction.cpp
+++ b/source/Target/ThreadPlanStepInstruction.cpp
@@ -14,7 +14,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/Process.h"
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index 0ded99b3091d..8b702a20ccd2 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -14,13 +14,13 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
diff --git a/source/Target/ThreadPlanStepOverBreakpoint.cpp b/source/Target/ThreadPlanStepOverBreakpoint.cpp
index 6f285e25fd0b..da0326bfa914 100644
--- a/source/Target/ThreadPlanStepOverBreakpoint.cpp
+++ b/source/Target/ThreadPlanStepOverBreakpoint.cpp
@@ -13,7 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/Process.h"
diff --git a/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp
index a6d65e4d8116..701e93d3c4de 100644
--- a/source/Target/ThreadPlanStepOverRange.cpp
+++ b/source/Target/ThreadPlanStepOverRange.cpp
@@ -13,8 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/Block.h"
@@ -248,7 +246,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
&& sc.comp_unit == m_addr_context.comp_unit
&& sc.function == m_addr_context.function)
{
- // Okay, find the next occurance of this file in the line table:
+ // Okay, find the next occurrence of this file in the line table:
LineTable *line_table = m_addr_context.comp_unit->GetLineTable();
if (line_table)
{
@@ -261,7 +259,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
bool step_past_remaining_inline = false;
if (entry_idx > 0)
{
- // We require the the previous line entry and the current line entry come
+ // We require the previous line entry and the current line entry come
// from the same file.
// The other requirement is that the previous line table entry be part of an
// inlined block, we don't want to step past cases where people have inlined
diff --git a/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp
index adc515cebc08..3aed85859507 100644
--- a/source/Target/ThreadPlanStepRange.cpp
+++ b/source/Target/ThreadPlanStepRange.cpp
@@ -13,8 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-
-#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Disassembler.h"
@@ -245,9 +243,9 @@ ThreadPlanStepRange::InSymbol()
{
return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
}
- else if (m_addr_context.symbol)
+ else if (m_addr_context.symbol && m_addr_context.symbol->ValueIsAddress())
{
- AddressRange range(m_addr_context.symbol->GetAddress(), m_addr_context.symbol->GetByteSize());
+ AddressRange range(m_addr_context.symbol->GetAddressRef(), m_addr_context.symbol->GetByteSize());
return range.ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
}
return false;
@@ -382,8 +380,9 @@ ThreadPlanStepRange::SetNextBranchBreakpoint ()
return false;
else
{
+ Target &target = GetThread().GetProcess()->GetTarget();
uint32_t branch_index;
- branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index);
+ branch_index = instructions->GetIndexOfNextBranchInstruction (pc_index, target);
Address run_to_address;
diff --git a/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp
index 5b50a41a6398..068d8e6584fd 100644
--- a/source/Target/ThreadPlanStepThrough.cpp
+++ b/source/Target/ThreadPlanStepThrough.cpp
@@ -13,7 +13,6 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/DynamicLoader.h"
diff --git a/source/Target/ThreadPlanStepUntil.cpp b/source/Target/ThreadPlanStepUntil.cpp
index fa5ab8c5d491..4c3d4a6a049e 100644
--- a/source/Target/ThreadPlanStepUntil.cpp
+++ b/source/Target/ThreadPlanStepUntil.cpp
@@ -18,7 +18,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp
index 0629eb9981ef..406708f8c396 100644
--- a/source/Target/ThreadPlanTracer.cpp
+++ b/source/Target/ThreadPlanTracer.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
#include "lldb/Target/ThreadPlan.h"
// C Includes
@@ -18,6 +16,7 @@
// Project includes
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
@@ -25,7 +24,9 @@
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
+#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
@@ -220,7 +221,8 @@ ThreadPlanAssemblyTracer::Log ()
NULL,
NULL,
NULL,
- disassemble_format);
+ disassemble_format,
+ 0);
}
}
}