• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CreateInstance(Target & target,Listener & listener,const FileSpec * core_file)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
Initialize()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 
ProcessLinux(Target & target,Listener & listener,FileSpec * core_file)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
Terminate()81 ProcessLinux::Terminate()
82 {
83 }
84 
85 lldb_private::ConstString
GetPluginNameStatic()86 ProcessLinux::GetPluginNameStatic()
87 {
88     static ConstString g_name("linux");
89     return g_name;
90 }
91 
92 const char *
GetPluginDescriptionStatic()93 ProcessLinux::GetPluginDescriptionStatic()
94 {
95     return "Process plugin for Linux";
96 }
97 
98 
99 bool
UpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)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
GetPluginName()111 ProcessLinux::GetPluginName()
112 {
113     return GetPluginNameStatic();
114 }
115 
116 uint32_t
GetPluginVersion()117 ProcessLinux::GetPluginVersion()
118 {
119     return 1;
120 }
121 
122 void
GetPluginCommandHelp(const char * command,Stream * strm)123 ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
124 {
125 }
126 
127 Error
ExecutePluginCommand(Args & command,Stream * strm)128 ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
129 {
130     return Error(1, eErrorTypeGeneric);
131 }
132 
133 Log *
EnablePluginLogging(Stream * strm,Args & command)134 ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
135 {
136     return NULL;
137 }
138 
139 // ProcessPOSIX override
140 void
StopAllThreads(lldb::tid_t stop_tid)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 *
CreateNewPOSIXThread(lldb_private::Process & process,lldb::tid_t tid)177 ProcessLinux::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
178 {
179     return new LinuxThread(process, tid);
180 }
181 
182 bool
CanDebug(Target & target,bool plugin_specified_by_name)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