Home | History | Annotate | Download | only in Linux
      1 //===-- ProcessLinux.cpp ----------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // C Includes
     11 #include <errno.h>
     12 
     13 // C++ Includes
     14 // Other libraries and framework includes
     15 #include "lldb/Core/PluginManager.h"
     16 #include "lldb/Core/State.h"
     17 #include "lldb/Host/Host.h"
     18 #include "lldb/Symbol/ObjectFile.h"
     19 #include "lldb/Target/DynamicLoader.h"
     20 #include "lldb/Target/Target.h"
     21 
     22 #include "ProcessLinux.h"
     23 #include "ProcessPOSIXLog.h"
     24 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
     25 #include "ProcessMonitor.h"
     26 #include "LinuxThread.h"
     27 
     28 using namespace lldb;
     29 using namespace lldb_private;
     30 
     31 //------------------------------------------------------------------------------
     32 // Static functions.
     33 
     34 ProcessSP
     35 ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
     36 {
     37     return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
     38 }
     39 
     40 void
     41 ProcessLinux::Initialize()
     42 {
     43     static bool g_initialized = false;
     44 
     45     if (!g_initialized)
     46     {
     47         g_initialized = true;
     48         PluginManager::RegisterPlugin(GetPluginNameStatic(),
     49                                       GetPluginDescriptionStatic(),
     50                                       CreateInstance);
     51 
     52         Log::Callbacks log_callbacks = {
     53             ProcessPOSIXLog::DisableLog,
     54             ProcessPOSIXLog::EnableLog,
     55             ProcessPOSIXLog::ListLogCategories
     56         };
     57 
     58         Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks);
     59         ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic());
     60     }
     61 }
     62 
     63 //------------------------------------------------------------------------------
     64 // Constructors and destructors.
     65 
     66 ProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
     67     : ProcessPOSIX(target, listener), m_core_file(core_file), m_stopping_threads(false)
     68 {
     69 #if 0
     70     // FIXME: Putting this code in the ctor and saving the byte order in a
     71     // member variable is a hack to avoid const qual issues in GetByteOrder.
     72     ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
     73     m_byte_order = obj_file->GetByteOrder();
     74 #else
     75     // XXX: Will work only for local processes.
     76     m_byte_order = lldb::endian::InlHostByteOrder();
     77 #endif
     78 }
     79 
     80 void
     81 ProcessLinux::Terminate()
     82 {
     83 }
     84 
     85 lldb_private::ConstString
     86 ProcessLinux::GetPluginNameStatic()
     87 {
     88     static ConstString g_name("linux");
     89     return g_name;
     90 }
     91 
     92 const char *
     93 ProcessLinux::GetPluginDescriptionStatic()
     94 {
     95     return "Process plugin for Linux";
     96 }
     97 
     98 
     99 bool
    100 ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
    101 {
    102     new_thread_list = old_thread_list;
    103     return new_thread_list.GetSize(false) > 0;
    104 }
    105 
    106 
    107 //------------------------------------------------------------------------------
    108 // ProcessInterface protocol.
    109 
    110 lldb_private::ConstString
    111 ProcessLinux::GetPluginName()
    112 {
    113     return GetPluginNameStatic();
    114 }
    115 
    116 uint32_t
    117 ProcessLinux::GetPluginVersion()
    118 {
    119     return 1;
    120 }
    121 
    122 void
    123 ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
    124 {
    125 }
    126 
    127 Error
    128 ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
    129 {
    130     return Error(1, eErrorTypeGeneric);
    131 }
    132 
    133 Log *
    134 ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
    135 {
    136     return NULL;
    137 }
    138 
    139 // ProcessPOSIX override
    140 void
    141 ProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
    142 {
    143     // If a breakpoint occurs while we're stopping threads, we'll get back
    144     // here, but we don't want to do it again.  Only the MonitorChildProcess
    145     // thread calls this function, so we don't need to protect this flag.
    146     if (m_stopping_threads)
    147       return;
    148     m_stopping_threads = true;
    149 
    150     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
    151     if (log)
    152         log->Printf ("ProcessLinux::%s() stopping all threads", __FUNCTION__);
    153 
    154     // Walk the thread list and stop the other threads.  The thread that caused
    155     // the stop should already be marked as stopped before we get here.
    156     Mutex::Locker thread_list_lock(m_thread_list.GetMutex());
    157 
    158     uint32_t thread_count = m_thread_list.GetSize(false);
    159     for (uint32_t i = 0; i < thread_count; ++i)
    160     {
    161         POSIXThread *thread = static_cast<POSIXThread*>(
    162             m_thread_list.GetThreadAtIndex(i, false).get());
    163         assert(thread);
    164         lldb::tid_t tid = thread->GetID();
    165         if (!StateIsStoppedState(thread->GetState(), false))
    166             m_monitor->StopThread(tid);
    167     }
    168 
    169     m_stopping_threads = false;
    170 
    171     if (log)
    172         log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
    173 }
    174 
    175 // ProcessPOSIX override
    176 POSIXThread *
    177 ProcessLinux::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
    178 {
    179     return new LinuxThread(process, tid);
    180 }
    181 
    182 bool
    183 ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
    184 {
    185     if (plugin_specified_by_name)
    186         return true;
    187 
    188     /* If core file is specified then let elf-core plugin handle it */
    189     if (m_core_file)
    190         return false;
    191 
    192     return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
    193 }
    194 
    195