Debugger.cpp revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ConnectionFileDescriptor.h"
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Debugger.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/InputReader.h"
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/State.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Timer.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/TargetList.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint Debugger::g_shared_debugger_refcount = 0;
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool Debugger::g_in_terminate = false;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::DebuggerSP &
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetDebuggerSP ()
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static DebuggerSP g_shared_debugger_sp;
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return g_shared_debugger_sp;
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::Initialize ()
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    g_shared_debugger_refcount++;
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (GetDebuggerSP().get() == NULL)
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        GetDebuggerSP().reset (new Debugger());
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        lldb_private::Initialize();
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        GetDebuggerSP()->GetCommandInterpreter().Initialize();
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::Terminate ()
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    g_shared_debugger_refcount--;
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (g_shared_debugger_refcount == 0)
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Because Terminate is called also in the destructor, we need to make sure
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // that none of the calls to GetSharedInstance leads to a call to Initialize,
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // thus bumping the refcount back to 1 & causing Debugger::~Debugger to try to
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // re-terminate.  So we use g_in_terminate to indicate this condition.
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // When we can require at least Initialize to be called, we won't have to do
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // this since then the GetSharedInstance won't have to auto-call Initialize...
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        g_in_terminate = true;
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int num_targets = GetDebuggerSP()->GetTargetList().GetNumTargets();
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (int i = 0; i < num_targets; i++)
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ProcessSP process_sp(GetDebuggerSP()->GetTargetList().GetTargetAtIndex (i)->GetProcessSP());
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (process_sp)
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                process_sp->Destroy();
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        GetDebuggerSP()->DisconnectInput();
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        lldb_private::WillTerminate();
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        GetDebuggerSP().reset();
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger &
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetSharedInstance()
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Don't worry about thread race conditions with the code below as
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // lldb_private::Initialize(); does this in a thread safe way. I just
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // want to avoid having to lock and unlock a mutex in
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // lldb_private::Initialize(); every time we want to access the
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Debugger shared instance.
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // FIXME: We intend to require clients to call Initialize by hand (since they
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // will also have to call Terminate by hand.)  But for now it is not clear where
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // we can reliably call these in JH.  So the present version initializes on first use
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // here, and terminates in the destructor.
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (g_shared_debugger_refcount == 0 && !g_in_terminate)
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Initialize();
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    assert(GetDebuggerSP().get()!= NULL);
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return *(GetDebuggerSP().get());
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::Debugger () :
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_comm("debugger.input"),
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_file (),
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_output_file (),
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_error_file (),
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_async_execution (true),
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_target_list (),
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_listener ("lldb.Debugger"),
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_source_manager (),
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_command_interpreter (eScriptLanguageDefault, false, &m_listener, m_source_manager),
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_readers (),
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_reader_data ()
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::~Debugger ()
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // FIXME:
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Remove this once this version of lldb has made its way through a build.
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Terminate();
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetAsyncExecution ()
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_async_execution;
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::SetAsyncExecution (bool async_execution)
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static bool value_has_been_set = false;
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!value_has_been_set)
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        value_has_been_set = true;
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_async_execution = async_execution;
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_command_interpreter.SetSynchronous (!async_execution);
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::DisconnectInput()
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_comm.Clear ();
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_file.SetFileHandle (fh, tranfer_ownership);
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_input_file.GetFileHandle() == NULL)
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_input_file.SetFileHandle (stdin, false);
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Disconnect from any old connection if we had one
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_comm.Disconnect ();
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true));
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Error error;
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_input_comm.StartReadThread (&error) == false)
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        FILE *err_fh = GetErrorFileHandle();
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (err_fh)
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exit(1);
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFILE *
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetInputFileHandle ()
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_input_file.GetFileHandle();
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_output_file.SetFileHandle (fh, tranfer_ownership);
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_output_file.GetFileHandle() == NULL)
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_output_file.SetFileHandle (stdin, false);
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFILE *
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetOutputFileHandle ()
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_output_file.GetFileHandle();
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_error_file.SetFileHandle (fh, tranfer_ownership);
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_error_file.GetFileHandle() == NULL)
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_error_file.SetFileHandle (stdin, false);
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFILE *
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetErrorFileHandle ()
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_error_file.GetFileHandle();
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerCommandInterpreter &
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetCommandInterpreter ()
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_command_interpreter;
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerListener &
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetListener ()
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_listener;
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerTargetSP
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetCurrentTarget ()
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_target_list.GetCurrentTarget ();
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerExecutionContext
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetCurrentExecutionContext ()
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ExecutionContext exe_ctx;
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    exe_ctx.Clear();
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lldb::TargetSP target_sp = GetCurrentTarget();
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    exe_ctx.target = target_sp.get();
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (target_sp)
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exe_ctx.process = target_sp->GetProcessSP().get();
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exe_ctx.thread = exe_ctx.process->GetThreadList().GetCurrentThread().get();
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (exe_ctx.thread == NULL)
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (exe_ctx.thread)
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                exe_ctx.frame = exe_ctx.thread->GetCurrentFrame().get();
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (exe_ctx.frame == NULL)
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return exe_ctx;
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSourceManager &
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetSourceManager ()
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_source_manager;
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerTargetList&
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::GetTargetList ()
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_target_list;
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::DispatchInput (const char *bytes, size_t bytes_len)
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (bytes == NULL || bytes_len == 0)
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // TODO: implement the STDIO to the process as an input reader...
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    TargetSP target = GetCurrentTarget();
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (target.get() != NULL)
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ProcessSP process_sp = target->GetProcessSP();
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (process_sp.get() != NULL
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            && StateIsRunningState (process_sp->GetState()))
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            Error error;
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (process_sp->PutSTDIN (bytes, bytes_len, error) == bytes_len)
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return;
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    WriteToDefaultReader (bytes, bytes_len);
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (bytes && bytes_len)
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_input_reader_data.append (bytes, bytes_len);
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_input_reader_data.empty())
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (!m_input_readers.empty() && !m_input_reader_data.empty())
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (CheckIfTopInputReaderIsDone ())
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            /* Do nothing. */;
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Get the input reader from the top of the stack
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InputReaderSP reader_sp(m_input_readers.top());
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!reader_sp)
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.data(),
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                          m_input_reader_data.size());
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (bytes_handled)
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_input_reader_data.erase (0, bytes_handled);
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // No bytes were handled, we might not have reached our
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // granularity, just return and wait for more data
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Flush out any input readers that are donesvn
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (CheckIfTopInputReaderIsDone ())
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        /* Do nothing. */;
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::PushInputReader (const InputReaderSP& reader_sp)
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reader_sp)
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!m_input_readers.empty())
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Deactivate the old top reader
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InputReaderSP top_reader_sp (m_input_readers.top());
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (top_reader_sp)
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            top_reader_sp->Notify (eInputReaderDeactivate);
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_input_readers.push (reader_sp);
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    reader_sp->Notify (eInputReaderActivate);
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ActivateInputReader (reader_sp);
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool result = false;
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The reader on the stop of the stack is done, so let the next
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // read on the stack referesh its prompt and if there is one...
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!m_input_readers.empty())
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InputReaderSP reader_sp(m_input_readers.top());
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_input_readers.pop ();
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            reader_sp->Notify (eInputReaderDeactivate);
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            reader_sp->Notify (eInputReaderDone);
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            result = true;
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (!m_input_readers.empty())
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                reader_sp = m_input_readers.top();
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (reader_sp)
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ActivateInputReader (reader_sp);
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    reader_sp->Notify (eInputReaderReactivate);
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return result;
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::CheckIfTopInputReaderIsDone ()
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool result = false;
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!m_input_readers.empty())
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        InputReaderSP reader_sp(m_input_readers.top());
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (reader_sp && reader_sp->IsDone())
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            result = true;
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            PopInputReader (reader_sp);
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return result;
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDebugger::ActivateInputReader (const InputReaderSP &reader_sp)
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    FILE *in_fh = GetInputFileHandle();
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (in_fh)
40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        struct termios in_fh_termios;
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int in_fd = fileno (in_fh);
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (::tcgetattr(in_fd, &in_fh_termios) == 0)
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (reader_sp->GetEcho())
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                in_fh_termios.c_lflag |= ECHO;  // Turn on echoing
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                in_fh_termios.c_lflag &= ~ECHO; // Turn off echoing
41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            switch (reader_sp->GetGranularity())
41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case eInputReaderGranularityByte:
41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case eInputReaderGranularityWord:
42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                in_fh_termios.c_lflag &= ~ICANON;   // Get one char at a time
42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case eInputReaderGranularityLine:
42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            case eInputReaderGranularityAll:
42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                in_fh_termios.c_lflag |= ICANON;   // Get lines at a time
42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            default:
42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                break;
43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ::tcsetattr (in_fd, TCSANOW, &in_fh_termios);
43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
435