summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core')
-rw-r--r--lldb/source/Core/Debugger.cpp189
-rw-r--r--lldb/source/Core/Disassembler.cpp3
-rw-r--r--lldb/source/Core/InputReader.cpp30
-rw-r--r--lldb/source/Core/Log.cpp16
4 files changed, 138 insertions, 100 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index c106d838fed..0b7676ca732 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -13,7 +13,7 @@
#include "lldb/Core/InputReader.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
-
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
@@ -22,115 +22,137 @@
using namespace lldb;
using namespace lldb_private;
-int Debugger::g_shared_debugger_refcount = 0;
-bool Debugger::g_in_terminate = false;
-
-Debugger::DebuggerSP &
-Debugger::GetDebuggerSP ()
-{
- static DebuggerSP g_shared_debugger_sp;
- return g_shared_debugger_sp;
-}
+static uint32_t g_shared_debugger_refcount = 0;
void
Debugger::Initialize ()
{
- g_shared_debugger_refcount++;
- if (GetDebuggerSP().get() == NULL)
- {
- GetDebuggerSP().reset (new Debugger());
+ if (g_shared_debugger_refcount == 0)
lldb_private::Initialize();
- GetDebuggerSP()->GetCommandInterpreter().Initialize();
- }
+ g_shared_debugger_refcount++;
}
void
Debugger::Terminate ()
{
- g_shared_debugger_refcount--;
- if (g_shared_debugger_refcount == 0)
+ if (g_shared_debugger_refcount > 0)
{
- // Because Terminate is called also in the destructor, we need to make sure
- // that none of the calls to GetSharedInstance leads to a call to Initialize,
- // thus bumping the refcount back to 1 & causing Debugger::~Debugger to try to
- // re-terminate. So we use g_in_terminate to indicate this condition.
- // When we can require at least Initialize to be called, we won't have to do
- // this since then the GetSharedInstance won't have to auto-call Initialize...
-
- g_in_terminate = true;
- int num_targets = GetDebuggerSP()->GetTargetList().GetNumTargets();
- for (int i = 0; i < num_targets; i++)
+ g_shared_debugger_refcount--;
+ if (g_shared_debugger_refcount == 0)
{
- ProcessSP process_sp(GetDebuggerSP()->GetTargetList().GetTargetAtIndex (i)->GetProcessSP());
- if (process_sp)
- process_sp->Destroy();
+ lldb_private::WillTerminate();
+ lldb_private::Terminate();
}
- GetDebuggerSP()->DisconnectInput();
- lldb_private::WillTerminate();
- GetDebuggerSP().reset();
}
}
-Debugger &
-Debugger::GetSharedInstance()
+typedef std::vector<DebuggerSP> DebuggerList;
+
+static Mutex &
+GetDebuggerListMutex ()
+{
+ static Mutex g_mutex(Mutex::eMutexTypeRecursive);
+ return g_mutex;
+}
+
+static DebuggerList &
+GetDebuggerList()
+{
+ // hide the static debugger list inside a singleton accessor to avoid
+ // global init contructors
+ static DebuggerList g_list;
+ return g_list;
+}
+
+
+DebuggerSP
+Debugger::CreateInstance ()
+{
+ DebuggerSP debugger_sp (new Debugger);
+ // Scope for locker
+ {
+ Mutex::Locker locker (GetDebuggerListMutex ());
+ GetDebuggerList().push_back(debugger_sp);
+ }
+ return debugger_sp;
+}
+
+lldb::DebuggerSP
+Debugger::GetSP ()
{
- // Don't worry about thread race conditions with the code below as
- // lldb_private::Initialize(); does this in a thread safe way. I just
- // want to avoid having to lock and unlock a mutex in
- // lldb_private::Initialize(); every time we want to access the
- // Debugger shared instance.
+ lldb::DebuggerSP debugger_sp;
- // FIXME: We intend to require clients to call Initialize by hand (since they
- // will also have to call Terminate by hand.) But for now it is not clear where
- // we can reliably call these in JH. So the present version initializes on first use
- // here, and terminates in the destructor.
- if (g_shared_debugger_refcount == 0 && !g_in_terminate)
- Initialize();
-
- assert(GetDebuggerSP().get()!= NULL);
- return *(GetDebuggerSP().get());
+ Mutex::Locker locker (GetDebuggerListMutex ());
+ DebuggerList &debugger_list = GetDebuggerList();
+ DebuggerList::iterator pos, end = debugger_list.end();
+ for (pos = debugger_list.begin(); pos != end; ++pos)
+ {
+ if ((*pos).get() == this)
+ {
+ debugger_sp = *pos;
+ break;
+ }
+ }
+ return debugger_sp;
}
+
+TargetSP
+Debugger::FindTargetWithProcessID (lldb::pid_t pid)
+{
+ lldb::TargetSP target_sp;
+ Mutex::Locker locker (GetDebuggerListMutex ());
+ DebuggerList &debugger_list = GetDebuggerList();
+ DebuggerList::iterator pos, end = debugger_list.end();
+ for (pos = debugger_list.begin(); pos != end; ++pos)
+ {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
+ if (target_sp)
+ break;
+ }
+ return target_sp;
+}
+
+
Debugger::Debugger () :
m_input_comm("debugger.input"),
m_input_file (),
m_output_file (),
m_error_file (),
- m_async_execution (true),
m_target_list (),
m_listener ("lldb.Debugger"),
m_source_manager (),
- m_command_interpreter (eScriptLanguageDefault, false, &m_listener, m_source_manager),
+ m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
+ m_exe_ctx (),
m_input_readers (),
m_input_reader_data ()
{
+ m_command_interpreter_ap->Initialize ();
}
Debugger::~Debugger ()
{
- // FIXME:
- // Remove this once this version of lldb has made its way through a build.
- Terminate();
+ int num_targets = m_target_list.GetNumTargets();
+ for (int i = 0; i < num_targets; i++)
+ {
+ ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
+ if (process_sp)
+ process_sp->Destroy();
+ }
+ DisconnectInput();
}
bool
Debugger::GetAsyncExecution ()
{
- return m_async_execution;
+ return !m_command_interpreter_ap->GetSynchronous();
}
void
Debugger::SetAsyncExecution (bool async_execution)
{
- static bool value_has_been_set = false;
-
- if (!value_has_been_set)
- {
- value_has_been_set = true;
- m_async_execution = async_execution;
- m_command_interpreter.SetSynchronous (!async_execution);
- }
+ m_command_interpreter_ap->SetSynchronous (!async_execution);
}
void
@@ -203,7 +225,8 @@ Debugger::GetErrorFileHandle ()
CommandInterpreter &
Debugger::GetCommandInterpreter ()
{
- return m_command_interpreter;
+ assert (m_command_interpreter_ap.get());
+ return *m_command_interpreter_ap;
}
Listener &
@@ -432,3 +455,39 @@ Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
}
}
}
+
+void
+Debugger::UpdateExecutionContext (ExecutionContext *override_context)
+{
+ m_exe_ctx.Clear();
+
+ if (override_context != NULL)
+ {
+ m_exe_ctx.target = override_context->target;
+ m_exe_ctx.process = override_context->process;
+ m_exe_ctx.thread = override_context->thread;
+ m_exe_ctx.frame = override_context->frame;
+ }
+ else
+ {
+ TargetSP target_sp (GetCurrentTarget());
+ if (target_sp)
+ {
+ m_exe_ctx.target = target_sp.get();
+ m_exe_ctx.process = target_sp->GetProcessSP().get();
+ if (m_exe_ctx.process && m_exe_ctx.process->IsRunning() == false)
+ {
+ m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetCurrentThread().get();
+ if (m_exe_ctx.thread == NULL)
+ m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
+ if (m_exe_ctx.thread)
+ {
+ m_exe_ctx.frame = m_exe_ctx.thread->GetCurrentFrame().get();
+ if (m_exe_ctx.frame == NULL)
+ m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
+ }
+ }
+ }
+ }
+}
+
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 570ff726225..9cdf618c087 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -55,6 +55,7 @@ Disassembler::FindPlugin (const ArchSpec &arch)
bool
Disassembler::Disassemble
(
+ Debugger &debugger,
const ArchSpec &arch,
const ExecutionContext &exe_ctx,
uint32_t mixed_context_lines,
@@ -144,7 +145,7 @@ Disassembler::Disassemble
if (sc.comp_unit && sc.line_entry.IsValid())
{
- Debugger::GetSharedInstance().GetSourceManager().DisplaySourceLinesWithLineNumbers (
+ debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (
sc.line_entry.file,
sc.line_entry.line,
mixed_context_lines,
diff --git a/lldb/source/Core/InputReader.cpp b/lldb/source/Core/InputReader.cpp
index c139a87387a..afda9fa25f6 100644
--- a/lldb/source/Core/InputReader.cpp
+++ b/lldb/source/Core/InputReader.cpp
@@ -15,7 +15,8 @@
using namespace lldb;
using namespace lldb_private;
-InputReader::InputReader () :
+InputReader::InputReader (Debugger &debugger) :
+ m_debugger (debugger),
m_callback (NULL),
m_callback_baton (NULL),
m_end_token (),
@@ -126,7 +127,7 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
break;
}
- if (m_callback (m_callback_baton, this, eInputReaderGotToken, p, 1) == 0)
+ if (m_callback (m_callback_baton, *this, eInputReaderGotToken, p, 1) == 0)
break;
++p;
if (IsDone())
@@ -175,7 +176,7 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
{
const size_t word_len = p - word_start;
size_t bytes_handled = m_callback (m_callback_baton,
- this,
+ *this,
eInputReaderGotToken,
word_start,
word_len);
@@ -212,7 +213,7 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
{
SetIsDone(true);
m_callback (m_callback_baton,
- this,
+ *this,
eInputReaderGotToken,
line_start,
end_token - line_start);
@@ -221,7 +222,7 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
}
size_t bytes_handled = m_callback (m_callback_baton,
- this,
+ *this,
eInputReaderGotToken,
line_start,
line_length);
@@ -259,7 +260,7 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
{
size_t length = end_token - bytes;
size_t bytes_handled = m_callback (m_callback_baton,
- this,
+ *this,
eInputReaderGotToken,
bytes,
length);
@@ -287,19 +288,6 @@ InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
return 0;
}
-
-FILE *
-InputReader::GetInputFileHandle ()
-{
- return Debugger::GetSharedInstance().GetInputFileHandle ();
-}
-
-FILE *
-InputReader::GetOutputFileHandle ()
-{
- return Debugger::GetSharedInstance().GetOutputFileHandle ();
-}
-
const char *
InputReader::GetPrompt () const
{
@@ -314,7 +302,7 @@ InputReader::RefreshPrompt ()
{
if (!m_prompt.empty())
{
- FILE *out_fh = GetOutputFileHandle();
+ FILE *out_fh = m_debugger.GetOutputFileHandle();
if (out_fh)
::fprintf (out_fh, "%s", m_prompt.c_str());
}
@@ -339,5 +327,5 @@ InputReader::Notify (InputReaderAction notification)
return; // We don't notify the tokens here, it is done in HandleRawBytes
}
if (m_callback)
- m_callback (m_callback_baton, this, notification, NULL, 0);
+ m_callback (m_callback_baton, *this, notification, NULL, 0);
}
diff --git a/lldb/source/Core/Log.cpp b/lldb/source/Core/Log.cpp
index 217f6c40297..1be3c525ae0 100644
--- a/lldb/source/Core/Log.cpp
+++ b/lldb/source/Core/Log.cpp
@@ -43,18 +43,8 @@ StreamForSTDOUTAccess (bool set, StreamSP &stream_sp)
if (set)
g_stream_sp = stream_sp;
else
- {
- if (g_stream_sp)
- stream_sp = g_stream_sp;
- else
- {
- FILE *out_fh = Debugger::GetSharedInstance().GetOutputFileHandle();
- if (out_fh)
- stream_sp.reset(new StreamFile(out_fh));
- else
- stream_sp.reset();
- }
- }
+ stream_sp = g_stream_sp;
+
return stream_sp.get();
}
@@ -91,7 +81,7 @@ StreamForSTDERRAccess (bool set, StreamSP &stream_sp)
// Since we are in a shared library and we can't have global
// constructors, we need to control access to this static variable
// through an accessor function to get and set the value.
- static StreamSP g_stream_sp(new StreamFile(Debugger::GetSharedInstance().GetErrorFileHandle()));
+ static StreamSP g_stream_sp;
if (set)
g_stream_sp = stream_sp;
OpenPOWER on IntegriCloud