summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Debugger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/Debugger.cpp')
-rw-r--r--lldb/source/Core/Debugger.cpp189
1 files changed, 124 insertions, 65 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();
+ }
+ }
+ }
+ }
+}
+
OpenPOWER on IntegriCloud