1*af245d11STodd Fiala //===-- NativeProcessLinux.cpp -------------------------------- -*- C++ -*-===//
2*af245d11STodd Fiala //
3*af245d11STodd Fiala //                     The LLVM Compiler Infrastructure
4*af245d11STodd Fiala //
5*af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source
6*af245d11STodd Fiala // License. See LICENSE.TXT for details.
7*af245d11STodd Fiala //
8*af245d11STodd Fiala //===----------------------------------------------------------------------===//
9*af245d11STodd Fiala 
10*af245d11STodd Fiala #include "lldb/lldb-python.h"
11*af245d11STodd Fiala 
12*af245d11STodd Fiala #include "NativeProcessLinux.h"
13*af245d11STodd Fiala 
14*af245d11STodd Fiala // C Includes
15*af245d11STodd Fiala #include <errno.h>
16*af245d11STodd Fiala #include <poll.h>
17*af245d11STodd Fiala #include <string.h>
18*af245d11STodd Fiala #include <stdint.h>
19*af245d11STodd Fiala #include <unistd.h>
20*af245d11STodd Fiala #include <linux/unistd.h>
21*af245d11STodd Fiala #include <sys/ptrace.h>
22*af245d11STodd Fiala #include <sys/socket.h>
23*af245d11STodd Fiala #include <sys/syscall.h>
24*af245d11STodd Fiala #include <sys/types.h>
25*af245d11STodd Fiala #include <sys/user.h>
26*af245d11STodd Fiala #include <sys/wait.h>
27*af245d11STodd Fiala 
28*af245d11STodd Fiala // C++ Includes
29*af245d11STodd Fiala #include <fstream>
30*af245d11STodd Fiala #include <string>
31*af245d11STodd Fiala 
32*af245d11STodd Fiala // Other libraries and framework includes
33*af245d11STodd Fiala #include "lldb/Core/Debugger.h"
34*af245d11STodd Fiala #include "lldb/Core/Error.h"
35*af245d11STodd Fiala #include "lldb/Core/Module.h"
36*af245d11STodd Fiala #include "lldb/Core/RegisterValue.h"
37*af245d11STodd Fiala #include "lldb/Core/Scalar.h"
38*af245d11STodd Fiala #include "lldb/Core/State.h"
39*af245d11STodd Fiala #include "lldb/Host/Host.h"
40*af245d11STodd Fiala #include "lldb/Symbol/ObjectFile.h"
41*af245d11STodd Fiala #include "lldb/Target/NativeRegisterContext.h"
42*af245d11STodd Fiala #include "lldb/Target/ProcessLaunchInfo.h"
43*af245d11STodd Fiala #include "lldb/Utility/PseudoTerminal.h"
44*af245d11STodd Fiala 
45*af245d11STodd Fiala #include "Host/common/NativeBreakpoint.h"
46*af245d11STodd Fiala #include "Utility/StringExtractor.h"
47*af245d11STodd Fiala 
48*af245d11STodd Fiala #include "Plugins/Process/Utility/LinuxSignals.h"
49*af245d11STodd Fiala #include "NativeThreadLinux.h"
50*af245d11STodd Fiala #include "ProcFileReader.h"
51*af245d11STodd Fiala #include "ProcessPOSIXLog.h"
52*af245d11STodd Fiala 
53*af245d11STodd Fiala #define DEBUG_PTRACE_MAXBYTES 20
54*af245d11STodd Fiala 
55*af245d11STodd Fiala // Support ptrace extensions even when compiled without required kernel support
56*af245d11STodd Fiala #ifndef PTRACE_GETREGS
57*af245d11STodd Fiala #define PTRACE_GETREGS 12
58*af245d11STodd Fiala #endif
59*af245d11STodd Fiala #ifndef PTRACE_SETREGS
60*af245d11STodd Fiala   #define PTRACE_SETREGS 13
61*af245d11STodd Fiala #endif
62*af245d11STodd Fiala #ifndef PTRACE_GETREGSET
63*af245d11STodd Fiala   #define PTRACE_GETREGSET 0x4204
64*af245d11STodd Fiala #endif
65*af245d11STodd Fiala #ifndef PTRACE_SETREGSET
66*af245d11STodd Fiala   #define PTRACE_SETREGSET 0x4205
67*af245d11STodd Fiala #endif
68*af245d11STodd Fiala #ifndef PTRACE_GET_THREAD_AREA
69*af245d11STodd Fiala   #define PTRACE_GET_THREAD_AREA 25
70*af245d11STodd Fiala #endif
71*af245d11STodd Fiala #ifndef PTRACE_ARCH_PRCTL
72*af245d11STodd Fiala   #define PTRACE_ARCH_PRCTL      30
73*af245d11STodd Fiala #endif
74*af245d11STodd Fiala #ifndef ARCH_GET_FS
75*af245d11STodd Fiala   #define ARCH_SET_GS 0x1001
76*af245d11STodd Fiala   #define ARCH_SET_FS 0x1002
77*af245d11STodd Fiala   #define ARCH_GET_FS 0x1003
78*af245d11STodd Fiala   #define ARCH_GET_GS 0x1004
79*af245d11STodd Fiala #endif
80*af245d11STodd Fiala 
81*af245d11STodd Fiala 
82*af245d11STodd Fiala // Support hardware breakpoints in case it has not been defined
83*af245d11STodd Fiala #ifndef TRAP_HWBKPT
84*af245d11STodd Fiala   #define TRAP_HWBKPT 4
85*af245d11STodd Fiala #endif
86*af245d11STodd Fiala 
87*af245d11STodd Fiala // Try to define a macro to encapsulate the tgkill syscall
88*af245d11STodd Fiala // fall back on kill() if tgkill isn't available
89*af245d11STodd Fiala #define tgkill(pid, tid, sig)  syscall(SYS_tgkill, pid, tid, sig)
90*af245d11STodd Fiala 
91*af245d11STodd Fiala // We disable the tracing of ptrace calls for integration builds to
92*af245d11STodd Fiala // avoid the additional indirection and checks.
93*af245d11STodd Fiala #ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
94*af245d11STodd Fiala #define PTRACE(req, pid, addr, data, data_size) \
95*af245d11STodd Fiala     PtraceWrapper((req), (pid), (addr), (data), (data_size), #req, __FILE__, __LINE__)
96*af245d11STodd Fiala #else
97*af245d11STodd Fiala #define PTRACE(req, pid, addr, data, data_size) \
98*af245d11STodd Fiala     PtraceWrapper((req), (pid), (addr), (data), (data_size))
99*af245d11STodd Fiala #endif
100*af245d11STodd Fiala 
101*af245d11STodd Fiala // Private bits we only need internally.
102*af245d11STodd Fiala namespace
103*af245d11STodd Fiala {
104*af245d11STodd Fiala     using namespace lldb;
105*af245d11STodd Fiala     using namespace lldb_private;
106*af245d11STodd Fiala 
107*af245d11STodd Fiala     const UnixSignals&
108*af245d11STodd Fiala     GetUnixSignals ()
109*af245d11STodd Fiala     {
110*af245d11STodd Fiala         static process_linux::LinuxSignals signals;
111*af245d11STodd Fiala         return signals;
112*af245d11STodd Fiala     }
113*af245d11STodd Fiala 
114*af245d11STodd Fiala     const char *
115*af245d11STodd Fiala     GetFilePath (const lldb_private::ProcessLaunchInfo::FileAction *file_action, const char *default_path)
116*af245d11STodd Fiala     {
117*af245d11STodd Fiala         const char *pts_name = "/dev/pts/";
118*af245d11STodd Fiala         const char *path = NULL;
119*af245d11STodd Fiala 
120*af245d11STodd Fiala         if (file_action)
121*af245d11STodd Fiala         {
122*af245d11STodd Fiala             if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
123*af245d11STodd Fiala             {
124*af245d11STodd Fiala                 path = file_action->GetPath ();
125*af245d11STodd Fiala                 // By default the stdio paths passed in will be pseudo-terminal
126*af245d11STodd Fiala                 // (/dev/pts). If so, convert to using a different default path
127*af245d11STodd Fiala                 // instead to redirect I/O to the debugger console. This should
128*af245d11STodd Fiala                 //  also handle user overrides to /dev/null or a different file.
129*af245d11STodd Fiala                 if (!path || ::strncmp (path, pts_name, ::strlen (pts_name)) == 0)
130*af245d11STodd Fiala                     path = default_path;
131*af245d11STodd Fiala             }
132*af245d11STodd Fiala         }
133*af245d11STodd Fiala 
134*af245d11STodd Fiala         return path;
135*af245d11STodd Fiala     }
136*af245d11STodd Fiala 
137*af245d11STodd Fiala     Error
138*af245d11STodd Fiala     ResolveProcessArchitecture (lldb::pid_t pid, Platform &platform, ArchSpec &arch)
139*af245d11STodd Fiala     {
140*af245d11STodd Fiala         // Grab process info for the running process.
141*af245d11STodd Fiala         ProcessInstanceInfo process_info;
142*af245d11STodd Fiala         if (!platform.GetProcessInfo (pid, process_info))
143*af245d11STodd Fiala             return lldb_private::Error("failed to get process info");
144*af245d11STodd Fiala 
145*af245d11STodd Fiala         // Resolve the executable module.
146*af245d11STodd Fiala         ModuleSP exe_module_sp;
147*af245d11STodd Fiala         FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths ());
148*af245d11STodd Fiala         Error error = platform.ResolveExecutable(
149*af245d11STodd Fiala             process_info.GetExecutableFile (),
150*af245d11STodd Fiala             platform.GetSystemArchitecture (),
151*af245d11STodd Fiala             exe_module_sp,
152*af245d11STodd Fiala             executable_search_paths.GetSize () ? &executable_search_paths : NULL);
153*af245d11STodd Fiala 
154*af245d11STodd Fiala         if (!error.Success ())
155*af245d11STodd Fiala             return error;
156*af245d11STodd Fiala 
157*af245d11STodd Fiala         // Check if we've got our architecture from the exe_module.
158*af245d11STodd Fiala         arch = exe_module_sp->GetArchitecture ();
159*af245d11STodd Fiala         if (arch.IsValid ())
160*af245d11STodd Fiala             return Error();
161*af245d11STodd Fiala         else
162*af245d11STodd Fiala             return Error("failed to retrieve a valid architecture from the exe module");
163*af245d11STodd Fiala     }
164*af245d11STodd Fiala 
165*af245d11STodd Fiala     void
166*af245d11STodd Fiala     DisplayBytes (lldb_private::StreamString &s, void *bytes, uint32_t count)
167*af245d11STodd Fiala     {
168*af245d11STodd Fiala         uint8_t *ptr = (uint8_t *)bytes;
169*af245d11STodd Fiala         const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
170*af245d11STodd Fiala         for(uint32_t i=0; i<loop_count; i++)
171*af245d11STodd Fiala         {
172*af245d11STodd Fiala             s.Printf ("[%x]", *ptr);
173*af245d11STodd Fiala             ptr++;
174*af245d11STodd Fiala         }
175*af245d11STodd Fiala     }
176*af245d11STodd Fiala 
177*af245d11STodd Fiala     void
178*af245d11STodd Fiala     PtraceDisplayBytes(int &req, void *data, size_t data_size)
179*af245d11STodd Fiala     {
180*af245d11STodd Fiala         StreamString buf;
181*af245d11STodd Fiala         Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
182*af245d11STodd Fiala                     POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
183*af245d11STodd Fiala 
184*af245d11STodd Fiala         if (verbose_log)
185*af245d11STodd Fiala         {
186*af245d11STodd Fiala             switch(req)
187*af245d11STodd Fiala             {
188*af245d11STodd Fiala             case PTRACE_POKETEXT:
189*af245d11STodd Fiala             {
190*af245d11STodd Fiala                 DisplayBytes(buf, &data, 8);
191*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
192*af245d11STodd Fiala                 break;
193*af245d11STodd Fiala             }
194*af245d11STodd Fiala             case PTRACE_POKEDATA:
195*af245d11STodd Fiala             {
196*af245d11STodd Fiala                 DisplayBytes(buf, &data, 8);
197*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
198*af245d11STodd Fiala                 break;
199*af245d11STodd Fiala             }
200*af245d11STodd Fiala             case PTRACE_POKEUSER:
201*af245d11STodd Fiala             {
202*af245d11STodd Fiala                 DisplayBytes(buf, &data, 8);
203*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
204*af245d11STodd Fiala                 break;
205*af245d11STodd Fiala             }
206*af245d11STodd Fiala             case PTRACE_SETREGS:
207*af245d11STodd Fiala             {
208*af245d11STodd Fiala                 DisplayBytes(buf, data, data_size);
209*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
210*af245d11STodd Fiala                 break;
211*af245d11STodd Fiala             }
212*af245d11STodd Fiala             case PTRACE_SETFPREGS:
213*af245d11STodd Fiala             {
214*af245d11STodd Fiala                 DisplayBytes(buf, data, data_size);
215*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
216*af245d11STodd Fiala                 break;
217*af245d11STodd Fiala             }
218*af245d11STodd Fiala             case PTRACE_SETSIGINFO:
219*af245d11STodd Fiala             {
220*af245d11STodd Fiala                 DisplayBytes(buf, data, sizeof(siginfo_t));
221*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
222*af245d11STodd Fiala                 break;
223*af245d11STodd Fiala             }
224*af245d11STodd Fiala             case PTRACE_SETREGSET:
225*af245d11STodd Fiala             {
226*af245d11STodd Fiala                 // Extract iov_base from data, which is a pointer to the struct IOVEC
227*af245d11STodd Fiala                 DisplayBytes(buf, *(void **)data, data_size);
228*af245d11STodd Fiala                 verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
229*af245d11STodd Fiala                 break;
230*af245d11STodd Fiala             }
231*af245d11STodd Fiala             default:
232*af245d11STodd Fiala             {
233*af245d11STodd Fiala             }
234*af245d11STodd Fiala             }
235*af245d11STodd Fiala         }
236*af245d11STodd Fiala     }
237*af245d11STodd Fiala 
238*af245d11STodd Fiala     // Wrapper for ptrace to catch errors and log calls.
239*af245d11STodd Fiala     // Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
240*af245d11STodd Fiala     long
241*af245d11STodd Fiala     PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size,
242*af245d11STodd Fiala             const char* reqName, const char* file, int line)
243*af245d11STodd Fiala     {
244*af245d11STodd Fiala         long int result;
245*af245d11STodd Fiala 
246*af245d11STodd Fiala         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
247*af245d11STodd Fiala 
248*af245d11STodd Fiala         PtraceDisplayBytes(req, data, data_size);
249*af245d11STodd Fiala 
250*af245d11STodd Fiala         errno = 0;
251*af245d11STodd Fiala         if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
252*af245d11STodd Fiala             result = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid), *(unsigned int *)addr, data);
253*af245d11STodd Fiala         else
254*af245d11STodd Fiala             result = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid), addr, data);
255*af245d11STodd Fiala 
256*af245d11STodd Fiala         if (log)
257*af245d11STodd Fiala             log->Printf("ptrace(%s, %" PRIu64 ", %p, %p, %zu)=%lX called from file %s line %d",
258*af245d11STodd Fiala                     reqName, pid, addr, data, data_size, result, file, line);
259*af245d11STodd Fiala 
260*af245d11STodd Fiala         PtraceDisplayBytes(req, data, data_size);
261*af245d11STodd Fiala 
262*af245d11STodd Fiala         if (log && errno != 0)
263*af245d11STodd Fiala         {
264*af245d11STodd Fiala             const char* str;
265*af245d11STodd Fiala             switch (errno)
266*af245d11STodd Fiala             {
267*af245d11STodd Fiala             case ESRCH:  str = "ESRCH"; break;
268*af245d11STodd Fiala             case EINVAL: str = "EINVAL"; break;
269*af245d11STodd Fiala             case EBUSY:  str = "EBUSY"; break;
270*af245d11STodd Fiala             case EPERM:  str = "EPERM"; break;
271*af245d11STodd Fiala             default:     str = "<unknown>";
272*af245d11STodd Fiala             }
273*af245d11STodd Fiala             log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
274*af245d11STodd Fiala         }
275*af245d11STodd Fiala 
276*af245d11STodd Fiala         return result;
277*af245d11STodd Fiala     }
278*af245d11STodd Fiala 
279*af245d11STodd Fiala #ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION
280*af245d11STodd Fiala     // Wrapper for ptrace when logging is not required.
281*af245d11STodd Fiala     // Sets errno to 0 prior to calling ptrace.
282*af245d11STodd Fiala     long
283*af245d11STodd Fiala     PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size)
284*af245d11STodd Fiala     {
285*af245d11STodd Fiala         long result = 0;
286*af245d11STodd Fiala         errno = 0;
287*af245d11STodd Fiala         if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
288*af245d11STodd Fiala             result = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid), *(unsigned int *)addr, data);
289*af245d11STodd Fiala         else
290*af245d11STodd Fiala             result = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid), addr, data);
291*af245d11STodd Fiala         return result;
292*af245d11STodd Fiala     }
293*af245d11STodd Fiala #endif
294*af245d11STodd Fiala 
295*af245d11STodd Fiala     //------------------------------------------------------------------------------
296*af245d11STodd Fiala     // Static implementations of NativeProcessLinux::ReadMemory and
297*af245d11STodd Fiala     // NativeProcessLinux::WriteMemory.  This enables mutual recursion between these
298*af245d11STodd Fiala     // functions without needed to go thru the thread funnel.
299*af245d11STodd Fiala 
300*af245d11STodd Fiala     static lldb::addr_t
301*af245d11STodd Fiala     DoReadMemory (
302*af245d11STodd Fiala         lldb::pid_t pid,
303*af245d11STodd Fiala         lldb::addr_t vm_addr,
304*af245d11STodd Fiala         void *buf,
305*af245d11STodd Fiala         lldb::addr_t size,
306*af245d11STodd Fiala         Error &error)
307*af245d11STodd Fiala     {
308*af245d11STodd Fiala         // ptrace word size is determined by the host, not the child
309*af245d11STodd Fiala         static const unsigned word_size = sizeof(void*);
310*af245d11STodd Fiala         unsigned char *dst = static_cast<unsigned char*>(buf);
311*af245d11STodd Fiala         lldb::addr_t bytes_read;
312*af245d11STodd Fiala         lldb::addr_t remainder;
313*af245d11STodd Fiala         long data;
314*af245d11STodd Fiala 
315*af245d11STodd Fiala         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
316*af245d11STodd Fiala         if (log)
317*af245d11STodd Fiala             ProcessPOSIXLog::IncNestLevel();
318*af245d11STodd Fiala         if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
319*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s(%" PRIu64 ", %d, %p, %p, %zd, _)", __FUNCTION__,
320*af245d11STodd Fiala                     pid, word_size, (void*)vm_addr, buf, size);
321*af245d11STodd Fiala 
322*af245d11STodd Fiala         assert(sizeof(data) >= word_size);
323*af245d11STodd Fiala         for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
324*af245d11STodd Fiala         {
325*af245d11STodd Fiala             errno = 0;
326*af245d11STodd Fiala             data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL, 0);
327*af245d11STodd Fiala             if (errno)
328*af245d11STodd Fiala             {
329*af245d11STodd Fiala                 error.SetErrorToErrno();
330*af245d11STodd Fiala                 if (log)
331*af245d11STodd Fiala                     ProcessPOSIXLog::DecNestLevel();
332*af245d11STodd Fiala                 return bytes_read;
333*af245d11STodd Fiala             }
334*af245d11STodd Fiala 
335*af245d11STodd Fiala             remainder = size - bytes_read;
336*af245d11STodd Fiala             remainder = remainder > word_size ? word_size : remainder;
337*af245d11STodd Fiala 
338*af245d11STodd Fiala             // Copy the data into our buffer
339*af245d11STodd Fiala             for (unsigned i = 0; i < remainder; ++i)
340*af245d11STodd Fiala                 dst[i] = ((data >> i*8) & 0xFF);
341*af245d11STodd Fiala 
342*af245d11STodd Fiala             if (log && ProcessPOSIXLog::AtTopNestLevel() &&
343*af245d11STodd Fiala                     (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
344*af245d11STodd Fiala                             (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
345*af245d11STodd Fiala                                     size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
346*af245d11STodd Fiala             {
347*af245d11STodd Fiala                 uintptr_t print_dst = 0;
348*af245d11STodd Fiala                 // Format bytes from data by moving into print_dst for log output
349*af245d11STodd Fiala                 for (unsigned i = 0; i < remainder; ++i)
350*af245d11STodd Fiala                     print_dst |= (((data >> i*8) & 0xFF) << i*8);
351*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
352*af245d11STodd Fiala                         (void*)vm_addr, print_dst, (unsigned long)data);
353*af245d11STodd Fiala             }
354*af245d11STodd Fiala 
355*af245d11STodd Fiala             vm_addr += word_size;
356*af245d11STodd Fiala             dst += word_size;
357*af245d11STodd Fiala         }
358*af245d11STodd Fiala 
359*af245d11STodd Fiala         if (log)
360*af245d11STodd Fiala             ProcessPOSIXLog::DecNestLevel();
361*af245d11STodd Fiala         return bytes_read;
362*af245d11STodd Fiala     }
363*af245d11STodd Fiala 
364*af245d11STodd Fiala     static lldb::addr_t
365*af245d11STodd Fiala     DoWriteMemory(
366*af245d11STodd Fiala         lldb::pid_t pid,
367*af245d11STodd Fiala         lldb::addr_t vm_addr,
368*af245d11STodd Fiala         const void *buf,
369*af245d11STodd Fiala         lldb::addr_t size,
370*af245d11STodd Fiala         Error &error)
371*af245d11STodd Fiala     {
372*af245d11STodd Fiala         // ptrace word size is determined by the host, not the child
373*af245d11STodd Fiala         static const unsigned word_size = sizeof(void*);
374*af245d11STodd Fiala         const unsigned char *src = static_cast<const unsigned char*>(buf);
375*af245d11STodd Fiala         lldb::addr_t bytes_written = 0;
376*af245d11STodd Fiala         lldb::addr_t remainder;
377*af245d11STodd Fiala 
378*af245d11STodd Fiala         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
379*af245d11STodd Fiala         if (log)
380*af245d11STodd Fiala             ProcessPOSIXLog::IncNestLevel();
381*af245d11STodd Fiala         if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
382*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s(%" PRIu64 ", %u, %p, %p, %" PRIu64 ")", __FUNCTION__,
383*af245d11STodd Fiala                     pid, word_size, (void*)vm_addr, buf, size);
384*af245d11STodd Fiala 
385*af245d11STodd Fiala         for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
386*af245d11STodd Fiala         {
387*af245d11STodd Fiala             remainder = size - bytes_written;
388*af245d11STodd Fiala             remainder = remainder > word_size ? word_size : remainder;
389*af245d11STodd Fiala 
390*af245d11STodd Fiala             if (remainder == word_size)
391*af245d11STodd Fiala             {
392*af245d11STodd Fiala                 unsigned long data = 0;
393*af245d11STodd Fiala                 assert(sizeof(data) >= word_size);
394*af245d11STodd Fiala                 for (unsigned i = 0; i < word_size; ++i)
395*af245d11STodd Fiala                     data |= (unsigned long)src[i] << i*8;
396*af245d11STodd Fiala 
397*af245d11STodd Fiala                 if (log && ProcessPOSIXLog::AtTopNestLevel() &&
398*af245d11STodd Fiala                         (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
399*af245d11STodd Fiala                                 (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
400*af245d11STodd Fiala                                         size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
401*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
402*af245d11STodd Fiala                             (void*)vm_addr, *(unsigned long*)src, data);
403*af245d11STodd Fiala 
404*af245d11STodd Fiala                 if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0))
405*af245d11STodd Fiala                 {
406*af245d11STodd Fiala                     error.SetErrorToErrno();
407*af245d11STodd Fiala                     if (log)
408*af245d11STodd Fiala                         ProcessPOSIXLog::DecNestLevel();
409*af245d11STodd Fiala                     return bytes_written;
410*af245d11STodd Fiala                 }
411*af245d11STodd Fiala             }
412*af245d11STodd Fiala             else
413*af245d11STodd Fiala             {
414*af245d11STodd Fiala                 unsigned char buff[8];
415*af245d11STodd Fiala                 if (DoReadMemory(pid, vm_addr,
416*af245d11STodd Fiala                                 buff, word_size, error) != word_size)
417*af245d11STodd Fiala                 {
418*af245d11STodd Fiala                     if (log)
419*af245d11STodd Fiala                         ProcessPOSIXLog::DecNestLevel();
420*af245d11STodd Fiala                     return bytes_written;
421*af245d11STodd Fiala                 }
422*af245d11STodd Fiala 
423*af245d11STodd Fiala                 memcpy(buff, src, remainder);
424*af245d11STodd Fiala 
425*af245d11STodd Fiala                 if (DoWriteMemory(pid, vm_addr,
426*af245d11STodd Fiala                                 buff, word_size, error) != word_size)
427*af245d11STodd Fiala                 {
428*af245d11STodd Fiala                     if (log)
429*af245d11STodd Fiala                         ProcessPOSIXLog::DecNestLevel();
430*af245d11STodd Fiala                     return bytes_written;
431*af245d11STodd Fiala                 }
432*af245d11STodd Fiala 
433*af245d11STodd Fiala                 if (log && ProcessPOSIXLog::AtTopNestLevel() &&
434*af245d11STodd Fiala                         (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
435*af245d11STodd Fiala                                 (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
436*af245d11STodd Fiala                                         size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
437*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
438*af245d11STodd Fiala                             (void*)vm_addr, *(unsigned long*)src, *(unsigned long*)buff);
439*af245d11STodd Fiala             }
440*af245d11STodd Fiala 
441*af245d11STodd Fiala             vm_addr += word_size;
442*af245d11STodd Fiala             src += word_size;
443*af245d11STodd Fiala         }
444*af245d11STodd Fiala         if (log)
445*af245d11STodd Fiala             ProcessPOSIXLog::DecNestLevel();
446*af245d11STodd Fiala         return bytes_written;
447*af245d11STodd Fiala     }
448*af245d11STodd Fiala 
449*af245d11STodd Fiala     //------------------------------------------------------------------------------
450*af245d11STodd Fiala     /// @class Operation
451*af245d11STodd Fiala     /// @brief Represents a NativeProcessLinux operation.
452*af245d11STodd Fiala     ///
453*af245d11STodd Fiala     /// Under Linux, it is not possible to ptrace() from any other thread but the
454*af245d11STodd Fiala     /// one that spawned or attached to the process from the start.  Therefore, when
455*af245d11STodd Fiala     /// a NativeProcessLinux is asked to deliver or change the state of an inferior
456*af245d11STodd Fiala     /// process the operation must be "funneled" to a specific thread to perform the
457*af245d11STodd Fiala     /// task.  The Operation class provides an abstract base for all services the
458*af245d11STodd Fiala     /// NativeProcessLinux must perform via the single virtual function Execute, thus
459*af245d11STodd Fiala     /// encapsulating the code that needs to run in the privileged context.
460*af245d11STodd Fiala     class Operation
461*af245d11STodd Fiala     {
462*af245d11STodd Fiala     public:
463*af245d11STodd Fiala         Operation () : m_error() { }
464*af245d11STodd Fiala 
465*af245d11STodd Fiala         virtual
466*af245d11STodd Fiala         ~Operation() {}
467*af245d11STodd Fiala 
468*af245d11STodd Fiala         virtual void
469*af245d11STodd Fiala         Execute (NativeProcessLinux *process) = 0;
470*af245d11STodd Fiala 
471*af245d11STodd Fiala         const Error &
472*af245d11STodd Fiala         GetError () const { return m_error; }
473*af245d11STodd Fiala 
474*af245d11STodd Fiala     protected:
475*af245d11STodd Fiala         Error m_error;
476*af245d11STodd Fiala     };
477*af245d11STodd Fiala 
478*af245d11STodd Fiala     //------------------------------------------------------------------------------
479*af245d11STodd Fiala     /// @class ReadOperation
480*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::ReadMemory.
481*af245d11STodd Fiala     class ReadOperation : public Operation
482*af245d11STodd Fiala     {
483*af245d11STodd Fiala     public:
484*af245d11STodd Fiala         ReadOperation (
485*af245d11STodd Fiala             lldb::addr_t addr,
486*af245d11STodd Fiala             void *buff,
487*af245d11STodd Fiala             lldb::addr_t size,
488*af245d11STodd Fiala             size_t &result) :
489*af245d11STodd Fiala             Operation (),
490*af245d11STodd Fiala             m_addr (addr),
491*af245d11STodd Fiala             m_buff (buff),
492*af245d11STodd Fiala             m_size (size),
493*af245d11STodd Fiala             m_result (result)
494*af245d11STodd Fiala             {
495*af245d11STodd Fiala             }
496*af245d11STodd Fiala 
497*af245d11STodd Fiala         void Execute (NativeProcessLinux *process) override;
498*af245d11STodd Fiala 
499*af245d11STodd Fiala     private:
500*af245d11STodd Fiala         lldb::addr_t m_addr;
501*af245d11STodd Fiala         void *m_buff;
502*af245d11STodd Fiala         lldb::addr_t m_size;
503*af245d11STodd Fiala         lldb::addr_t &m_result;
504*af245d11STodd Fiala     };
505*af245d11STodd Fiala 
506*af245d11STodd Fiala     void
507*af245d11STodd Fiala     ReadOperation::Execute (NativeProcessLinux *process)
508*af245d11STodd Fiala     {
509*af245d11STodd Fiala         m_result = DoReadMemory (process->GetID (), m_addr, m_buff, m_size, m_error);
510*af245d11STodd Fiala     }
511*af245d11STodd Fiala 
512*af245d11STodd Fiala     //------------------------------------------------------------------------------
513*af245d11STodd Fiala     /// @class WriteOperation
514*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::WriteMemory.
515*af245d11STodd Fiala     class WriteOperation : public Operation
516*af245d11STodd Fiala     {
517*af245d11STodd Fiala     public:
518*af245d11STodd Fiala         WriteOperation (
519*af245d11STodd Fiala             lldb::addr_t addr,
520*af245d11STodd Fiala             const void *buff,
521*af245d11STodd Fiala             lldb::addr_t size,
522*af245d11STodd Fiala             lldb::addr_t &result) :
523*af245d11STodd Fiala             Operation (),
524*af245d11STodd Fiala             m_addr (addr),
525*af245d11STodd Fiala             m_buff (buff),
526*af245d11STodd Fiala             m_size (size),
527*af245d11STodd Fiala             m_result (result)
528*af245d11STodd Fiala             {
529*af245d11STodd Fiala             }
530*af245d11STodd Fiala 
531*af245d11STodd Fiala         void Execute (NativeProcessLinux *process) override;
532*af245d11STodd Fiala 
533*af245d11STodd Fiala     private:
534*af245d11STodd Fiala         lldb::addr_t m_addr;
535*af245d11STodd Fiala         const void *m_buff;
536*af245d11STodd Fiala         lldb::addr_t m_size;
537*af245d11STodd Fiala         lldb::addr_t &m_result;
538*af245d11STodd Fiala     };
539*af245d11STodd Fiala 
540*af245d11STodd Fiala     void
541*af245d11STodd Fiala     WriteOperation::Execute(NativeProcessLinux *process)
542*af245d11STodd Fiala     {
543*af245d11STodd Fiala         m_result = DoWriteMemory (process->GetID (), m_addr, m_buff, m_size, m_error);
544*af245d11STodd Fiala     }
545*af245d11STodd Fiala 
546*af245d11STodd Fiala     //------------------------------------------------------------------------------
547*af245d11STodd Fiala     /// @class ReadRegOperation
548*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::ReadRegisterValue.
549*af245d11STodd Fiala     class ReadRegOperation : public Operation
550*af245d11STodd Fiala     {
551*af245d11STodd Fiala     public:
552*af245d11STodd Fiala         ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name,
553*af245d11STodd Fiala                 RegisterValue &value, bool &result)
554*af245d11STodd Fiala             : m_tid(tid), m_offset(static_cast<uintptr_t> (offset)), m_reg_name(reg_name),
555*af245d11STodd Fiala               m_value(value), m_result(result)
556*af245d11STodd Fiala             { }
557*af245d11STodd Fiala 
558*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
559*af245d11STodd Fiala 
560*af245d11STodd Fiala     private:
561*af245d11STodd Fiala         lldb::tid_t m_tid;
562*af245d11STodd Fiala         uintptr_t m_offset;
563*af245d11STodd Fiala         const char *m_reg_name;
564*af245d11STodd Fiala         RegisterValue &m_value;
565*af245d11STodd Fiala         bool &m_result;
566*af245d11STodd Fiala     };
567*af245d11STodd Fiala 
568*af245d11STodd Fiala     void
569*af245d11STodd Fiala     ReadRegOperation::Execute(NativeProcessLinux *monitor)
570*af245d11STodd Fiala     {
571*af245d11STodd Fiala         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
572*af245d11STodd Fiala 
573*af245d11STodd Fiala         // Set errno to zero so that we can detect a failed peek.
574*af245d11STodd Fiala         errno = 0;
575*af245d11STodd Fiala         lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL, 0);
576*af245d11STodd Fiala         if (errno)
577*af245d11STodd Fiala             m_result = false;
578*af245d11STodd Fiala         else
579*af245d11STodd Fiala         {
580*af245d11STodd Fiala             m_value = data;
581*af245d11STodd Fiala             m_result = true;
582*af245d11STodd Fiala         }
583*af245d11STodd Fiala         if (log)
584*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__,
585*af245d11STodd Fiala                     m_reg_name, data);
586*af245d11STodd Fiala     }
587*af245d11STodd Fiala 
588*af245d11STodd Fiala     //------------------------------------------------------------------------------
589*af245d11STodd Fiala     /// @class WriteRegOperation
590*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::WriteRegisterValue.
591*af245d11STodd Fiala     class WriteRegOperation : public Operation
592*af245d11STodd Fiala     {
593*af245d11STodd Fiala     public:
594*af245d11STodd Fiala         WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name,
595*af245d11STodd Fiala                 const RegisterValue &value, bool &result)
596*af245d11STodd Fiala             : m_tid(tid), m_offset(offset), m_reg_name(reg_name),
597*af245d11STodd Fiala               m_value(value), m_result(result)
598*af245d11STodd Fiala             { }
599*af245d11STodd Fiala 
600*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
601*af245d11STodd Fiala 
602*af245d11STodd Fiala     private:
603*af245d11STodd Fiala         lldb::tid_t m_tid;
604*af245d11STodd Fiala         uintptr_t m_offset;
605*af245d11STodd Fiala         const char *m_reg_name;
606*af245d11STodd Fiala         const RegisterValue &m_value;
607*af245d11STodd Fiala         bool &m_result;
608*af245d11STodd Fiala     };
609*af245d11STodd Fiala 
610*af245d11STodd Fiala     void
611*af245d11STodd Fiala     WriteRegOperation::Execute(NativeProcessLinux *monitor)
612*af245d11STodd Fiala     {
613*af245d11STodd Fiala         void* buf;
614*af245d11STodd Fiala         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
615*af245d11STodd Fiala 
616*af245d11STodd Fiala         buf = (void*) m_value.GetAsUInt64();
617*af245d11STodd Fiala 
618*af245d11STodd Fiala         if (log)
619*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf);
620*af245d11STodd Fiala         if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0))
621*af245d11STodd Fiala             m_result = false;
622*af245d11STodd Fiala         else
623*af245d11STodd Fiala             m_result = true;
624*af245d11STodd Fiala     }
625*af245d11STodd Fiala 
626*af245d11STodd Fiala     //------------------------------------------------------------------------------
627*af245d11STodd Fiala     /// @class ReadGPROperation
628*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::ReadGPR.
629*af245d11STodd Fiala     class ReadGPROperation : public Operation
630*af245d11STodd Fiala     {
631*af245d11STodd Fiala     public:
632*af245d11STodd Fiala         ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
633*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
634*af245d11STodd Fiala             { }
635*af245d11STodd Fiala 
636*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
637*af245d11STodd Fiala 
638*af245d11STodd Fiala     private:
639*af245d11STodd Fiala         lldb::tid_t m_tid;
640*af245d11STodd Fiala         void *m_buf;
641*af245d11STodd Fiala         size_t m_buf_size;
642*af245d11STodd Fiala         bool &m_result;
643*af245d11STodd Fiala     };
644*af245d11STodd Fiala 
645*af245d11STodd Fiala     void
646*af245d11STodd Fiala     ReadGPROperation::Execute(NativeProcessLinux *monitor)
647*af245d11STodd Fiala     {
648*af245d11STodd Fiala         if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
649*af245d11STodd Fiala             m_result = false;
650*af245d11STodd Fiala         else
651*af245d11STodd Fiala             m_result = true;
652*af245d11STodd Fiala     }
653*af245d11STodd Fiala 
654*af245d11STodd Fiala     //------------------------------------------------------------------------------
655*af245d11STodd Fiala     /// @class ReadFPROperation
656*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::ReadFPR.
657*af245d11STodd Fiala     class ReadFPROperation : public Operation
658*af245d11STodd Fiala     {
659*af245d11STodd Fiala     public:
660*af245d11STodd Fiala         ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
661*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
662*af245d11STodd Fiala             { }
663*af245d11STodd Fiala 
664*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
665*af245d11STodd Fiala 
666*af245d11STodd Fiala     private:
667*af245d11STodd Fiala         lldb::tid_t m_tid;
668*af245d11STodd Fiala         void *m_buf;
669*af245d11STodd Fiala         size_t m_buf_size;
670*af245d11STodd Fiala         bool &m_result;
671*af245d11STodd Fiala     };
672*af245d11STodd Fiala 
673*af245d11STodd Fiala     void
674*af245d11STodd Fiala     ReadFPROperation::Execute(NativeProcessLinux *monitor)
675*af245d11STodd Fiala     {
676*af245d11STodd Fiala         if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
677*af245d11STodd Fiala             m_result = false;
678*af245d11STodd Fiala         else
679*af245d11STodd Fiala             m_result = true;
680*af245d11STodd Fiala     }
681*af245d11STodd Fiala 
682*af245d11STodd Fiala     //------------------------------------------------------------------------------
683*af245d11STodd Fiala     /// @class ReadRegisterSetOperation
684*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::ReadRegisterSet.
685*af245d11STodd Fiala     class ReadRegisterSetOperation : public Operation
686*af245d11STodd Fiala     {
687*af245d11STodd Fiala     public:
688*af245d11STodd Fiala         ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
689*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
690*af245d11STodd Fiala             { }
691*af245d11STodd Fiala 
692*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
693*af245d11STodd Fiala 
694*af245d11STodd Fiala     private:
695*af245d11STodd Fiala         lldb::tid_t m_tid;
696*af245d11STodd Fiala         void *m_buf;
697*af245d11STodd Fiala         size_t m_buf_size;
698*af245d11STodd Fiala         const unsigned int m_regset;
699*af245d11STodd Fiala         bool &m_result;
700*af245d11STodd Fiala     };
701*af245d11STodd Fiala 
702*af245d11STodd Fiala     void
703*af245d11STodd Fiala     ReadRegisterSetOperation::Execute(NativeProcessLinux *monitor)
704*af245d11STodd Fiala     {
705*af245d11STodd Fiala         if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
706*af245d11STodd Fiala             m_result = false;
707*af245d11STodd Fiala         else
708*af245d11STodd Fiala             m_result = true;
709*af245d11STodd Fiala     }
710*af245d11STodd Fiala 
711*af245d11STodd Fiala     //------------------------------------------------------------------------------
712*af245d11STodd Fiala     /// @class WriteGPROperation
713*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::WriteGPR.
714*af245d11STodd Fiala     class WriteGPROperation : public Operation
715*af245d11STodd Fiala     {
716*af245d11STodd Fiala     public:
717*af245d11STodd Fiala         WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
718*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
719*af245d11STodd Fiala             { }
720*af245d11STodd Fiala 
721*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
722*af245d11STodd Fiala 
723*af245d11STodd Fiala     private:
724*af245d11STodd Fiala         lldb::tid_t m_tid;
725*af245d11STodd Fiala         void *m_buf;
726*af245d11STodd Fiala         size_t m_buf_size;
727*af245d11STodd Fiala         bool &m_result;
728*af245d11STodd Fiala     };
729*af245d11STodd Fiala 
730*af245d11STodd Fiala     void
731*af245d11STodd Fiala     WriteGPROperation::Execute(NativeProcessLinux *monitor)
732*af245d11STodd Fiala     {
733*af245d11STodd Fiala         if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
734*af245d11STodd Fiala             m_result = false;
735*af245d11STodd Fiala         else
736*af245d11STodd Fiala             m_result = true;
737*af245d11STodd Fiala     }
738*af245d11STodd Fiala 
739*af245d11STodd Fiala     //------------------------------------------------------------------------------
740*af245d11STodd Fiala     /// @class WriteFPROperation
741*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::WriteFPR.
742*af245d11STodd Fiala     class WriteFPROperation : public Operation
743*af245d11STodd Fiala     {
744*af245d11STodd Fiala     public:
745*af245d11STodd Fiala         WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
746*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
747*af245d11STodd Fiala             { }
748*af245d11STodd Fiala 
749*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
750*af245d11STodd Fiala 
751*af245d11STodd Fiala     private:
752*af245d11STodd Fiala         lldb::tid_t m_tid;
753*af245d11STodd Fiala         void *m_buf;
754*af245d11STodd Fiala         size_t m_buf_size;
755*af245d11STodd Fiala         bool &m_result;
756*af245d11STodd Fiala     };
757*af245d11STodd Fiala 
758*af245d11STodd Fiala     void
759*af245d11STodd Fiala     WriteFPROperation::Execute(NativeProcessLinux *monitor)
760*af245d11STodd Fiala     {
761*af245d11STodd Fiala         if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
762*af245d11STodd Fiala             m_result = false;
763*af245d11STodd Fiala         else
764*af245d11STodd Fiala             m_result = true;
765*af245d11STodd Fiala     }
766*af245d11STodd Fiala 
767*af245d11STodd Fiala     //------------------------------------------------------------------------------
768*af245d11STodd Fiala     /// @class WriteRegisterSetOperation
769*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::WriteRegisterSet.
770*af245d11STodd Fiala     class WriteRegisterSetOperation : public Operation
771*af245d11STodd Fiala     {
772*af245d11STodd Fiala     public:
773*af245d11STodd Fiala         WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
774*af245d11STodd Fiala             : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
775*af245d11STodd Fiala             { }
776*af245d11STodd Fiala 
777*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
778*af245d11STodd Fiala 
779*af245d11STodd Fiala     private:
780*af245d11STodd Fiala         lldb::tid_t m_tid;
781*af245d11STodd Fiala         void *m_buf;
782*af245d11STodd Fiala         size_t m_buf_size;
783*af245d11STodd Fiala         const unsigned int m_regset;
784*af245d11STodd Fiala         bool &m_result;
785*af245d11STodd Fiala     };
786*af245d11STodd Fiala 
787*af245d11STodd Fiala     void
788*af245d11STodd Fiala     WriteRegisterSetOperation::Execute(NativeProcessLinux *monitor)
789*af245d11STodd Fiala     {
790*af245d11STodd Fiala         if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
791*af245d11STodd Fiala             m_result = false;
792*af245d11STodd Fiala         else
793*af245d11STodd Fiala             m_result = true;
794*af245d11STodd Fiala     }
795*af245d11STodd Fiala 
796*af245d11STodd Fiala     //------------------------------------------------------------------------------
797*af245d11STodd Fiala     /// @class ResumeOperation
798*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::Resume.
799*af245d11STodd Fiala     class ResumeOperation : public Operation
800*af245d11STodd Fiala     {
801*af245d11STodd Fiala     public:
802*af245d11STodd Fiala         ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) :
803*af245d11STodd Fiala             m_tid(tid), m_signo(signo), m_result(result) { }
804*af245d11STodd Fiala 
805*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
806*af245d11STodd Fiala 
807*af245d11STodd Fiala     private:
808*af245d11STodd Fiala         lldb::tid_t m_tid;
809*af245d11STodd Fiala         uint32_t m_signo;
810*af245d11STodd Fiala         bool &m_result;
811*af245d11STodd Fiala     };
812*af245d11STodd Fiala 
813*af245d11STodd Fiala     void
814*af245d11STodd Fiala     ResumeOperation::Execute(NativeProcessLinux *monitor)
815*af245d11STodd Fiala     {
816*af245d11STodd Fiala         intptr_t data = 0;
817*af245d11STodd Fiala 
818*af245d11STodd Fiala         if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
819*af245d11STodd Fiala             data = m_signo;
820*af245d11STodd Fiala 
821*af245d11STodd Fiala         if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data, 0))
822*af245d11STodd Fiala         {
823*af245d11STodd Fiala             Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
824*af245d11STodd Fiala 
825*af245d11STodd Fiala             if (log)
826*af245d11STodd Fiala                 log->Printf ("ResumeOperation (%"  PRIu64 ") failed: %s", m_tid, strerror(errno));
827*af245d11STodd Fiala             m_result = false;
828*af245d11STodd Fiala         }
829*af245d11STodd Fiala         else
830*af245d11STodd Fiala             m_result = true;
831*af245d11STodd Fiala     }
832*af245d11STodd Fiala 
833*af245d11STodd Fiala     //------------------------------------------------------------------------------
834*af245d11STodd Fiala     /// @class SingleStepOperation
835*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::SingleStep.
836*af245d11STodd Fiala     class SingleStepOperation : public Operation
837*af245d11STodd Fiala     {
838*af245d11STodd Fiala     public:
839*af245d11STodd Fiala         SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result)
840*af245d11STodd Fiala             : m_tid(tid), m_signo(signo), m_result(result) { }
841*af245d11STodd Fiala 
842*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
843*af245d11STodd Fiala 
844*af245d11STodd Fiala     private:
845*af245d11STodd Fiala         lldb::tid_t m_tid;
846*af245d11STodd Fiala         uint32_t m_signo;
847*af245d11STodd Fiala         bool &m_result;
848*af245d11STodd Fiala     };
849*af245d11STodd Fiala 
850*af245d11STodd Fiala     void
851*af245d11STodd Fiala     SingleStepOperation::Execute(NativeProcessLinux *monitor)
852*af245d11STodd Fiala     {
853*af245d11STodd Fiala         intptr_t data = 0;
854*af245d11STodd Fiala 
855*af245d11STodd Fiala         if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
856*af245d11STodd Fiala             data = m_signo;
857*af245d11STodd Fiala 
858*af245d11STodd Fiala         if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data, 0))
859*af245d11STodd Fiala             m_result = false;
860*af245d11STodd Fiala         else
861*af245d11STodd Fiala             m_result = true;
862*af245d11STodd Fiala     }
863*af245d11STodd Fiala 
864*af245d11STodd Fiala     //------------------------------------------------------------------------------
865*af245d11STodd Fiala     /// @class SiginfoOperation
866*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::GetSignalInfo.
867*af245d11STodd Fiala     class SiginfoOperation : public Operation
868*af245d11STodd Fiala     {
869*af245d11STodd Fiala     public:
870*af245d11STodd Fiala         SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
871*af245d11STodd Fiala             : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
872*af245d11STodd Fiala 
873*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
874*af245d11STodd Fiala 
875*af245d11STodd Fiala     private:
876*af245d11STodd Fiala         lldb::tid_t m_tid;
877*af245d11STodd Fiala         void *m_info;
878*af245d11STodd Fiala         bool &m_result;
879*af245d11STodd Fiala         int &m_err;
880*af245d11STodd Fiala     };
881*af245d11STodd Fiala 
882*af245d11STodd Fiala     void
883*af245d11STodd Fiala     SiginfoOperation::Execute(NativeProcessLinux *monitor)
884*af245d11STodd Fiala     {
885*af245d11STodd Fiala         if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info, 0)) {
886*af245d11STodd Fiala             m_result = false;
887*af245d11STodd Fiala             m_err = errno;
888*af245d11STodd Fiala         }
889*af245d11STodd Fiala         else
890*af245d11STodd Fiala             m_result = true;
891*af245d11STodd Fiala     }
892*af245d11STodd Fiala 
893*af245d11STodd Fiala     //------------------------------------------------------------------------------
894*af245d11STodd Fiala     /// @class EventMessageOperation
895*af245d11STodd Fiala     /// @brief Implements NativeProcessLinux::GetEventMessage.
896*af245d11STodd Fiala     class EventMessageOperation : public Operation
897*af245d11STodd Fiala     {
898*af245d11STodd Fiala     public:
899*af245d11STodd Fiala         EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
900*af245d11STodd Fiala             : m_tid(tid), m_message(message), m_result(result) { }
901*af245d11STodd Fiala 
902*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
903*af245d11STodd Fiala 
904*af245d11STodd Fiala     private:
905*af245d11STodd Fiala         lldb::tid_t m_tid;
906*af245d11STodd Fiala         unsigned long *m_message;
907*af245d11STodd Fiala         bool &m_result;
908*af245d11STodd Fiala     };
909*af245d11STodd Fiala 
910*af245d11STodd Fiala     void
911*af245d11STodd Fiala     EventMessageOperation::Execute(NativeProcessLinux *monitor)
912*af245d11STodd Fiala     {
913*af245d11STodd Fiala         if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message, 0))
914*af245d11STodd Fiala             m_result = false;
915*af245d11STodd Fiala         else
916*af245d11STodd Fiala             m_result = true;
917*af245d11STodd Fiala     }
918*af245d11STodd Fiala 
919*af245d11STodd Fiala     class DetachOperation : public Operation
920*af245d11STodd Fiala     {
921*af245d11STodd Fiala     public:
922*af245d11STodd Fiala         DetachOperation(lldb::tid_t tid, Error &result) : m_tid(tid), m_error(result) { }
923*af245d11STodd Fiala 
924*af245d11STodd Fiala         void Execute(NativeProcessLinux *monitor);
925*af245d11STodd Fiala 
926*af245d11STodd Fiala     private:
927*af245d11STodd Fiala         lldb::tid_t m_tid;
928*af245d11STodd Fiala         Error &m_error;
929*af245d11STodd Fiala     };
930*af245d11STodd Fiala 
931*af245d11STodd Fiala     void
932*af245d11STodd Fiala     DetachOperation::Execute(NativeProcessLinux *monitor)
933*af245d11STodd Fiala     {
934*af245d11STodd Fiala         if (ptrace(PT_DETACH, m_tid, NULL, 0) < 0)
935*af245d11STodd Fiala             m_error.SetErrorToErrno();
936*af245d11STodd Fiala     }
937*af245d11STodd Fiala 
938*af245d11STodd Fiala }
939*af245d11STodd Fiala 
940*af245d11STodd Fiala using namespace lldb_private;
941*af245d11STodd Fiala 
942*af245d11STodd Fiala // Simple helper function to ensure flags are enabled on the given file
943*af245d11STodd Fiala // descriptor.
944*af245d11STodd Fiala static bool
945*af245d11STodd Fiala EnsureFDFlags(int fd, int flags, Error &error)
946*af245d11STodd Fiala {
947*af245d11STodd Fiala     int status;
948*af245d11STodd Fiala 
949*af245d11STodd Fiala     if ((status = fcntl(fd, F_GETFL)) == -1)
950*af245d11STodd Fiala     {
951*af245d11STodd Fiala         error.SetErrorToErrno();
952*af245d11STodd Fiala         return false;
953*af245d11STodd Fiala     }
954*af245d11STodd Fiala 
955*af245d11STodd Fiala     if (fcntl(fd, F_SETFL, status | flags) == -1)
956*af245d11STodd Fiala     {
957*af245d11STodd Fiala         error.SetErrorToErrno();
958*af245d11STodd Fiala         return false;
959*af245d11STodd Fiala     }
960*af245d11STodd Fiala 
961*af245d11STodd Fiala     return true;
962*af245d11STodd Fiala }
963*af245d11STodd Fiala 
964*af245d11STodd Fiala NativeProcessLinux::OperationArgs::OperationArgs(NativeProcessLinux *monitor)
965*af245d11STodd Fiala     : m_monitor(monitor)
966*af245d11STodd Fiala {
967*af245d11STodd Fiala     sem_init(&m_semaphore, 0, 0);
968*af245d11STodd Fiala }
969*af245d11STodd Fiala 
970*af245d11STodd Fiala NativeProcessLinux::OperationArgs::~OperationArgs()
971*af245d11STodd Fiala {
972*af245d11STodd Fiala     sem_destroy(&m_semaphore);
973*af245d11STodd Fiala }
974*af245d11STodd Fiala 
975*af245d11STodd Fiala NativeProcessLinux::LaunchArgs::LaunchArgs(NativeProcessLinux *monitor,
976*af245d11STodd Fiala                                        lldb_private::Module *module,
977*af245d11STodd Fiala                                        char const **argv,
978*af245d11STodd Fiala                                        char const **envp,
979*af245d11STodd Fiala                                        const char *stdin_path,
980*af245d11STodd Fiala                                        const char *stdout_path,
981*af245d11STodd Fiala                                        const char *stderr_path,
982*af245d11STodd Fiala                                        const char *working_dir)
983*af245d11STodd Fiala     : OperationArgs(monitor),
984*af245d11STodd Fiala       m_module(module),
985*af245d11STodd Fiala       m_argv(argv),
986*af245d11STodd Fiala       m_envp(envp),
987*af245d11STodd Fiala       m_stdin_path(stdin_path),
988*af245d11STodd Fiala       m_stdout_path(stdout_path),
989*af245d11STodd Fiala       m_stderr_path(stderr_path),
990*af245d11STodd Fiala       m_working_dir(working_dir) { }
991*af245d11STodd Fiala 
992*af245d11STodd Fiala NativeProcessLinux::LaunchArgs::~LaunchArgs()
993*af245d11STodd Fiala { }
994*af245d11STodd Fiala 
995*af245d11STodd Fiala NativeProcessLinux::AttachArgs::AttachArgs(NativeProcessLinux *monitor,
996*af245d11STodd Fiala                                        lldb::pid_t pid)
997*af245d11STodd Fiala     : OperationArgs(monitor), m_pid(pid) { }
998*af245d11STodd Fiala 
999*af245d11STodd Fiala NativeProcessLinux::AttachArgs::~AttachArgs()
1000*af245d11STodd Fiala { }
1001*af245d11STodd Fiala 
1002*af245d11STodd Fiala // -----------------------------------------------------------------------------
1003*af245d11STodd Fiala // Public Static Methods
1004*af245d11STodd Fiala // -----------------------------------------------------------------------------
1005*af245d11STodd Fiala 
1006*af245d11STodd Fiala lldb_private::Error
1007*af245d11STodd Fiala NativeProcessLinux::LaunchProcess (
1008*af245d11STodd Fiala     lldb_private::Module *exe_module,
1009*af245d11STodd Fiala     lldb_private::ProcessLaunchInfo &launch_info,
1010*af245d11STodd Fiala     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
1011*af245d11STodd Fiala     NativeProcessProtocolSP &native_process_sp)
1012*af245d11STodd Fiala {
1013*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1014*af245d11STodd Fiala 
1015*af245d11STodd Fiala     Error error;
1016*af245d11STodd Fiala 
1017*af245d11STodd Fiala     // Verify the working directory is valid if one was specified.
1018*af245d11STodd Fiala     const char* working_dir = launch_info.GetWorkingDirectory ();
1019*af245d11STodd Fiala     if (working_dir)
1020*af245d11STodd Fiala     {
1021*af245d11STodd Fiala       FileSpec working_dir_fs (working_dir, true);
1022*af245d11STodd Fiala       if (!working_dir_fs || working_dir_fs.GetFileType () != FileSpec::eFileTypeDirectory)
1023*af245d11STodd Fiala       {
1024*af245d11STodd Fiala           error.SetErrorStringWithFormat ("No such file or directory: %s", working_dir);
1025*af245d11STodd Fiala           return error;
1026*af245d11STodd Fiala       }
1027*af245d11STodd Fiala     }
1028*af245d11STodd Fiala 
1029*af245d11STodd Fiala     const lldb_private::ProcessLaunchInfo::FileAction *file_action;
1030*af245d11STodd Fiala 
1031*af245d11STodd Fiala     // Default of NULL will mean to use existing open file descriptors.
1032*af245d11STodd Fiala     const char *stdin_path = NULL;
1033*af245d11STodd Fiala     const char *stdout_path = NULL;
1034*af245d11STodd Fiala     const char *stderr_path = NULL;
1035*af245d11STodd Fiala 
1036*af245d11STodd Fiala     file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
1037*af245d11STodd Fiala     stdin_path = GetFilePath (file_action, stdin_path);
1038*af245d11STodd Fiala 
1039*af245d11STodd Fiala     file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
1040*af245d11STodd Fiala     stdout_path = GetFilePath (file_action, stdout_path);
1041*af245d11STodd Fiala 
1042*af245d11STodd Fiala     file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
1043*af245d11STodd Fiala     stderr_path = GetFilePath (file_action, stderr_path);
1044*af245d11STodd Fiala 
1045*af245d11STodd Fiala     // Create the NativeProcessLinux in launch mode.
1046*af245d11STodd Fiala     native_process_sp.reset (new NativeProcessLinux ());
1047*af245d11STodd Fiala 
1048*af245d11STodd Fiala     if (log)
1049*af245d11STodd Fiala     {
1050*af245d11STodd Fiala         int i = 0;
1051*af245d11STodd Fiala         for (const char **args = launch_info.GetArguments ().GetConstArgumentVector (); *args; ++args, ++i)
1052*af245d11STodd Fiala         {
1053*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr");
1054*af245d11STodd Fiala             ++i;
1055*af245d11STodd Fiala         }
1056*af245d11STodd Fiala     }
1057*af245d11STodd Fiala 
1058*af245d11STodd Fiala     if (!native_process_sp->RegisterNativeDelegate (native_delegate))
1059*af245d11STodd Fiala     {
1060*af245d11STodd Fiala         native_process_sp.reset ();
1061*af245d11STodd Fiala         error.SetErrorStringWithFormat ("failed to register the native delegate");
1062*af245d11STodd Fiala         return error;
1063*af245d11STodd Fiala     }
1064*af245d11STodd Fiala 
1065*af245d11STodd Fiala     reinterpret_cast<NativeProcessLinux*> (native_process_sp.get ())->LaunchInferior (
1066*af245d11STodd Fiala             exe_module,
1067*af245d11STodd Fiala             launch_info.GetArguments ().GetConstArgumentVector (),
1068*af245d11STodd Fiala             launch_info.GetEnvironmentEntries ().GetConstArgumentVector (),
1069*af245d11STodd Fiala             stdin_path,
1070*af245d11STodd Fiala             stdout_path,
1071*af245d11STodd Fiala             stderr_path,
1072*af245d11STodd Fiala             working_dir,
1073*af245d11STodd Fiala             error);
1074*af245d11STodd Fiala 
1075*af245d11STodd Fiala     if (error.Fail ())
1076*af245d11STodd Fiala     {
1077*af245d11STodd Fiala         native_process_sp.reset ();
1078*af245d11STodd Fiala         if (log)
1079*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s failed to launch process: %s", __FUNCTION__, error.AsCString ());
1080*af245d11STodd Fiala         return error;
1081*af245d11STodd Fiala     }
1082*af245d11STodd Fiala 
1083*af245d11STodd Fiala     launch_info.SetProcessID (native_process_sp->GetID ());
1084*af245d11STodd Fiala 
1085*af245d11STodd Fiala     return error;
1086*af245d11STodd Fiala }
1087*af245d11STodd Fiala 
1088*af245d11STodd Fiala lldb_private::Error
1089*af245d11STodd Fiala NativeProcessLinux::AttachToProcess (
1090*af245d11STodd Fiala     lldb::pid_t pid,
1091*af245d11STodd Fiala     lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
1092*af245d11STodd Fiala     NativeProcessProtocolSP &native_process_sp)
1093*af245d11STodd Fiala {
1094*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1095*af245d11STodd Fiala     if (log && log->GetMask ().Test (POSIX_LOG_VERBOSE))
1096*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
1097*af245d11STodd Fiala 
1098*af245d11STodd Fiala     // Grab the current platform architecture.  This should be Linux,
1099*af245d11STodd Fiala     // since this code is only intended to run on a Linux host.
1100*af245d11STodd Fiala     PlatformSP platform_sp (Platform::GetDefaultPlatform ());
1101*af245d11STodd Fiala     if (!platform_sp)
1102*af245d11STodd Fiala         return Error("failed to get a valid default platform");
1103*af245d11STodd Fiala 
1104*af245d11STodd Fiala     // Retrieve the architecture for the running process.
1105*af245d11STodd Fiala     ArchSpec process_arch;
1106*af245d11STodd Fiala     Error error = ResolveProcessArchitecture (pid, *platform_sp.get (), process_arch);
1107*af245d11STodd Fiala     if (!error.Success ())
1108*af245d11STodd Fiala         return error;
1109*af245d11STodd Fiala 
1110*af245d11STodd Fiala     native_process_sp.reset (new NativeProcessLinux ());
1111*af245d11STodd Fiala 
1112*af245d11STodd Fiala     if (!native_process_sp->RegisterNativeDelegate (native_delegate))
1113*af245d11STodd Fiala     {
1114*af245d11STodd Fiala         native_process_sp.reset (new NativeProcessLinux ());
1115*af245d11STodd Fiala         error.SetErrorStringWithFormat ("failed to register the native delegate");
1116*af245d11STodd Fiala         return error;
1117*af245d11STodd Fiala     }
1118*af245d11STodd Fiala 
1119*af245d11STodd Fiala     reinterpret_cast<NativeProcessLinux*> (native_process_sp.get ())->AttachToInferior (pid, error);
1120*af245d11STodd Fiala     if (!error.Success ())
1121*af245d11STodd Fiala     {
1122*af245d11STodd Fiala         native_process_sp.reset ();
1123*af245d11STodd Fiala         return error;
1124*af245d11STodd Fiala     }
1125*af245d11STodd Fiala 
1126*af245d11STodd Fiala     return error;
1127*af245d11STodd Fiala }
1128*af245d11STodd Fiala 
1129*af245d11STodd Fiala // -----------------------------------------------------------------------------
1130*af245d11STodd Fiala // Public Instance Methods
1131*af245d11STodd Fiala // -----------------------------------------------------------------------------
1132*af245d11STodd Fiala 
1133*af245d11STodd Fiala NativeProcessLinux::NativeProcessLinux () :
1134*af245d11STodd Fiala     NativeProcessProtocol (LLDB_INVALID_PROCESS_ID),
1135*af245d11STodd Fiala     m_arch (),
1136*af245d11STodd Fiala     m_operation_thread (LLDB_INVALID_HOST_THREAD),
1137*af245d11STodd Fiala     m_monitor_thread (LLDB_INVALID_HOST_THREAD),
1138*af245d11STodd Fiala     m_operation (nullptr),
1139*af245d11STodd Fiala     m_operation_mutex (),
1140*af245d11STodd Fiala     m_operation_pending (),
1141*af245d11STodd Fiala     m_operation_done (),
1142*af245d11STodd Fiala     m_wait_for_stop_tids (),
1143*af245d11STodd Fiala     m_wait_for_stop_tids_mutex (),
1144*af245d11STodd Fiala     m_supports_mem_region (eLazyBoolCalculate),
1145*af245d11STodd Fiala     m_mem_region_cache (),
1146*af245d11STodd Fiala     m_mem_region_cache_mutex ()
1147*af245d11STodd Fiala {
1148*af245d11STodd Fiala }
1149*af245d11STodd Fiala 
1150*af245d11STodd Fiala //------------------------------------------------------------------------------
1151*af245d11STodd Fiala /// The basic design of the NativeProcessLinux is built around two threads.
1152*af245d11STodd Fiala ///
1153*af245d11STodd Fiala /// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
1154*af245d11STodd Fiala /// for changes in the debugee state.  When a change is detected a
1155*af245d11STodd Fiala /// ProcessMessage is sent to the associated ProcessLinux instance.  This thread
1156*af245d11STodd Fiala /// "drives" state changes in the debugger.
1157*af245d11STodd Fiala ///
1158*af245d11STodd Fiala /// The second thread (@see OperationThread) is responsible for two things 1)
1159*af245d11STodd Fiala /// launching or attaching to the inferior process, and then 2) servicing
1160*af245d11STodd Fiala /// operations such as register reads/writes, stepping, etc.  See the comments
1161*af245d11STodd Fiala /// on the Operation class for more info as to why this is needed.
1162*af245d11STodd Fiala void
1163*af245d11STodd Fiala NativeProcessLinux::LaunchInferior (
1164*af245d11STodd Fiala     Module *module,
1165*af245d11STodd Fiala     const char *argv[],
1166*af245d11STodd Fiala     const char *envp[],
1167*af245d11STodd Fiala     const char *stdin_path,
1168*af245d11STodd Fiala     const char *stdout_path,
1169*af245d11STodd Fiala     const char *stderr_path,
1170*af245d11STodd Fiala     const char *working_dir,
1171*af245d11STodd Fiala     lldb_private::Error &error)
1172*af245d11STodd Fiala {
1173*af245d11STodd Fiala     if (module)
1174*af245d11STodd Fiala         m_arch = module->GetArchitecture ();
1175*af245d11STodd Fiala 
1176*af245d11STodd Fiala     SetState(eStateLaunching);
1177*af245d11STodd Fiala 
1178*af245d11STodd Fiala     std::unique_ptr<LaunchArgs> args(
1179*af245d11STodd Fiala         new LaunchArgs(
1180*af245d11STodd Fiala             this, module, argv, envp,
1181*af245d11STodd Fiala             stdin_path, stdout_path, stderr_path,
1182*af245d11STodd Fiala             working_dir));
1183*af245d11STodd Fiala 
1184*af245d11STodd Fiala     sem_init(&m_operation_pending, 0, 0);
1185*af245d11STodd Fiala     sem_init(&m_operation_done, 0, 0);
1186*af245d11STodd Fiala 
1187*af245d11STodd Fiala     StartLaunchOpThread(args.get(), error);
1188*af245d11STodd Fiala     if (!error.Success())
1189*af245d11STodd Fiala         return;
1190*af245d11STodd Fiala 
1191*af245d11STodd Fiala WAIT_AGAIN:
1192*af245d11STodd Fiala     // Wait for the operation thread to initialize.
1193*af245d11STodd Fiala     if (sem_wait(&args->m_semaphore))
1194*af245d11STodd Fiala     {
1195*af245d11STodd Fiala         if (errno == EINTR)
1196*af245d11STodd Fiala             goto WAIT_AGAIN;
1197*af245d11STodd Fiala         else
1198*af245d11STodd Fiala         {
1199*af245d11STodd Fiala             error.SetErrorToErrno();
1200*af245d11STodd Fiala             return;
1201*af245d11STodd Fiala         }
1202*af245d11STodd Fiala     }
1203*af245d11STodd Fiala 
1204*af245d11STodd Fiala     // Check that the launch was a success.
1205*af245d11STodd Fiala     if (!args->m_error.Success())
1206*af245d11STodd Fiala     {
1207*af245d11STodd Fiala         StopOpThread();
1208*af245d11STodd Fiala         error = args->m_error;
1209*af245d11STodd Fiala         return;
1210*af245d11STodd Fiala     }
1211*af245d11STodd Fiala 
1212*af245d11STodd Fiala     // Finally, start monitoring the child process for change in state.
1213*af245d11STodd Fiala     m_monitor_thread = Host::StartMonitoringChildProcess(
1214*af245d11STodd Fiala         NativeProcessLinux::MonitorCallback, this, GetID(), true);
1215*af245d11STodd Fiala     if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
1216*af245d11STodd Fiala     {
1217*af245d11STodd Fiala         error.SetErrorToGenericError();
1218*af245d11STodd Fiala         error.SetErrorString ("Process attach failed to create monitor thread for NativeProcessLinux::MonitorCallback.");
1219*af245d11STodd Fiala         return;
1220*af245d11STodd Fiala     }
1221*af245d11STodd Fiala }
1222*af245d11STodd Fiala 
1223*af245d11STodd Fiala void
1224*af245d11STodd Fiala NativeProcessLinux::AttachToInferior (lldb::pid_t pid, lldb_private::Error &error)
1225*af245d11STodd Fiala {
1226*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1227*af245d11STodd Fiala     if (log)
1228*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
1229*af245d11STodd Fiala 
1230*af245d11STodd Fiala     // We can use the Host for everything except the ResolveExecutable portion.
1231*af245d11STodd Fiala     PlatformSP platform_sp = Platform::GetDefaultPlatform ();
1232*af245d11STodd Fiala     if (!platform_sp)
1233*af245d11STodd Fiala     {
1234*af245d11STodd Fiala         if (log)
1235*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 "): no default platform set", __FUNCTION__, pid);
1236*af245d11STodd Fiala         error.SetErrorString ("no default platform available");
1237*af245d11STodd Fiala     }
1238*af245d11STodd Fiala 
1239*af245d11STodd Fiala     // Gather info about the process.
1240*af245d11STodd Fiala     ProcessInstanceInfo process_info;
1241*af245d11STodd Fiala     platform_sp->GetProcessInfo (pid, process_info);
1242*af245d11STodd Fiala 
1243*af245d11STodd Fiala     // Resolve the executable module
1244*af245d11STodd Fiala     ModuleSP exe_module_sp;
1245*af245d11STodd Fiala     FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
1246*af245d11STodd Fiala 
1247*af245d11STodd Fiala     error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
1248*af245d11STodd Fiala                                     Host::GetArchitecture(),
1249*af245d11STodd Fiala                                     exe_module_sp,
1250*af245d11STodd Fiala                                     executable_search_paths.GetSize() ? &executable_search_paths : NULL);
1251*af245d11STodd Fiala     if (!error.Success())
1252*af245d11STodd Fiala         return;
1253*af245d11STodd Fiala 
1254*af245d11STodd Fiala     // Set the architecture to the exe architecture.
1255*af245d11STodd Fiala     m_arch = exe_module_sp->GetArchitecture();
1256*af245d11STodd Fiala     if (log)
1257*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ());
1258*af245d11STodd Fiala 
1259*af245d11STodd Fiala     m_pid = pid;
1260*af245d11STodd Fiala     SetState(eStateAttaching);
1261*af245d11STodd Fiala 
1262*af245d11STodd Fiala     sem_init (&m_operation_pending, 0, 0);
1263*af245d11STodd Fiala     sem_init (&m_operation_done, 0, 0);
1264*af245d11STodd Fiala 
1265*af245d11STodd Fiala     std::unique_ptr<AttachArgs> args (new AttachArgs (this, pid));
1266*af245d11STodd Fiala 
1267*af245d11STodd Fiala     StartAttachOpThread(args.get (), error);
1268*af245d11STodd Fiala     if (!error.Success ())
1269*af245d11STodd Fiala         return;
1270*af245d11STodd Fiala 
1271*af245d11STodd Fiala WAIT_AGAIN:
1272*af245d11STodd Fiala     // Wait for the operation thread to initialize.
1273*af245d11STodd Fiala     if (sem_wait (&args->m_semaphore))
1274*af245d11STodd Fiala     {
1275*af245d11STodd Fiala         if (errno == EINTR)
1276*af245d11STodd Fiala             goto WAIT_AGAIN;
1277*af245d11STodd Fiala         else
1278*af245d11STodd Fiala         {
1279*af245d11STodd Fiala             error.SetErrorToErrno ();
1280*af245d11STodd Fiala             return;
1281*af245d11STodd Fiala         }
1282*af245d11STodd Fiala     }
1283*af245d11STodd Fiala 
1284*af245d11STodd Fiala     // Check that the attach was a success.
1285*af245d11STodd Fiala     if (!args->m_error.Success ())
1286*af245d11STodd Fiala     {
1287*af245d11STodd Fiala         StopOpThread ();
1288*af245d11STodd Fiala         error = args->m_error;
1289*af245d11STodd Fiala         return;
1290*af245d11STodd Fiala     }
1291*af245d11STodd Fiala 
1292*af245d11STodd Fiala     // Finally, start monitoring the child process for change in state.
1293*af245d11STodd Fiala     m_monitor_thread = Host::StartMonitoringChildProcess (
1294*af245d11STodd Fiala         NativeProcessLinux::MonitorCallback, this, GetID (), true);
1295*af245d11STodd Fiala     if (!IS_VALID_LLDB_HOST_THREAD (m_monitor_thread))
1296*af245d11STodd Fiala     {
1297*af245d11STodd Fiala         error.SetErrorToGenericError ();
1298*af245d11STodd Fiala         error.SetErrorString ("Process attach failed to create monitor thread for NativeProcessLinux::MonitorCallback.");
1299*af245d11STodd Fiala         return;
1300*af245d11STodd Fiala     }
1301*af245d11STodd Fiala }
1302*af245d11STodd Fiala 
1303*af245d11STodd Fiala NativeProcessLinux::~NativeProcessLinux()
1304*af245d11STodd Fiala {
1305*af245d11STodd Fiala     StopMonitor();
1306*af245d11STodd Fiala }
1307*af245d11STodd Fiala 
1308*af245d11STodd Fiala //------------------------------------------------------------------------------
1309*af245d11STodd Fiala // Thread setup and tear down.
1310*af245d11STodd Fiala 
1311*af245d11STodd Fiala void
1312*af245d11STodd Fiala NativeProcessLinux::StartLaunchOpThread(LaunchArgs *args, Error &error)
1313*af245d11STodd Fiala {
1314*af245d11STodd Fiala     static const char *g_thread_name = "lldb.process.nativelinux.operation";
1315*af245d11STodd Fiala 
1316*af245d11STodd Fiala     if (IS_VALID_LLDB_HOST_THREAD (m_operation_thread))
1317*af245d11STodd Fiala         return;
1318*af245d11STodd Fiala 
1319*af245d11STodd Fiala     m_operation_thread =
1320*af245d11STodd Fiala         Host::ThreadCreate (g_thread_name, LaunchOpThread, args, &error);
1321*af245d11STodd Fiala }
1322*af245d11STodd Fiala 
1323*af245d11STodd Fiala void *
1324*af245d11STodd Fiala NativeProcessLinux::LaunchOpThread(void *arg)
1325*af245d11STodd Fiala {
1326*af245d11STodd Fiala     LaunchArgs *args = static_cast<LaunchArgs*>(arg);
1327*af245d11STodd Fiala 
1328*af245d11STodd Fiala     if (!Launch(args)) {
1329*af245d11STodd Fiala         sem_post(&args->m_semaphore);
1330*af245d11STodd Fiala         return NULL;
1331*af245d11STodd Fiala     }
1332*af245d11STodd Fiala 
1333*af245d11STodd Fiala     ServeOperation(args);
1334*af245d11STodd Fiala     return NULL;
1335*af245d11STodd Fiala }
1336*af245d11STodd Fiala 
1337*af245d11STodd Fiala bool
1338*af245d11STodd Fiala NativeProcessLinux::Launch(LaunchArgs *args)
1339*af245d11STodd Fiala {
1340*af245d11STodd Fiala     NativeProcessLinux *monitor = args->m_monitor;
1341*af245d11STodd Fiala     assert (monitor && "monitor is NULL");
1342*af245d11STodd Fiala     if (!monitor)
1343*af245d11STodd Fiala         return false;
1344*af245d11STodd Fiala 
1345*af245d11STodd Fiala     const char **argv = args->m_argv;
1346*af245d11STodd Fiala     const char **envp = args->m_envp;
1347*af245d11STodd Fiala     const char *stdin_path = args->m_stdin_path;
1348*af245d11STodd Fiala     const char *stdout_path = args->m_stdout_path;
1349*af245d11STodd Fiala     const char *stderr_path = args->m_stderr_path;
1350*af245d11STodd Fiala     const char *working_dir = args->m_working_dir;
1351*af245d11STodd Fiala 
1352*af245d11STodd Fiala     lldb_utility::PseudoTerminal terminal;
1353*af245d11STodd Fiala     const size_t err_len = 1024;
1354*af245d11STodd Fiala     char err_str[err_len];
1355*af245d11STodd Fiala     lldb::pid_t pid;
1356*af245d11STodd Fiala     NativeThreadProtocolSP thread_sp;
1357*af245d11STodd Fiala 
1358*af245d11STodd Fiala     lldb::ThreadSP inferior;
1359*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1360*af245d11STodd Fiala 
1361*af245d11STodd Fiala     // Propagate the environment if one is not supplied.
1362*af245d11STodd Fiala     if (envp == NULL || envp[0] == NULL)
1363*af245d11STodd Fiala         envp = const_cast<const char **>(environ);
1364*af245d11STodd Fiala 
1365*af245d11STodd Fiala     if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t> (-1))
1366*af245d11STodd Fiala     {
1367*af245d11STodd Fiala         args->m_error.SetErrorToGenericError();
1368*af245d11STodd Fiala         args->m_error.SetErrorString("Process fork failed.");
1369*af245d11STodd Fiala         goto FINISH;
1370*af245d11STodd Fiala     }
1371*af245d11STodd Fiala 
1372*af245d11STodd Fiala     // Recognized child exit status codes.
1373*af245d11STodd Fiala     enum {
1374*af245d11STodd Fiala         ePtraceFailed = 1,
1375*af245d11STodd Fiala         eDupStdinFailed,
1376*af245d11STodd Fiala         eDupStdoutFailed,
1377*af245d11STodd Fiala         eDupStderrFailed,
1378*af245d11STodd Fiala         eChdirFailed,
1379*af245d11STodd Fiala         eExecFailed,
1380*af245d11STodd Fiala         eSetGidFailed
1381*af245d11STodd Fiala     };
1382*af245d11STodd Fiala 
1383*af245d11STodd Fiala     // Child process.
1384*af245d11STodd Fiala     if (pid == 0)
1385*af245d11STodd Fiala     {
1386*af245d11STodd Fiala         if (log)
1387*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior process preparing to fork", __FUNCTION__);
1388*af245d11STodd Fiala 
1389*af245d11STodd Fiala         // Trace this process.
1390*af245d11STodd Fiala         if (log)
1391*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior process issuing PTRACE_TRACEME", __FUNCTION__);
1392*af245d11STodd Fiala 
1393*af245d11STodd Fiala         if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL, 0) < 0)
1394*af245d11STodd Fiala         {
1395*af245d11STodd Fiala             if (log)
1396*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s inferior process PTRACE_TRACEME failed", __FUNCTION__);
1397*af245d11STodd Fiala             exit(ePtraceFailed);
1398*af245d11STodd Fiala         }
1399*af245d11STodd Fiala 
1400*af245d11STodd Fiala         // Do not inherit setgid powers.
1401*af245d11STodd Fiala         if (log)
1402*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior process resetting gid", __FUNCTION__);
1403*af245d11STodd Fiala 
1404*af245d11STodd Fiala         if (setgid(getgid()) != 0)
1405*af245d11STodd Fiala         {
1406*af245d11STodd Fiala             if (log)
1407*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s inferior process setgid() failed", __FUNCTION__);
1408*af245d11STodd Fiala             exit(eSetGidFailed);
1409*af245d11STodd Fiala         }
1410*af245d11STodd Fiala 
1411*af245d11STodd Fiala         // Attempt to have our own process group.
1412*af245d11STodd Fiala         // TODO verify if we really want this.
1413*af245d11STodd Fiala         if (log)
1414*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior process resetting process group", __FUNCTION__);
1415*af245d11STodd Fiala 
1416*af245d11STodd Fiala         if (setpgid(0, 0) != 0)
1417*af245d11STodd Fiala         {
1418*af245d11STodd Fiala             if (log)
1419*af245d11STodd Fiala             {
1420*af245d11STodd Fiala                 const int error_code = errno;
1421*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s inferior setpgid() failed, errno=%d (%s), continuing with existing proccess group %" PRIu64,
1422*af245d11STodd Fiala                         __FUNCTION__,
1423*af245d11STodd Fiala                         error_code,
1424*af245d11STodd Fiala                         strerror (error_code),
1425*af245d11STodd Fiala                         static_cast<lldb::pid_t> (getpgid (0)));
1426*af245d11STodd Fiala             }
1427*af245d11STodd Fiala             // Don't allow this to prevent an inferior exec.
1428*af245d11STodd Fiala         }
1429*af245d11STodd Fiala 
1430*af245d11STodd Fiala         // Dup file descriptors if needed.
1431*af245d11STodd Fiala         //
1432*af245d11STodd Fiala         // FIXME: If two or more of the paths are the same we needlessly open
1433*af245d11STodd Fiala         // the same file multiple times.
1434*af245d11STodd Fiala         if (stdin_path != NULL && stdin_path[0])
1435*af245d11STodd Fiala             if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY))
1436*af245d11STodd Fiala                 exit(eDupStdinFailed);
1437*af245d11STodd Fiala 
1438*af245d11STodd Fiala         if (stdout_path != NULL && stdout_path[0])
1439*af245d11STodd Fiala             if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT))
1440*af245d11STodd Fiala                 exit(eDupStdoutFailed);
1441*af245d11STodd Fiala 
1442*af245d11STodd Fiala         if (stderr_path != NULL && stderr_path[0])
1443*af245d11STodd Fiala             if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
1444*af245d11STodd Fiala                 exit(eDupStderrFailed);
1445*af245d11STodd Fiala 
1446*af245d11STodd Fiala         // Change working directory
1447*af245d11STodd Fiala         if (working_dir != NULL && working_dir[0])
1448*af245d11STodd Fiala           if (0 != ::chdir(working_dir))
1449*af245d11STodd Fiala               exit(eChdirFailed);
1450*af245d11STodd Fiala 
1451*af245d11STodd Fiala         // Execute.  We should never return.
1452*af245d11STodd Fiala         execve(argv[0],
1453*af245d11STodd Fiala                const_cast<char *const *>(argv),
1454*af245d11STodd Fiala                const_cast<char *const *>(envp));
1455*af245d11STodd Fiala         exit(eExecFailed);
1456*af245d11STodd Fiala     }
1457*af245d11STodd Fiala 
1458*af245d11STodd Fiala     // Wait for the child process to trap on its call to execve.
1459*af245d11STodd Fiala     ::pid_t wpid;
1460*af245d11STodd Fiala     int status;
1461*af245d11STodd Fiala     if ((wpid = waitpid(pid, &status, 0)) < 0)
1462*af245d11STodd Fiala     {
1463*af245d11STodd Fiala         args->m_error.SetErrorToErrno();
1464*af245d11STodd Fiala 
1465*af245d11STodd Fiala         if (log)
1466*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s waitpid for inferior failed with %s", __FUNCTION__, args->m_error.AsCString ());
1467*af245d11STodd Fiala 
1468*af245d11STodd Fiala         // Mark the inferior as invalid.
1469*af245d11STodd Fiala         // FIXME this could really use a new state - eStateLaunchFailure.  For now, using eStateInvalid.
1470*af245d11STodd Fiala         monitor->SetState (StateType::eStateInvalid);
1471*af245d11STodd Fiala 
1472*af245d11STodd Fiala         goto FINISH;
1473*af245d11STodd Fiala     }
1474*af245d11STodd Fiala     else if (WIFEXITED(status))
1475*af245d11STodd Fiala     {
1476*af245d11STodd Fiala         // open, dup or execve likely failed for some reason.
1477*af245d11STodd Fiala         args->m_error.SetErrorToGenericError();
1478*af245d11STodd Fiala         switch (WEXITSTATUS(status))
1479*af245d11STodd Fiala         {
1480*af245d11STodd Fiala             case ePtraceFailed:
1481*af245d11STodd Fiala                 args->m_error.SetErrorString("Child ptrace failed.");
1482*af245d11STodd Fiala                 break;
1483*af245d11STodd Fiala             case eDupStdinFailed:
1484*af245d11STodd Fiala                 args->m_error.SetErrorString("Child open stdin failed.");
1485*af245d11STodd Fiala                 break;
1486*af245d11STodd Fiala             case eDupStdoutFailed:
1487*af245d11STodd Fiala                 args->m_error.SetErrorString("Child open stdout failed.");
1488*af245d11STodd Fiala                 break;
1489*af245d11STodd Fiala             case eDupStderrFailed:
1490*af245d11STodd Fiala                 args->m_error.SetErrorString("Child open stderr failed.");
1491*af245d11STodd Fiala                 break;
1492*af245d11STodd Fiala             case eChdirFailed:
1493*af245d11STodd Fiala                 args->m_error.SetErrorString("Child failed to set working directory.");
1494*af245d11STodd Fiala                 break;
1495*af245d11STodd Fiala             case eExecFailed:
1496*af245d11STodd Fiala                 args->m_error.SetErrorString("Child exec failed.");
1497*af245d11STodd Fiala                 break;
1498*af245d11STodd Fiala             case eSetGidFailed:
1499*af245d11STodd Fiala                 args->m_error.SetErrorString("Child setgid failed.");
1500*af245d11STodd Fiala                 break;
1501*af245d11STodd Fiala             default:
1502*af245d11STodd Fiala                 args->m_error.SetErrorString("Child returned unknown exit status.");
1503*af245d11STodd Fiala                 break;
1504*af245d11STodd Fiala         }
1505*af245d11STodd Fiala 
1506*af245d11STodd Fiala         if (log)
1507*af245d11STodd Fiala         {
1508*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior exited with status %d before issuing a STOP",
1509*af245d11STodd Fiala                     __FUNCTION__,
1510*af245d11STodd Fiala                     WEXITSTATUS(status));
1511*af245d11STodd Fiala         }
1512*af245d11STodd Fiala 
1513*af245d11STodd Fiala         // Mark the inferior as invalid.
1514*af245d11STodd Fiala         // FIXME this could really use a new state - eStateLaunchFailure.  For now, using eStateInvalid.
1515*af245d11STodd Fiala         monitor->SetState (StateType::eStateInvalid);
1516*af245d11STodd Fiala 
1517*af245d11STodd Fiala         goto FINISH;
1518*af245d11STodd Fiala     }
1519*af245d11STodd Fiala     assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t> (pid)) &&
1520*af245d11STodd Fiala            "Could not sync with inferior process.");
1521*af245d11STodd Fiala 
1522*af245d11STodd Fiala     if (log)
1523*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s inferior started, now in stopped state", __FUNCTION__);
1524*af245d11STodd Fiala 
1525*af245d11STodd Fiala     if (!SetDefaultPtraceOpts(pid))
1526*af245d11STodd Fiala     {
1527*af245d11STodd Fiala         args->m_error.SetErrorToErrno();
1528*af245d11STodd Fiala         if (log)
1529*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior failed to set default ptrace options: %s",
1530*af245d11STodd Fiala                     __FUNCTION__,
1531*af245d11STodd Fiala                     args->m_error.AsCString ());
1532*af245d11STodd Fiala 
1533*af245d11STodd Fiala         // Mark the inferior as invalid.
1534*af245d11STodd Fiala         // FIXME this could really use a new state - eStateLaunchFailure.  For now, using eStateInvalid.
1535*af245d11STodd Fiala         monitor->SetState (StateType::eStateInvalid);
1536*af245d11STodd Fiala 
1537*af245d11STodd Fiala         goto FINISH;
1538*af245d11STodd Fiala     }
1539*af245d11STodd Fiala 
1540*af245d11STodd Fiala     // Release the master terminal descriptor and pass it off to the
1541*af245d11STodd Fiala     // NativeProcessLinux instance.  Similarly stash the inferior pid.
1542*af245d11STodd Fiala     monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
1543*af245d11STodd Fiala     monitor->m_pid = pid;
1544*af245d11STodd Fiala 
1545*af245d11STodd Fiala     // Set the terminal fd to be in non blocking mode (it simplifies the
1546*af245d11STodd Fiala     // implementation of ProcessLinux::GetSTDOUT to have a non-blocking
1547*af245d11STodd Fiala     // descriptor to read from).
1548*af245d11STodd Fiala     if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
1549*af245d11STodd Fiala     {
1550*af245d11STodd Fiala         if (log)
1551*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior EnsureFDFlags failed for ensuring terminal O_NONBLOCK setting: %s",
1552*af245d11STodd Fiala                     __FUNCTION__,
1553*af245d11STodd Fiala                     args->m_error.AsCString ());
1554*af245d11STodd Fiala 
1555*af245d11STodd Fiala         // Mark the inferior as invalid.
1556*af245d11STodd Fiala         // FIXME this could really use a new state - eStateLaunchFailure.  For now, using eStateInvalid.
1557*af245d11STodd Fiala         monitor->SetState (StateType::eStateInvalid);
1558*af245d11STodd Fiala 
1559*af245d11STodd Fiala         goto FINISH;
1560*af245d11STodd Fiala     }
1561*af245d11STodd Fiala 
1562*af245d11STodd Fiala     if (log)
1563*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
1564*af245d11STodd Fiala 
1565*af245d11STodd Fiala     thread_sp = monitor->AddThread (static_cast<lldb::tid_t> (pid));
1566*af245d11STodd Fiala     assert (thread_sp && "AddThread() returned a nullptr thread");
1567*af245d11STodd Fiala     reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (SIGSTOP);
1568*af245d11STodd Fiala     monitor->SetCurrentThreadID (thread_sp->GetID ());
1569*af245d11STodd Fiala 
1570*af245d11STodd Fiala     // Let our process instance know the thread has stopped.
1571*af245d11STodd Fiala     monitor->SetState (StateType::eStateStopped);
1572*af245d11STodd Fiala 
1573*af245d11STodd Fiala FINISH:
1574*af245d11STodd Fiala     if (log)
1575*af245d11STodd Fiala     {
1576*af245d11STodd Fiala         if (args->m_error.Success ())
1577*af245d11STodd Fiala         {
1578*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__);
1579*af245d11STodd Fiala         }
1580*af245d11STodd Fiala         else
1581*af245d11STodd Fiala         {
1582*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s inferior launching failed: %s",
1583*af245d11STodd Fiala                 __FUNCTION__,
1584*af245d11STodd Fiala                 args->m_error.AsCString ());
1585*af245d11STodd Fiala         }
1586*af245d11STodd Fiala     }
1587*af245d11STodd Fiala     return args->m_error.Success();
1588*af245d11STodd Fiala }
1589*af245d11STodd Fiala 
1590*af245d11STodd Fiala void
1591*af245d11STodd Fiala NativeProcessLinux::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
1592*af245d11STodd Fiala {
1593*af245d11STodd Fiala     static const char *g_thread_name = "lldb.process.linux.operation";
1594*af245d11STodd Fiala 
1595*af245d11STodd Fiala     if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
1596*af245d11STodd Fiala         return;
1597*af245d11STodd Fiala 
1598*af245d11STodd Fiala     m_operation_thread =
1599*af245d11STodd Fiala         Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error);
1600*af245d11STodd Fiala }
1601*af245d11STodd Fiala 
1602*af245d11STodd Fiala void *
1603*af245d11STodd Fiala NativeProcessLinux::AttachOpThread(void *arg)
1604*af245d11STodd Fiala {
1605*af245d11STodd Fiala     AttachArgs *args = static_cast<AttachArgs*>(arg);
1606*af245d11STodd Fiala 
1607*af245d11STodd Fiala     if (!Attach(args)) {
1608*af245d11STodd Fiala         sem_post(&args->m_semaphore);
1609*af245d11STodd Fiala         return NULL;
1610*af245d11STodd Fiala     }
1611*af245d11STodd Fiala 
1612*af245d11STodd Fiala     ServeOperation(args);
1613*af245d11STodd Fiala     return NULL;
1614*af245d11STodd Fiala }
1615*af245d11STodd Fiala 
1616*af245d11STodd Fiala bool
1617*af245d11STodd Fiala NativeProcessLinux::Attach(AttachArgs *args)
1618*af245d11STodd Fiala {
1619*af245d11STodd Fiala     lldb::pid_t pid = args->m_pid;
1620*af245d11STodd Fiala 
1621*af245d11STodd Fiala     NativeProcessLinux *monitor = args->m_monitor;
1622*af245d11STodd Fiala     lldb::ThreadSP inferior;
1623*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1624*af245d11STodd Fiala 
1625*af245d11STodd Fiala     // Use a map to keep track of the threads which we have attached/need to attach.
1626*af245d11STodd Fiala     Host::TidMap tids_to_attach;
1627*af245d11STodd Fiala     if (pid <= 1)
1628*af245d11STodd Fiala     {
1629*af245d11STodd Fiala         args->m_error.SetErrorToGenericError();
1630*af245d11STodd Fiala         args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
1631*af245d11STodd Fiala         goto FINISH;
1632*af245d11STodd Fiala     }
1633*af245d11STodd Fiala 
1634*af245d11STodd Fiala     while (Host::FindProcessThreads(pid, tids_to_attach))
1635*af245d11STodd Fiala     {
1636*af245d11STodd Fiala         for (Host::TidMap::iterator it = tids_to_attach.begin();
1637*af245d11STodd Fiala              it != tids_to_attach.end();)
1638*af245d11STodd Fiala         {
1639*af245d11STodd Fiala             if (it->second == false)
1640*af245d11STodd Fiala             {
1641*af245d11STodd Fiala                 lldb::tid_t tid = it->first;
1642*af245d11STodd Fiala 
1643*af245d11STodd Fiala                 // Attach to the requested process.
1644*af245d11STodd Fiala                 // An attach will cause the thread to stop with a SIGSTOP.
1645*af245d11STodd Fiala                 if (PTRACE(PTRACE_ATTACH, tid, NULL, NULL, 0) < 0)
1646*af245d11STodd Fiala                 {
1647*af245d11STodd Fiala                     // No such thread. The thread may have exited.
1648*af245d11STodd Fiala                     // More error handling may be needed.
1649*af245d11STodd Fiala                     if (errno == ESRCH)
1650*af245d11STodd Fiala                     {
1651*af245d11STodd Fiala                         it = tids_to_attach.erase(it);
1652*af245d11STodd Fiala                         continue;
1653*af245d11STodd Fiala                     }
1654*af245d11STodd Fiala                     else
1655*af245d11STodd Fiala                     {
1656*af245d11STodd Fiala                         args->m_error.SetErrorToErrno();
1657*af245d11STodd Fiala                         goto FINISH;
1658*af245d11STodd Fiala                     }
1659*af245d11STodd Fiala                 }
1660*af245d11STodd Fiala 
1661*af245d11STodd Fiala                 int status;
1662*af245d11STodd Fiala                 // Need to use __WALL otherwise we receive an error with errno=ECHLD
1663*af245d11STodd Fiala                 // At this point we should have a thread stopped if waitpid succeeds.
1664*af245d11STodd Fiala                 if ((status = waitpid(tid, NULL, __WALL)) < 0)
1665*af245d11STodd Fiala                 {
1666*af245d11STodd Fiala                     // No such thread. The thread may have exited.
1667*af245d11STodd Fiala                     // More error handling may be needed.
1668*af245d11STodd Fiala                     if (errno == ESRCH)
1669*af245d11STodd Fiala                     {
1670*af245d11STodd Fiala                         it = tids_to_attach.erase(it);
1671*af245d11STodd Fiala                         continue;
1672*af245d11STodd Fiala                     }
1673*af245d11STodd Fiala                     else
1674*af245d11STodd Fiala                     {
1675*af245d11STodd Fiala                         args->m_error.SetErrorToErrno();
1676*af245d11STodd Fiala                         goto FINISH;
1677*af245d11STodd Fiala                     }
1678*af245d11STodd Fiala                 }
1679*af245d11STodd Fiala 
1680*af245d11STodd Fiala                 if (!SetDefaultPtraceOpts(tid))
1681*af245d11STodd Fiala                 {
1682*af245d11STodd Fiala                     args->m_error.SetErrorToErrno();
1683*af245d11STodd Fiala                     goto FINISH;
1684*af245d11STodd Fiala                 }
1685*af245d11STodd Fiala 
1686*af245d11STodd Fiala 
1687*af245d11STodd Fiala                 if (log)
1688*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() adding tid = %" PRIu64, __FUNCTION__, tid);
1689*af245d11STodd Fiala 
1690*af245d11STodd Fiala                 it->second = true;
1691*af245d11STodd Fiala 
1692*af245d11STodd Fiala                 // Create the thread, mark it as stopped.
1693*af245d11STodd Fiala                 NativeThreadProtocolSP thread_sp (monitor->AddThread (static_cast<lldb::tid_t> (tid)));
1694*af245d11STodd Fiala                 assert (thread_sp && "AddThread() returned a nullptr");
1695*af245d11STodd Fiala                 reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (SIGSTOP);
1696*af245d11STodd Fiala                 monitor->SetCurrentThreadID (thread_sp->GetID ());
1697*af245d11STodd Fiala             }
1698*af245d11STodd Fiala 
1699*af245d11STodd Fiala             // move the loop forward
1700*af245d11STodd Fiala             ++it;
1701*af245d11STodd Fiala         }
1702*af245d11STodd Fiala     }
1703*af245d11STodd Fiala 
1704*af245d11STodd Fiala     if (tids_to_attach.size() > 0)
1705*af245d11STodd Fiala     {
1706*af245d11STodd Fiala         monitor->m_pid = pid;
1707*af245d11STodd Fiala         // Let our process instance know the thread has stopped.
1708*af245d11STodd Fiala         monitor->SetState (StateType::eStateStopped);
1709*af245d11STodd Fiala     }
1710*af245d11STodd Fiala     else
1711*af245d11STodd Fiala     {
1712*af245d11STodd Fiala         args->m_error.SetErrorToGenericError();
1713*af245d11STodd Fiala         args->m_error.SetErrorString("No such process.");
1714*af245d11STodd Fiala     }
1715*af245d11STodd Fiala 
1716*af245d11STodd Fiala  FINISH:
1717*af245d11STodd Fiala     return args->m_error.Success();
1718*af245d11STodd Fiala }
1719*af245d11STodd Fiala 
1720*af245d11STodd Fiala bool
1721*af245d11STodd Fiala NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid)
1722*af245d11STodd Fiala {
1723*af245d11STodd Fiala     long ptrace_opts = 0;
1724*af245d11STodd Fiala 
1725*af245d11STodd Fiala     // Have the child raise an event on exit.  This is used to keep the child in
1726*af245d11STodd Fiala     // limbo until it is destroyed.
1727*af245d11STodd Fiala     ptrace_opts |= PTRACE_O_TRACEEXIT;
1728*af245d11STodd Fiala 
1729*af245d11STodd Fiala     // Have the tracer trace threads which spawn in the inferior process.
1730*af245d11STodd Fiala     // TODO: if we want to support tracing the inferiors' child, add the
1731*af245d11STodd Fiala     // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
1732*af245d11STodd Fiala     ptrace_opts |= PTRACE_O_TRACECLONE;
1733*af245d11STodd Fiala 
1734*af245d11STodd Fiala     // Have the tracer notify us before execve returns
1735*af245d11STodd Fiala     // (needed to disable legacy SIGTRAP generation)
1736*af245d11STodd Fiala     ptrace_opts |= PTRACE_O_TRACEEXEC;
1737*af245d11STodd Fiala 
1738*af245d11STodd Fiala     return PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts, 0) >= 0;
1739*af245d11STodd Fiala }
1740*af245d11STodd Fiala 
1741*af245d11STodd Fiala static ExitType convert_pid_status_to_exit_type (int status)
1742*af245d11STodd Fiala {
1743*af245d11STodd Fiala     if (WIFEXITED (status))
1744*af245d11STodd Fiala         return ExitType::eExitTypeExit;
1745*af245d11STodd Fiala     else if (WIFSIGNALED (status))
1746*af245d11STodd Fiala         return ExitType::eExitTypeSignal;
1747*af245d11STodd Fiala     else if (WIFSTOPPED (status))
1748*af245d11STodd Fiala         return ExitType::eExitTypeStop;
1749*af245d11STodd Fiala     else
1750*af245d11STodd Fiala     {
1751*af245d11STodd Fiala         // We don't know what this is.
1752*af245d11STodd Fiala         return ExitType::eExitTypeInvalid;
1753*af245d11STodd Fiala     }
1754*af245d11STodd Fiala }
1755*af245d11STodd Fiala 
1756*af245d11STodd Fiala static int convert_pid_status_to_return_code (int status)
1757*af245d11STodd Fiala {
1758*af245d11STodd Fiala     if (WIFEXITED (status))
1759*af245d11STodd Fiala         return WEXITSTATUS (status);
1760*af245d11STodd Fiala     else if (WIFSIGNALED (status))
1761*af245d11STodd Fiala         return WTERMSIG (status);
1762*af245d11STodd Fiala     else if (WIFSTOPPED (status))
1763*af245d11STodd Fiala         return WSTOPSIG (status);
1764*af245d11STodd Fiala     else
1765*af245d11STodd Fiala     {
1766*af245d11STodd Fiala         // We don't know what this is.
1767*af245d11STodd Fiala         return ExitType::eExitTypeInvalid;
1768*af245d11STodd Fiala     }
1769*af245d11STodd Fiala }
1770*af245d11STodd Fiala 
1771*af245d11STodd Fiala // Main process monitoring waitpid-loop handler.
1772*af245d11STodd Fiala bool
1773*af245d11STodd Fiala NativeProcessLinux::MonitorCallback(void *callback_baton,
1774*af245d11STodd Fiala                                 lldb::pid_t pid,
1775*af245d11STodd Fiala                                 bool exited,
1776*af245d11STodd Fiala                                 int signal,
1777*af245d11STodd Fiala                                 int status)
1778*af245d11STodd Fiala {
1779*af245d11STodd Fiala     Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
1780*af245d11STodd Fiala 
1781*af245d11STodd Fiala     NativeProcessLinux *const process = static_cast<NativeProcessLinux*>(callback_baton);
1782*af245d11STodd Fiala     assert (process && "process is null");
1783*af245d11STodd Fiala     if (!process)
1784*af245d11STodd Fiala     {
1785*af245d11STodd Fiala         if (log)
1786*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " callback_baton was null, can't determine process to use", __FUNCTION__, pid);
1787*af245d11STodd Fiala         return true;
1788*af245d11STodd Fiala     }
1789*af245d11STodd Fiala 
1790*af245d11STodd Fiala     // Certain activities differ based on whether the pid is the tid of the main thread.
1791*af245d11STodd Fiala     const bool is_main_thread = (pid == process->GetID ());
1792*af245d11STodd Fiala 
1793*af245d11STodd Fiala     // Assume we keep monitoring by default.
1794*af245d11STodd Fiala     bool stop_monitoring = false;
1795*af245d11STodd Fiala 
1796*af245d11STodd Fiala     // Handle when the thread exits.
1797*af245d11STodd Fiala     if (exited)
1798*af245d11STodd Fiala     {
1799*af245d11STodd Fiala         if (log)
1800*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() got exit signal, tid = %"  PRIu64 " (%s main thread)", __FUNCTION__, pid, is_main_thread ? "is" : "is not");
1801*af245d11STodd Fiala 
1802*af245d11STodd Fiala         // This is a thread that exited.  Ensure we're not tracking it anymore.
1803*af245d11STodd Fiala         const bool thread_found = process->StopTrackingThread (pid);
1804*af245d11STodd Fiala 
1805*af245d11STodd Fiala         if (is_main_thread)
1806*af245d11STodd Fiala         {
1807*af245d11STodd Fiala             // We only set the exit status and notify the delegate if we haven't already set the process
1808*af245d11STodd Fiala             // state to an exited state.  We normally should have received a SIGTRAP | (PTRACE_EVENT_EXIT << 8)
1809*af245d11STodd Fiala             // for the main thread.
1810*af245d11STodd Fiala             const bool already_notified = (process->GetState() == StateType::eStateExited) | (process->GetState () == StateType::eStateCrashed);
1811*af245d11STodd Fiala             if (!already_notified)
1812*af245d11STodd Fiala             {
1813*af245d11STodd Fiala                 if (log)
1814*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() tid = %"  PRIu64 " handling main thread exit (%s), expected exit state already set but state was %s instead, setting exit state now", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found", StateAsCString (process->GetState ()));
1815*af245d11STodd Fiala                 // The main thread exited.  We're done monitoring.  Report to delegate.
1816*af245d11STodd Fiala                 process->SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
1817*af245d11STodd Fiala 
1818*af245d11STodd Fiala                 // Notify delegate that our process has exited.
1819*af245d11STodd Fiala                 process->SetState (StateType::eStateExited, true);
1820*af245d11STodd Fiala             }
1821*af245d11STodd Fiala             else
1822*af245d11STodd Fiala             {
1823*af245d11STodd Fiala                 if (log)
1824*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() tid = %"  PRIu64 " main thread now exited (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
1825*af245d11STodd Fiala             }
1826*af245d11STodd Fiala             return true;
1827*af245d11STodd Fiala         }
1828*af245d11STodd Fiala         else
1829*af245d11STodd Fiala         {
1830*af245d11STodd Fiala             // Do we want to report to the delegate in this case?  I think not.  If this was an orderly
1831*af245d11STodd Fiala             // thread exit, we would already have received the SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal,
1832*af245d11STodd Fiala             // and we would have done an all-stop then.
1833*af245d11STodd Fiala             if (log)
1834*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() tid = %"  PRIu64 " handling non-main thread exit (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found");
1835*af245d11STodd Fiala 
1836*af245d11STodd Fiala             // Not the main thread, we keep going.
1837*af245d11STodd Fiala             return false;
1838*af245d11STodd Fiala         }
1839*af245d11STodd Fiala     }
1840*af245d11STodd Fiala 
1841*af245d11STodd Fiala     // Get details on the signal raised.
1842*af245d11STodd Fiala     siginfo_t info;
1843*af245d11STodd Fiala     int ptrace_err = 0;
1844*af245d11STodd Fiala 
1845*af245d11STodd Fiala     if (!process->GetSignalInfo (pid, &info, ptrace_err))
1846*af245d11STodd Fiala     {
1847*af245d11STodd Fiala         if (ptrace_err == EINVAL)
1848*af245d11STodd Fiala         {
1849*af245d11STodd Fiala             // This is the first part of the Linux ptrace group-stop mechanism.
1850*af245d11STodd Fiala             // The tracer (i.e. NativeProcessLinux) is expected to inject the signal
1851*af245d11STodd Fiala             // into the tracee (i.e. inferior) at this point.
1852*af245d11STodd Fiala             if (log)
1853*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() resuming from group-stop", __FUNCTION__);
1854*af245d11STodd Fiala 
1855*af245d11STodd Fiala             // The inferior process is in 'group-stop', so deliver the stopping signal.
1856*af245d11STodd Fiala             const bool signal_delivered = process->Resume (pid, info.si_signo);
1857*af245d11STodd Fiala             if (log)
1858*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " group-stop signal delivery of signal 0x%x (%s) - %s", __FUNCTION__, pid, info.si_signo, GetUnixSignals ().GetSignalAsCString (info.si_signo), signal_delivered ? "success" : "failed");
1859*af245d11STodd Fiala 
1860*af245d11STodd Fiala             assert(signal_delivered && "SIGSTOP delivery failed while in 'group-stop' state");
1861*af245d11STodd Fiala 
1862*af245d11STodd Fiala             stop_monitoring = false;
1863*af245d11STodd Fiala         }
1864*af245d11STodd Fiala         else
1865*af245d11STodd Fiala         {
1866*af245d11STodd Fiala             // ptrace(GETSIGINFO) failed (but not due to group-stop).
1867*af245d11STodd Fiala 
1868*af245d11STodd Fiala             // A return value of ESRCH means the thread/process is no longer on the system,
1869*af245d11STodd Fiala             // so it was killed somehow outside of our control.  Either way, we can't do anything
1870*af245d11STodd Fiala             // with it anymore.
1871*af245d11STodd Fiala 
1872*af245d11STodd Fiala             // We stop monitoring if it was the main thread.
1873*af245d11STodd Fiala             stop_monitoring = is_main_thread;
1874*af245d11STodd Fiala 
1875*af245d11STodd Fiala             // Stop tracking the metadata for the thread since it's entirely off the system now.
1876*af245d11STodd Fiala             const bool thread_found = process->StopTrackingThread (pid);
1877*af245d11STodd Fiala 
1878*af245d11STodd Fiala             if (log)
1879*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)",
1880*af245d11STodd Fiala                              __FUNCTION__, strerror(ptrace_err), pid, signal, status, ptrace_err == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found");
1881*af245d11STodd Fiala 
1882*af245d11STodd Fiala             if (is_main_thread)
1883*af245d11STodd Fiala             {
1884*af245d11STodd Fiala                 // Notify the delegate - our process is not available but appears to have been killed outside
1885*af245d11STodd Fiala                 // our control.  Is eStateExited the right exit state in this case?
1886*af245d11STodd Fiala                 process->SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true);
1887*af245d11STodd Fiala                 process->SetState (StateType::eStateExited, true);
1888*af245d11STodd Fiala             }
1889*af245d11STodd Fiala             else
1890*af245d11STodd Fiala             {
1891*af245d11STodd Fiala                 // This thread was pulled out from underneath us.  Anything to do here? Do we want to do an all stop?
1892*af245d11STodd Fiala                 if (log)
1893*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " non-main thread exit occurred, didn't tell delegate anything since thread disappeared out from underneath us", __FUNCTION__, process->GetID (), pid);
1894*af245d11STodd Fiala             }
1895*af245d11STodd Fiala         }
1896*af245d11STodd Fiala     }
1897*af245d11STodd Fiala     else
1898*af245d11STodd Fiala     {
1899*af245d11STodd Fiala         // We have retrieved the signal info.  Dispatch appropriately.
1900*af245d11STodd Fiala         if (info.si_signo == SIGTRAP)
1901*af245d11STodd Fiala             process->MonitorSIGTRAP(&info, pid);
1902*af245d11STodd Fiala         else
1903*af245d11STodd Fiala             process->MonitorSignal(&info, pid, exited);
1904*af245d11STodd Fiala 
1905*af245d11STodd Fiala         stop_monitoring = false;
1906*af245d11STodd Fiala     }
1907*af245d11STodd Fiala 
1908*af245d11STodd Fiala     return stop_monitoring;
1909*af245d11STodd Fiala }
1910*af245d11STodd Fiala 
1911*af245d11STodd Fiala void
1912*af245d11STodd Fiala NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid)
1913*af245d11STodd Fiala {
1914*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
1915*af245d11STodd Fiala     const bool is_main_thread = (pid == GetID ());
1916*af245d11STodd Fiala 
1917*af245d11STodd Fiala     assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
1918*af245d11STodd Fiala     if (!info)
1919*af245d11STodd Fiala         return;
1920*af245d11STodd Fiala 
1921*af245d11STodd Fiala     // See if we can find a thread for this signal.
1922*af245d11STodd Fiala     NativeThreadProtocolSP thread_sp = GetThreadByID (pid);
1923*af245d11STodd Fiala     if (!thread_sp)
1924*af245d11STodd Fiala     {
1925*af245d11STodd Fiala         if (log)
1926*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid);
1927*af245d11STodd Fiala     }
1928*af245d11STodd Fiala 
1929*af245d11STodd Fiala     switch (info->si_code)
1930*af245d11STodd Fiala     {
1931*af245d11STodd Fiala     // TODO: these two cases are required if we want to support tracing of the inferiors' children.  We'd need this to debug a monitor.
1932*af245d11STodd Fiala     // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
1933*af245d11STodd Fiala     // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
1934*af245d11STodd Fiala 
1935*af245d11STodd Fiala     case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
1936*af245d11STodd Fiala     {
1937*af245d11STodd Fiala         lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
1938*af245d11STodd Fiala 
1939*af245d11STodd Fiala         unsigned long event_message = 0;
1940*af245d11STodd Fiala         if (GetEventMessage(pid, &event_message))
1941*af245d11STodd Fiala             tid = static_cast<lldb::tid_t> (event_message);
1942*af245d11STodd Fiala 
1943*af245d11STodd Fiala         if (log)
1944*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event for tid %" PRIu64, __FUNCTION__, pid, tid);
1945*af245d11STodd Fiala 
1946*af245d11STodd Fiala         // If we don't track the thread yet: create it, mark as stopped.
1947*af245d11STodd Fiala         // If we do track it, this is the wait we needed.  Now resume the new thread.
1948*af245d11STodd Fiala         // In all cases, resume the current (i.e. main process) thread.
1949*af245d11STodd Fiala         bool already_tracked = false;
1950*af245d11STodd Fiala         thread_sp = GetOrCreateThread (tid, already_tracked);
1951*af245d11STodd Fiala         assert (thread_sp.get() && "failed to get or create the tracking data for newly created inferior thread");
1952*af245d11STodd Fiala 
1953*af245d11STodd Fiala         // If the thread was already tracked, it means the created thread already received its SI_USER notification of creation.
1954*af245d11STodd Fiala         if (already_tracked)
1955*af245d11STodd Fiala         {
1956*af245d11STodd Fiala             // FIXME loops like we want to stop all theads here.
1957*af245d11STodd Fiala             // StopAllThreads
1958*af245d11STodd Fiala 
1959*af245d11STodd Fiala             // We can now resume the newly created thread since it is fully created.
1960*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
1961*af245d11STodd Fiala             Resume (tid, LLDB_INVALID_SIGNAL_NUMBER);
1962*af245d11STodd Fiala         }
1963*af245d11STodd Fiala         else
1964*af245d11STodd Fiala         {
1965*af245d11STodd Fiala             // Mark the thread as currently launching.  Need to wait for SIGTRAP clone on the main thread before
1966*af245d11STodd Fiala             // this thread is ready to go.
1967*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetLaunching ();
1968*af245d11STodd Fiala         }
1969*af245d11STodd Fiala 
1970*af245d11STodd Fiala         // In all cases, we can resume the main thread here.
1971*af245d11STodd Fiala         Resume (pid, LLDB_INVALID_SIGNAL_NUMBER);
1972*af245d11STodd Fiala         break;
1973*af245d11STodd Fiala     }
1974*af245d11STodd Fiala 
1975*af245d11STodd Fiala     case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)):
1976*af245d11STodd Fiala         if (log)
1977*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP);
1978*af245d11STodd Fiala         // FIXME stop all threads, mark thread stop reason as ThreadStopInfo.reason = eStopReasonExec;
1979*af245d11STodd Fiala         break;
1980*af245d11STodd Fiala 
1981*af245d11STodd Fiala     case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
1982*af245d11STodd Fiala     {
1983*af245d11STodd Fiala         // The inferior process or one of its threads is about to exit.
1984*af245d11STodd Fiala         // Maintain the process or thread in a state of "limbo" until we are
1985*af245d11STodd Fiala         // explicitly commanded to detach, destroy, resume, etc.
1986*af245d11STodd Fiala         unsigned long data = 0;
1987*af245d11STodd Fiala         if (!GetEventMessage(pid, &data))
1988*af245d11STodd Fiala             data = -1;
1989*af245d11STodd Fiala 
1990*af245d11STodd Fiala         if (log)
1991*af245d11STodd Fiala         {
1992*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = %lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
1993*af245d11STodd Fiala                          __FUNCTION__,
1994*af245d11STodd Fiala                          data, WIFEXITED (data) ? "true" : "false", WIFSIGNALED (data) ? "true" : "false",
1995*af245d11STodd Fiala                          pid,
1996*af245d11STodd Fiala                     is_main_thread ? "is main thread" : "not main thread");
1997*af245d11STodd Fiala         }
1998*af245d11STodd Fiala 
1999*af245d11STodd Fiala         // Set the thread to exited.
2000*af245d11STodd Fiala         if (thread_sp)
2001*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetExited ();
2002*af245d11STodd Fiala         else
2003*af245d11STodd Fiala         {
2004*af245d11STodd Fiala             if (log)
2005*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " failed to retrieve thread for tid %" PRIu64", cannot set thread state", __FUNCTION__, GetID (), pid);
2006*af245d11STodd Fiala         }
2007*af245d11STodd Fiala 
2008*af245d11STodd Fiala         if (is_main_thread)
2009*af245d11STodd Fiala         {
2010*af245d11STodd Fiala             SetExitStatus (convert_pid_status_to_exit_type (data), convert_pid_status_to_return_code (data), nullptr, true);
2011*af245d11STodd Fiala             // Resume the thread so it completely exits.
2012*af245d11STodd Fiala             Resume (pid, LLDB_INVALID_SIGNAL_NUMBER);
2013*af245d11STodd Fiala         }
2014*af245d11STodd Fiala         else
2015*af245d11STodd Fiala         {
2016*af245d11STodd Fiala             // FIXME figure out the path where we plan to reap the metadata for the thread.
2017*af245d11STodd Fiala         }
2018*af245d11STodd Fiala 
2019*af245d11STodd Fiala         break;
2020*af245d11STodd Fiala     }
2021*af245d11STodd Fiala 
2022*af245d11STodd Fiala     case 0:
2023*af245d11STodd Fiala     case TRAP_TRACE:
2024*af245d11STodd Fiala         // We receive this on single stepping.
2025*af245d11STodd Fiala         if (log)
2026*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)", __FUNCTION__, pid);
2027*af245d11STodd Fiala 
2028*af245d11STodd Fiala         if (thread_sp)
2029*af245d11STodd Fiala         {
2030*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (SIGTRAP);
2031*af245d11STodd Fiala             SetCurrentThreadID (thread_sp->GetID ());
2032*af245d11STodd Fiala         }
2033*af245d11STodd Fiala         else
2034*af245d11STodd Fiala         {
2035*af245d11STodd Fiala             if (log)
2036*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 " single stepping received trace but thread not found", __FUNCTION__, GetID (), pid);
2037*af245d11STodd Fiala         }
2038*af245d11STodd Fiala 
2039*af245d11STodd Fiala         // Tell the process we have a stop (from single stepping).
2040*af245d11STodd Fiala         SetState (StateType::eStateStopped, true);
2041*af245d11STodd Fiala         break;
2042*af245d11STodd Fiala 
2043*af245d11STodd Fiala     case SI_KERNEL:
2044*af245d11STodd Fiala     case TRAP_BRKPT:
2045*af245d11STodd Fiala         if (log)
2046*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64, __FUNCTION__, pid);
2047*af245d11STodd Fiala 
2048*af245d11STodd Fiala         // Mark the thread as stopped at breakpoint.
2049*af245d11STodd Fiala         if (thread_sp)
2050*af245d11STodd Fiala         {
2051*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (SIGTRAP);
2052*af245d11STodd Fiala             Error error = FixupBreakpointPCAsNeeded (thread_sp);
2053*af245d11STodd Fiala             if (error.Fail ())
2054*af245d11STodd Fiala             {
2055*af245d11STodd Fiala                 if (log)
2056*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s", __FUNCTION__, pid, error.AsCString ());
2057*af245d11STodd Fiala             }
2058*af245d11STodd Fiala         }
2059*af245d11STodd Fiala         else
2060*af245d11STodd Fiala         {
2061*af245d11STodd Fiala             if (log)
2062*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s()  pid = %" PRIu64 ": warning, cannot process software breakpoint since no thread metadata", __FUNCTION__, pid);
2063*af245d11STodd Fiala         }
2064*af245d11STodd Fiala 
2065*af245d11STodd Fiala 
2066*af245d11STodd Fiala         // Tell the process we have a stop from this thread.
2067*af245d11STodd Fiala         SetCurrentThreadID (pid);
2068*af245d11STodd Fiala         SetState (StateType::eStateStopped, true);
2069*af245d11STodd Fiala         break;
2070*af245d11STodd Fiala 
2071*af245d11STodd Fiala     case TRAP_HWBKPT:
2072*af245d11STodd Fiala         if (log)
2073*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received watchpoint event, pid = %" PRIu64, __FUNCTION__, pid);
2074*af245d11STodd Fiala 
2075*af245d11STodd Fiala         // Mark the thread as stopped at watchpoint.
2076*af245d11STodd Fiala         // The address is at (lldb::addr_t)info->si_addr if we need it.
2077*af245d11STodd Fiala         if (thread_sp)
2078*af245d11STodd Fiala             reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (SIGTRAP);
2079*af245d11STodd Fiala         else
2080*af245d11STodd Fiala         {
2081*af245d11STodd Fiala             if (log)
2082*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ": warning, cannot process hardware breakpoint since no thread metadata", __FUNCTION__, GetID (), pid);
2083*af245d11STodd Fiala         }
2084*af245d11STodd Fiala 
2085*af245d11STodd Fiala         // Tell the process we have a stop from this thread.
2086*af245d11STodd Fiala         SetCurrentThreadID (pid);
2087*af245d11STodd Fiala         SetState (StateType::eStateStopped, true);
2088*af245d11STodd Fiala         break;
2089*af245d11STodd Fiala 
2090*af245d11STodd Fiala     case SIGTRAP:
2091*af245d11STodd Fiala     case (SIGTRAP | 0x80):
2092*af245d11STodd Fiala         if (log)
2093*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received system call stop event, pid %" PRIu64 "tid %" PRIu64, __FUNCTION__, GetID (), pid);
2094*af245d11STodd Fiala         // Ignore these signals until we know more about them.
2095*af245d11STodd Fiala         Resume(pid, 0);
2096*af245d11STodd Fiala         break;
2097*af245d11STodd Fiala 
2098*af245d11STodd Fiala     default:
2099*af245d11STodd Fiala         assert(false && "Unexpected SIGTRAP code!");
2100*af245d11STodd Fiala         if (log)
2101*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64 " received unhandled SIGTRAP code: 0x%" PRIx64, __FUNCTION__, GetID (), pid, static_cast<uint64_t> (SIGTRAP | (PTRACE_EVENT_CLONE << 8)));
2102*af245d11STodd Fiala         break;
2103*af245d11STodd Fiala 
2104*af245d11STodd Fiala     }
2105*af245d11STodd Fiala }
2106*af245d11STodd Fiala 
2107*af245d11STodd Fiala void
2108*af245d11STodd Fiala NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited)
2109*af245d11STodd Fiala {
2110*af245d11STodd Fiala     int signo = info->si_signo;
2111*af245d11STodd Fiala 
2112*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2113*af245d11STodd Fiala 
2114*af245d11STodd Fiala     // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
2115*af245d11STodd Fiala     // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
2116*af245d11STodd Fiala     // kill(2) or raise(3).  Similarly for tgkill(2) on Linux.
2117*af245d11STodd Fiala     //
2118*af245d11STodd Fiala     // IOW, user generated signals never generate what we consider to be a
2119*af245d11STodd Fiala     // "crash".
2120*af245d11STodd Fiala     //
2121*af245d11STodd Fiala     // Similarly, ACK signals generated by this monitor.
2122*af245d11STodd Fiala 
2123*af245d11STodd Fiala     // See if we can find a thread for this signal.
2124*af245d11STodd Fiala     NativeThreadProtocolSP thread_sp = GetThreadByID (pid);
2125*af245d11STodd Fiala     if (!thread_sp)
2126*af245d11STodd Fiala     {
2127*af245d11STodd Fiala         if (log)
2128*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid);
2129*af245d11STodd Fiala     }
2130*af245d11STodd Fiala 
2131*af245d11STodd Fiala     // Handle the signal.
2132*af245d11STodd Fiala     if (info->si_code == SI_TKILL || info->si_code == SI_USER)
2133*af245d11STodd Fiala     {
2134*af245d11STodd Fiala         if (log)
2135*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
2136*af245d11STodd Fiala                             __FUNCTION__,
2137*af245d11STodd Fiala                             GetUnixSignals ().GetSignalAsCString (signo),
2138*af245d11STodd Fiala                             signo,
2139*af245d11STodd Fiala                             (info->si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
2140*af245d11STodd Fiala                             info->si_pid,
2141*af245d11STodd Fiala                             (info->si_pid == getpid ()) ? "is monitor" : "is not monitor",
2142*af245d11STodd Fiala                             pid);
2143*af245d11STodd Fiala 
2144*af245d11STodd Fiala         if ((info->si_pid == 0) && info->si_code == SI_USER)
2145*af245d11STodd Fiala         {
2146*af245d11STodd Fiala             // A new thread creation is being signaled.  This is one of two parts that come in
2147*af245d11STodd Fiala             // a non-deterministic order.  pid is the thread id.
2148*af245d11STodd Fiala             if (log)
2149*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification",
2150*af245d11STodd Fiala                          __FUNCTION__, GetID (), pid);
2151*af245d11STodd Fiala 
2152*af245d11STodd Fiala             // Did we already create the thread?
2153*af245d11STodd Fiala             bool already_tracked = false;
2154*af245d11STodd Fiala             thread_sp = GetOrCreateThread (pid, already_tracked);
2155*af245d11STodd Fiala             assert (thread_sp.get() && "failed to get or create the tracking data for newly created inferior thread");
2156*af245d11STodd Fiala 
2157*af245d11STodd Fiala             // If the thread was already tracked, it means the main thread already received its SIGTRAP for the create.
2158*af245d11STodd Fiala             if (already_tracked)
2159*af245d11STodd Fiala             {
2160*af245d11STodd Fiala                 // We can now resume this thread up since it is fully created.
2161*af245d11STodd Fiala                 reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
2162*af245d11STodd Fiala                 Resume (thread_sp->GetID (), LLDB_INVALID_SIGNAL_NUMBER);
2163*af245d11STodd Fiala             }
2164*af245d11STodd Fiala             else
2165*af245d11STodd Fiala             {
2166*af245d11STodd Fiala                 // Mark the thread as currently launching.  Need to wait for SIGTRAP clone on the main thread before
2167*af245d11STodd Fiala                 // this thread is ready to go.
2168*af245d11STodd Fiala                 reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetLaunching ();
2169*af245d11STodd Fiala             }
2170*af245d11STodd Fiala         }
2171*af245d11STodd Fiala         else if (info->si_pid == getpid () && (signo == SIGSTOP))
2172*af245d11STodd Fiala         {
2173*af245d11STodd Fiala             // This is a tgkill()-based stop.
2174*af245d11STodd Fiala             if (thread_sp)
2175*af245d11STodd Fiala             {
2176*af245d11STodd Fiala                 // An inferior thread just stopped.  Mark it as such.
2177*af245d11STodd Fiala                 reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
2178*af245d11STodd Fiala                 SetCurrentThreadID (thread_sp->GetID ());
2179*af245d11STodd Fiala 
2180*af245d11STodd Fiala                 // Remove this tid from the wait-for-stop set.
2181*af245d11STodd Fiala                 Mutex::Locker locker (m_wait_for_stop_tids_mutex);
2182*af245d11STodd Fiala 
2183*af245d11STodd Fiala                 auto removed_count = m_wait_for_stop_tids.erase (thread_sp->GetID ());
2184*af245d11STodd Fiala                 if (removed_count < 1)
2185*af245d11STodd Fiala                 {
2186*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": tgkill()-stopped thread not in m_wait_for_stop_tids",
2187*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID ());
2188*af245d11STodd Fiala 
2189*af245d11STodd Fiala                 }
2190*af245d11STodd Fiala 
2191*af245d11STodd Fiala                 // If this is the last thread in the m_wait_for_stop_tids, we need to notify
2192*af245d11STodd Fiala                 // the delegate that a stop has occurred now that every thread that was supposed
2193*af245d11STodd Fiala                 // to stop has stopped.
2194*af245d11STodd Fiala                 if (m_wait_for_stop_tids.empty ())
2195*af245d11STodd Fiala                 {
2196*af245d11STodd Fiala                     if (log)
2197*af245d11STodd Fiala                     {
2198*af245d11STodd Fiala                         log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", setting process state to stopped now that all tids marked for stop have completed",
2199*af245d11STodd Fiala                                      __FUNCTION__,
2200*af245d11STodd Fiala                                      GetID (),
2201*af245d11STodd Fiala                                      pid);
2202*af245d11STodd Fiala                     }
2203*af245d11STodd Fiala                     SetState (StateType::eStateStopped, true);
2204*af245d11STodd Fiala                 }
2205*af245d11STodd Fiala             }
2206*af245d11STodd Fiala         }
2207*af245d11STodd Fiala         else
2208*af245d11STodd Fiala         {
2209*af245d11STodd Fiala             // Hmm, not sure what to do with this.
2210*af245d11STodd Fiala             if (log)
2211*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " unsure how to handle SI_KILL or SI_USER signal", __FUNCTION__, GetID ());
2212*af245d11STodd Fiala         }
2213*af245d11STodd Fiala 
2214*af245d11STodd Fiala         return;
2215*af245d11STodd Fiala     }
2216*af245d11STodd Fiala 
2217*af245d11STodd Fiala     if (log)
2218*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, GetUnixSignals ().GetSignalAsCString (signo));
2219*af245d11STodd Fiala 
2220*af245d11STodd Fiala     switch (signo)
2221*af245d11STodd Fiala     {
2222*af245d11STodd Fiala     case SIGSEGV:
2223*af245d11STodd Fiala         {
2224*af245d11STodd Fiala             lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
2225*af245d11STodd Fiala 
2226*af245d11STodd Fiala             // FIXME figure out how to propagate this properly.  Seems like it
2227*af245d11STodd Fiala             // should go in ThreadStopInfo.
2228*af245d11STodd Fiala             // We can get more details on the exact nature of the crash here.
2229*af245d11STodd Fiala             // ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
2230*af245d11STodd Fiala             if (!exited)
2231*af245d11STodd Fiala             {
2232*af245d11STodd Fiala                 // This is just a pre-signal-delivery notification of the incoming signal.
2233*af245d11STodd Fiala                 // Send a stop to the debugger.
2234*af245d11STodd Fiala                 if (thread_sp)
2235*af245d11STodd Fiala                 {
2236*af245d11STodd Fiala                     reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
2237*af245d11STodd Fiala                     SetCurrentThreadID (thread_sp->GetID ());
2238*af245d11STodd Fiala                 }
2239*af245d11STodd Fiala                 SetState (StateType::eStateStopped, true);
2240*af245d11STodd Fiala             }
2241*af245d11STodd Fiala             else
2242*af245d11STodd Fiala             {
2243*af245d11STodd Fiala                 if (thread_sp)
2244*af245d11STodd Fiala                 {
2245*af245d11STodd Fiala                     // FIXME figure out what type this is.
2246*af245d11STodd Fiala                     const uint64_t exception_type = static_cast<uint64_t> (SIGSEGV);
2247*af245d11STodd Fiala                     reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetCrashedWithException (exception_type, fault_addr);
2248*af245d11STodd Fiala                 }
2249*af245d11STodd Fiala                 SetState (StateType::eStateCrashed, true);
2250*af245d11STodd Fiala             }
2251*af245d11STodd Fiala         }
2252*af245d11STodd Fiala         break;
2253*af245d11STodd Fiala 
2254*af245d11STodd Fiala     case SIGILL:
2255*af245d11STodd Fiala         {
2256*af245d11STodd Fiala             // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
2257*af245d11STodd Fiala             // Can get the reason from here.
2258*af245d11STodd Fiala             // ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
2259*af245d11STodd Fiala             // FIXME save the crash reason
2260*af245d11STodd Fiala             SetState (StateType::eStateCrashed, true);
2261*af245d11STodd Fiala         }
2262*af245d11STodd Fiala         break;
2263*af245d11STodd Fiala 
2264*af245d11STodd Fiala     case SIGFPE:
2265*af245d11STodd Fiala         {
2266*af245d11STodd Fiala             // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
2267*af245d11STodd Fiala             // Can get the crash reason from below.
2268*af245d11STodd Fiala             // ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
2269*af245d11STodd Fiala             // FIXME save the crash reason
2270*af245d11STodd Fiala             SetState (StateType::eStateCrashed, true);
2271*af245d11STodd Fiala         }
2272*af245d11STodd Fiala         break;
2273*af245d11STodd Fiala 
2274*af245d11STodd Fiala     case SIGBUS:
2275*af245d11STodd Fiala         {
2276*af245d11STodd Fiala             // lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
2277*af245d11STodd Fiala             // Can get the crash reason from below.
2278*af245d11STodd Fiala             // ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
2279*af245d11STodd Fiala             // FIXME save the crash reason
2280*af245d11STodd Fiala             SetState (StateType::eStateCrashed);
2281*af245d11STodd Fiala         }
2282*af245d11STodd Fiala         break;
2283*af245d11STodd Fiala 
2284*af245d11STodd Fiala     default:
2285*af245d11STodd Fiala         // FIXME Stop all threads here.
2286*af245d11STodd Fiala         break;
2287*af245d11STodd Fiala     }
2288*af245d11STodd Fiala }
2289*af245d11STodd Fiala 
2290*af245d11STodd Fiala Error
2291*af245d11STodd Fiala NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
2292*af245d11STodd Fiala {
2293*af245d11STodd Fiala     Error error;
2294*af245d11STodd Fiala 
2295*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
2296*af245d11STodd Fiala     if (log)
2297*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ());
2298*af245d11STodd Fiala 
2299*af245d11STodd Fiala     int run_thread_count = 0;
2300*af245d11STodd Fiala     int stop_thread_count = 0;
2301*af245d11STodd Fiala     int step_thread_count = 0;
2302*af245d11STodd Fiala 
2303*af245d11STodd Fiala     std::vector<NativeThreadProtocolSP> new_stop_threads;
2304*af245d11STodd Fiala 
2305*af245d11STodd Fiala     Mutex::Locker locker (m_threads_mutex);
2306*af245d11STodd Fiala     for (auto thread_sp : m_threads)
2307*af245d11STodd Fiala     {
2308*af245d11STodd Fiala         assert (thread_sp && "thread list should not contain NULL threads");
2309*af245d11STodd Fiala         NativeThreadLinux *const linux_thread_p = reinterpret_cast<NativeThreadLinux*> (thread_sp.get ());
2310*af245d11STodd Fiala 
2311*af245d11STodd Fiala         const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
2312*af245d11STodd Fiala         assert (action && "NULL ResumeAction returned for thread during Resume ()");
2313*af245d11STodd Fiala 
2314*af245d11STodd Fiala         if (log)
2315*af245d11STodd Fiala         {
2316*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64,
2317*af245d11STodd Fiala                     __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
2318*af245d11STodd Fiala         }
2319*af245d11STodd Fiala 
2320*af245d11STodd Fiala         switch (action->state)
2321*af245d11STodd Fiala         {
2322*af245d11STodd Fiala         case eStateRunning:
2323*af245d11STodd Fiala             // Run the thread, possibly feeding it the signal.
2324*af245d11STodd Fiala             linux_thread_p->SetRunning ();
2325*af245d11STodd Fiala             if (action->signal > 0)
2326*af245d11STodd Fiala             {
2327*af245d11STodd Fiala                 // Resume the thread and deliver the given signal,
2328*af245d11STodd Fiala                 // then mark as delivered.
2329*af245d11STodd Fiala                 Resume (thread_sp->GetID (), action->signal);
2330*af245d11STodd Fiala                 resume_actions.SetSignalHandledForThread (thread_sp->GetID ());
2331*af245d11STodd Fiala             }
2332*af245d11STodd Fiala             else
2333*af245d11STodd Fiala             {
2334*af245d11STodd Fiala                 // Just resume the thread with no signal.
2335*af245d11STodd Fiala                 Resume (thread_sp->GetID (), LLDB_INVALID_SIGNAL_NUMBER);
2336*af245d11STodd Fiala             }
2337*af245d11STodd Fiala             ++run_thread_count;
2338*af245d11STodd Fiala             break;
2339*af245d11STodd Fiala 
2340*af245d11STodd Fiala         case eStateStepping:
2341*af245d11STodd Fiala             // Note: if we have multiple threads, we may need to stop
2342*af245d11STodd Fiala             // the other threads first, then step this one.
2343*af245d11STodd Fiala             linux_thread_p->SetStepping ();
2344*af245d11STodd Fiala             if (SingleStep (thread_sp->GetID (), 0))
2345*af245d11STodd Fiala             {
2346*af245d11STodd Fiala                 if (log)
2347*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " single step succeeded",
2348*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID ());
2349*af245d11STodd Fiala             }
2350*af245d11STodd Fiala             else
2351*af245d11STodd Fiala             {
2352*af245d11STodd Fiala                 if (log)
2353*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " single step failed",
2354*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID ());
2355*af245d11STodd Fiala             }
2356*af245d11STodd Fiala             ++step_thread_count;
2357*af245d11STodd Fiala             break;
2358*af245d11STodd Fiala 
2359*af245d11STodd Fiala         case eStateSuspended:
2360*af245d11STodd Fiala         case eStateStopped:
2361*af245d11STodd Fiala             if (!StateIsStoppedState (linux_thread_p->GetState (), false))
2362*af245d11STodd Fiala                 new_stop_threads.push_back (thread_sp);
2363*af245d11STodd Fiala             else
2364*af245d11STodd Fiala             {
2365*af245d11STodd Fiala                 if (log)
2366*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s no need to stop pid %" PRIu64 " tid %" PRIu64 ", thread state already %s",
2367*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID (), StateAsCString (linux_thread_p->GetState ()));
2368*af245d11STodd Fiala             }
2369*af245d11STodd Fiala 
2370*af245d11STodd Fiala             ++stop_thread_count;
2371*af245d11STodd Fiala             break;
2372*af245d11STodd Fiala 
2373*af245d11STodd Fiala         default:
2374*af245d11STodd Fiala             return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64,
2375*af245d11STodd Fiala                     __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
2376*af245d11STodd Fiala         }
2377*af245d11STodd Fiala     }
2378*af245d11STodd Fiala 
2379*af245d11STodd Fiala     // If any thread was set to run, notify the process state as running.
2380*af245d11STodd Fiala     if (run_thread_count > 0)
2381*af245d11STodd Fiala         SetState (StateType::eStateRunning, true);
2382*af245d11STodd Fiala 
2383*af245d11STodd Fiala     // Now do a tgkill SIGSTOP on each thread we want to stop.
2384*af245d11STodd Fiala     if (!new_stop_threads.empty ())
2385*af245d11STodd Fiala     {
2386*af245d11STodd Fiala         // Lock the m_wait_for_stop_tids set so we can fill it with every thread we expect to have stopped.
2387*af245d11STodd Fiala         Mutex::Locker stop_thread_id_locker (m_wait_for_stop_tids_mutex);
2388*af245d11STodd Fiala         for (auto thread_sp : new_stop_threads)
2389*af245d11STodd Fiala         {
2390*af245d11STodd Fiala             // Send a stop signal to the thread.
2391*af245d11STodd Fiala             const int result = tgkill (GetID (), thread_sp->GetID (), SIGSTOP);
2392*af245d11STodd Fiala             if (result != 0)
2393*af245d11STodd Fiala             {
2394*af245d11STodd Fiala                 // tgkill failed.
2395*af245d11STodd Fiala                 if (log)
2396*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s error: tgkill SIGSTOP for pid %" PRIu64 " tid %" PRIu64 "failed, retval %d",
2397*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID (), result);
2398*af245d11STodd Fiala             }
2399*af245d11STodd Fiala             else
2400*af245d11STodd Fiala             {
2401*af245d11STodd Fiala                 // tgkill succeeded.  Don't mark the thread state, though.  Let the signal
2402*af245d11STodd Fiala                 // handling mark it.
2403*af245d11STodd Fiala                 if (log)
2404*af245d11STodd Fiala                     log->Printf ("NativeProcessLinux::%s tgkill SIGSTOP for pid %" PRIu64 " tid %" PRIu64 " succeeded",
2405*af245d11STodd Fiala                                  __FUNCTION__, GetID (), thread_sp->GetID ());
2406*af245d11STodd Fiala 
2407*af245d11STodd Fiala                 // Add it to the set of threads we expect to signal a stop.
2408*af245d11STodd Fiala                 // We won't tell the delegate about it until this list drains to empty.
2409*af245d11STodd Fiala                 m_wait_for_stop_tids.insert (thread_sp->GetID ());
2410*af245d11STodd Fiala             }
2411*af245d11STodd Fiala         }
2412*af245d11STodd Fiala     }
2413*af245d11STodd Fiala 
2414*af245d11STodd Fiala     return error;
2415*af245d11STodd Fiala }
2416*af245d11STodd Fiala 
2417*af245d11STodd Fiala Error
2418*af245d11STodd Fiala NativeProcessLinux::Halt ()
2419*af245d11STodd Fiala {
2420*af245d11STodd Fiala     Error error;
2421*af245d11STodd Fiala 
2422*af245d11STodd Fiala     // FIXME check if we're already stopped
2423*af245d11STodd Fiala     const bool is_stopped = false;
2424*af245d11STodd Fiala     if (is_stopped)
2425*af245d11STodd Fiala         return error;
2426*af245d11STodd Fiala 
2427*af245d11STodd Fiala     if (kill (GetID (), SIGSTOP) != 0)
2428*af245d11STodd Fiala         error.SetErrorToErrno ();
2429*af245d11STodd Fiala 
2430*af245d11STodd Fiala     return error;
2431*af245d11STodd Fiala }
2432*af245d11STodd Fiala 
2433*af245d11STodd Fiala Error
2434*af245d11STodd Fiala NativeProcessLinux::Detach ()
2435*af245d11STodd Fiala {
2436*af245d11STodd Fiala     Error error;
2437*af245d11STodd Fiala 
2438*af245d11STodd Fiala     // Tell ptrace to detach from the process.
2439*af245d11STodd Fiala     if (GetID () != LLDB_INVALID_PROCESS_ID)
2440*af245d11STodd Fiala         error = Detach (GetID ());
2441*af245d11STodd Fiala 
2442*af245d11STodd Fiala     // Stop monitoring the inferior.
2443*af245d11STodd Fiala     StopMonitor ();
2444*af245d11STodd Fiala 
2445*af245d11STodd Fiala     // No error.
2446*af245d11STodd Fiala     return error;
2447*af245d11STodd Fiala }
2448*af245d11STodd Fiala 
2449*af245d11STodd Fiala Error
2450*af245d11STodd Fiala NativeProcessLinux::Signal (int signo)
2451*af245d11STodd Fiala {
2452*af245d11STodd Fiala     Error error;
2453*af245d11STodd Fiala 
2454*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2455*af245d11STodd Fiala     if (log)
2456*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64,
2457*af245d11STodd Fiala                 __FUNCTION__, signo,  GetUnixSignals ().GetSignalAsCString (signo), GetID ());
2458*af245d11STodd Fiala 
2459*af245d11STodd Fiala     if (kill(GetID(), signo))
2460*af245d11STodd Fiala         error.SetErrorToErrno();
2461*af245d11STodd Fiala 
2462*af245d11STodd Fiala     return error;
2463*af245d11STodd Fiala }
2464*af245d11STodd Fiala 
2465*af245d11STodd Fiala Error
2466*af245d11STodd Fiala NativeProcessLinux::Kill ()
2467*af245d11STodd Fiala {
2468*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2469*af245d11STodd Fiala     if (log)
2470*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__, GetID ());
2471*af245d11STodd Fiala 
2472*af245d11STodd Fiala     Error error;
2473*af245d11STodd Fiala 
2474*af245d11STodd Fiala     switch (m_state)
2475*af245d11STodd Fiala     {
2476*af245d11STodd Fiala         case StateType::eStateInvalid:
2477*af245d11STodd Fiala         case StateType::eStateExited:
2478*af245d11STodd Fiala         case StateType::eStateCrashed:
2479*af245d11STodd Fiala         case StateType::eStateDetached:
2480*af245d11STodd Fiala         case StateType::eStateUnloaded:
2481*af245d11STodd Fiala             // Nothing to do - the process is already dead.
2482*af245d11STodd Fiala             if (log)
2483*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s ignored for PID %" PRIu64 " due to current state: %s", __FUNCTION__, GetID (), StateAsCString (m_state));
2484*af245d11STodd Fiala             return error;
2485*af245d11STodd Fiala 
2486*af245d11STodd Fiala         case StateType::eStateConnected:
2487*af245d11STodd Fiala         case StateType::eStateAttaching:
2488*af245d11STodd Fiala         case StateType::eStateLaunching:
2489*af245d11STodd Fiala         case StateType::eStateStopped:
2490*af245d11STodd Fiala         case StateType::eStateRunning:
2491*af245d11STodd Fiala         case StateType::eStateStepping:
2492*af245d11STodd Fiala         case StateType::eStateSuspended:
2493*af245d11STodd Fiala             // We can try to kill a process in these states.
2494*af245d11STodd Fiala             break;
2495*af245d11STodd Fiala     }
2496*af245d11STodd Fiala 
2497*af245d11STodd Fiala     if (kill (GetID (), SIGKILL) != 0)
2498*af245d11STodd Fiala     {
2499*af245d11STodd Fiala         error.SetErrorToErrno ();
2500*af245d11STodd Fiala         return error;
2501*af245d11STodd Fiala     }
2502*af245d11STodd Fiala 
2503*af245d11STodd Fiala     return error;
2504*af245d11STodd Fiala }
2505*af245d11STodd Fiala 
2506*af245d11STodd Fiala static Error
2507*af245d11STodd Fiala ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegionInfo &memory_region_info)
2508*af245d11STodd Fiala {
2509*af245d11STodd Fiala     memory_region_info.Clear();
2510*af245d11STodd Fiala 
2511*af245d11STodd Fiala     StringExtractor line_extractor (maps_line.c_str ());
2512*af245d11STodd Fiala 
2513*af245d11STodd Fiala     // Format: {address_start_hex}-{address_end_hex} perms offset  dev   inode   pathname
2514*af245d11STodd Fiala     // perms: rwxp   (letter is present if set, '-' if not, final character is p=private, s=shared).
2515*af245d11STodd Fiala 
2516*af245d11STodd Fiala     // Parse out the starting address
2517*af245d11STodd Fiala     lldb::addr_t start_address = line_extractor.GetHexMaxU64 (false, 0);
2518*af245d11STodd Fiala 
2519*af245d11STodd Fiala     // Parse out hyphen separating start and end address from range.
2520*af245d11STodd Fiala     if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != '-'))
2521*af245d11STodd Fiala         return Error ("malformed /proc/{pid}/maps entry, missing dash between address range");
2522*af245d11STodd Fiala 
2523*af245d11STodd Fiala     // Parse out the ending address
2524*af245d11STodd Fiala     lldb::addr_t end_address = line_extractor.GetHexMaxU64 (false, start_address);
2525*af245d11STodd Fiala 
2526*af245d11STodd Fiala     // Parse out the space after the address.
2527*af245d11STodd Fiala     if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != ' '))
2528*af245d11STodd Fiala         return Error ("malformed /proc/{pid}/maps entry, missing space after range");
2529*af245d11STodd Fiala 
2530*af245d11STodd Fiala     // Save the range.
2531*af245d11STodd Fiala     memory_region_info.GetRange ().SetRangeBase (start_address);
2532*af245d11STodd Fiala     memory_region_info.GetRange ().SetRangeEnd (end_address);
2533*af245d11STodd Fiala 
2534*af245d11STodd Fiala     // Parse out each permission entry.
2535*af245d11STodd Fiala     if (line_extractor.GetBytesLeft () < 4)
2536*af245d11STodd Fiala         return Error ("malformed /proc/{pid}/maps entry, missing some portion of permissions");
2537*af245d11STodd Fiala 
2538*af245d11STodd Fiala     // Handle read permission.
2539*af245d11STodd Fiala     const char read_perm_char = line_extractor.GetChar ();
2540*af245d11STodd Fiala     if (read_perm_char == 'r')
2541*af245d11STodd Fiala         memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eYes);
2542*af245d11STodd Fiala     else
2543*af245d11STodd Fiala     {
2544*af245d11STodd Fiala         assert ( (read_perm_char == '-') && "unexpected /proc/{pid}/maps read permission char" );
2545*af245d11STodd Fiala         memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
2546*af245d11STodd Fiala     }
2547*af245d11STodd Fiala 
2548*af245d11STodd Fiala     // Handle write permission.
2549*af245d11STodd Fiala     const char write_perm_char = line_extractor.GetChar ();
2550*af245d11STodd Fiala     if (write_perm_char == 'w')
2551*af245d11STodd Fiala         memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eYes);
2552*af245d11STodd Fiala     else
2553*af245d11STodd Fiala     {
2554*af245d11STodd Fiala         assert ( (write_perm_char == '-') && "unexpected /proc/{pid}/maps write permission char" );
2555*af245d11STodd Fiala         memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
2556*af245d11STodd Fiala     }
2557*af245d11STodd Fiala 
2558*af245d11STodd Fiala     // Handle execute permission.
2559*af245d11STodd Fiala     const char exec_perm_char = line_extractor.GetChar ();
2560*af245d11STodd Fiala     if (exec_perm_char == 'x')
2561*af245d11STodd Fiala         memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eYes);
2562*af245d11STodd Fiala     else
2563*af245d11STodd Fiala     {
2564*af245d11STodd Fiala         assert ( (exec_perm_char == '-') && "unexpected /proc/{pid}/maps exec permission char" );
2565*af245d11STodd Fiala         memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
2566*af245d11STodd Fiala     }
2567*af245d11STodd Fiala 
2568*af245d11STodd Fiala     return Error ();
2569*af245d11STodd Fiala }
2570*af245d11STodd Fiala 
2571*af245d11STodd Fiala Error
2572*af245d11STodd Fiala NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info)
2573*af245d11STodd Fiala {
2574*af245d11STodd Fiala     // FIXME review that the final memory region returned extends to the end of the virtual address space,
2575*af245d11STodd Fiala     // with no perms if it is not mapped.
2576*af245d11STodd Fiala 
2577*af245d11STodd Fiala     // Use an approach that reads memory regions from /proc/{pid}/maps.
2578*af245d11STodd Fiala     // Assume proc maps entries are in ascending order.
2579*af245d11STodd Fiala     // FIXME assert if we find differently.
2580*af245d11STodd Fiala     Mutex::Locker locker (m_mem_region_cache_mutex);
2581*af245d11STodd Fiala 
2582*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2583*af245d11STodd Fiala     Error error;
2584*af245d11STodd Fiala 
2585*af245d11STodd Fiala     if (m_supports_mem_region == LazyBool::eLazyBoolNo)
2586*af245d11STodd Fiala     {
2587*af245d11STodd Fiala         // We're done.
2588*af245d11STodd Fiala         error.SetErrorString ("unsupported");
2589*af245d11STodd Fiala         return error;
2590*af245d11STodd Fiala     }
2591*af245d11STodd Fiala 
2592*af245d11STodd Fiala     // If our cache is empty, pull the latest.  There should always be at least one memory region
2593*af245d11STodd Fiala     // if memory region handling is supported.
2594*af245d11STodd Fiala     if (m_mem_region_cache.empty ())
2595*af245d11STodd Fiala     {
2596*af245d11STodd Fiala         error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
2597*af245d11STodd Fiala              [&] (const std::string &line) -> bool
2598*af245d11STodd Fiala              {
2599*af245d11STodd Fiala                  MemoryRegionInfo info;
2600*af245d11STodd Fiala                  const Error parse_error = ParseMemoryRegionInfoFromProcMapsLine (line, info);
2601*af245d11STodd Fiala                  if (parse_error.Success ())
2602*af245d11STodd Fiala                  {
2603*af245d11STodd Fiala                      m_mem_region_cache.push_back (info);
2604*af245d11STodd Fiala                      return true;
2605*af245d11STodd Fiala                  }
2606*af245d11STodd Fiala                  else
2607*af245d11STodd Fiala                  {
2608*af245d11STodd Fiala                      if (log)
2609*af245d11STodd Fiala                          log->Printf ("NativeProcessLinux::%s failed to parse proc maps line '%s': %s", __FUNCTION__, line.c_str (), error.AsCString ());
2610*af245d11STodd Fiala                      return false;
2611*af245d11STodd Fiala                  }
2612*af245d11STodd Fiala              });
2613*af245d11STodd Fiala 
2614*af245d11STodd Fiala         // If we had an error, we'll mark unsupported.
2615*af245d11STodd Fiala         if (error.Fail ())
2616*af245d11STodd Fiala         {
2617*af245d11STodd Fiala             m_supports_mem_region = LazyBool::eLazyBoolNo;
2618*af245d11STodd Fiala             return error;
2619*af245d11STodd Fiala         }
2620*af245d11STodd Fiala         else if (m_mem_region_cache.empty ())
2621*af245d11STodd Fiala         {
2622*af245d11STodd Fiala             // No entries after attempting to read them.  This shouldn't happen if /proc/{pid}/maps
2623*af245d11STodd Fiala             // is supported.  Assume we don't support map entries via procfs.
2624*af245d11STodd Fiala             if (log)
2625*af245d11STodd Fiala                 log->Printf ("NativeProcessLinux::%s failed to find any procfs maps entries, assuming no support for memory region metadata retrieval", __FUNCTION__);
2626*af245d11STodd Fiala             m_supports_mem_region = LazyBool::eLazyBoolNo;
2627*af245d11STodd Fiala             error.SetErrorString ("not supported");
2628*af245d11STodd Fiala             return error;
2629*af245d11STodd Fiala         }
2630*af245d11STodd Fiala 
2631*af245d11STodd Fiala         if (log)
2632*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s read %" PRIu64 " memory region entries from /proc/%" PRIu64 "/maps", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()), GetID ());
2633*af245d11STodd Fiala 
2634*af245d11STodd Fiala         // We support memory retrieval, remember that.
2635*af245d11STodd Fiala         m_supports_mem_region = LazyBool::eLazyBoolYes;
2636*af245d11STodd Fiala     }
2637*af245d11STodd Fiala     else
2638*af245d11STodd Fiala     {
2639*af245d11STodd Fiala         if (log)
2640*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s reusing %" PRIu64 " cached memory region entries", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
2641*af245d11STodd Fiala     }
2642*af245d11STodd Fiala 
2643*af245d11STodd Fiala     lldb::addr_t prev_base_address = 0;
2644*af245d11STodd Fiala 
2645*af245d11STodd Fiala     // FIXME start by finding the last region that is <= target address using binary search.  Data is sorted.
2646*af245d11STodd Fiala     // There can be a ton of regions on pthreads apps with lots of threads.
2647*af245d11STodd Fiala     for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end (); ++it)
2648*af245d11STodd Fiala     {
2649*af245d11STodd Fiala         MemoryRegionInfo &proc_entry_info = *it;
2650*af245d11STodd Fiala 
2651*af245d11STodd Fiala         // Sanity check assumption that /proc/{pid}/maps entries are ascending.
2652*af245d11STodd Fiala         assert ((proc_entry_info.GetRange ().GetRangeBase () >= prev_base_address) && "descending /proc/pid/maps entries detected, unexpected");
2653*af245d11STodd Fiala         prev_base_address = proc_entry_info.GetRange ().GetRangeBase ();
2654*af245d11STodd Fiala 
2655*af245d11STodd Fiala         // If the target address comes before this entry, indicate distance to next region.
2656*af245d11STodd Fiala         if (load_addr < proc_entry_info.GetRange ().GetRangeBase ())
2657*af245d11STodd Fiala         {
2658*af245d11STodd Fiala             range_info.GetRange ().SetRangeBase (load_addr);
2659*af245d11STodd Fiala             range_info.GetRange ().SetByteSize (proc_entry_info.GetRange ().GetRangeBase () - load_addr);
2660*af245d11STodd Fiala             range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo);
2661*af245d11STodd Fiala             range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo);
2662*af245d11STodd Fiala             range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo);
2663*af245d11STodd Fiala 
2664*af245d11STodd Fiala             return error;
2665*af245d11STodd Fiala         }
2666*af245d11STodd Fiala         else if (proc_entry_info.GetRange ().Contains (load_addr))
2667*af245d11STodd Fiala         {
2668*af245d11STodd Fiala             // The target address is within the memory region we're processing here.
2669*af245d11STodd Fiala             range_info = proc_entry_info;
2670*af245d11STodd Fiala             return error;
2671*af245d11STodd Fiala         }
2672*af245d11STodd Fiala 
2673*af245d11STodd Fiala         // The target memory address comes somewhere after the region we just parsed.
2674*af245d11STodd Fiala     }
2675*af245d11STodd Fiala 
2676*af245d11STodd Fiala     // If we made it here, we didn't find an entry that contained the given address.
2677*af245d11STodd Fiala     error.SetErrorString ("address comes after final region");
2678*af245d11STodd Fiala 
2679*af245d11STodd Fiala     if (log)
2680*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s failed to find map entry for address 0x%" PRIx64 ": %s", __FUNCTION__, load_addr, error.AsCString ());
2681*af245d11STodd Fiala 
2682*af245d11STodd Fiala     return error;
2683*af245d11STodd Fiala }
2684*af245d11STodd Fiala 
2685*af245d11STodd Fiala void
2686*af245d11STodd Fiala NativeProcessLinux::DoStopIDBumped (uint32_t newBumpId)
2687*af245d11STodd Fiala {
2688*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2689*af245d11STodd Fiala     if (log)
2690*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called", __FUNCTION__, newBumpId);
2691*af245d11STodd Fiala 
2692*af245d11STodd Fiala     {
2693*af245d11STodd Fiala         Mutex::Locker locker (m_mem_region_cache_mutex);
2694*af245d11STodd Fiala         if (log)
2695*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s clearing %" PRIu64 " entries from the cache", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()));
2696*af245d11STodd Fiala         m_mem_region_cache.clear ();
2697*af245d11STodd Fiala     }
2698*af245d11STodd Fiala }
2699*af245d11STodd Fiala 
2700*af245d11STodd Fiala Error
2701*af245d11STodd Fiala NativeProcessLinux::AllocateMemory (
2702*af245d11STodd Fiala     lldb::addr_t size,
2703*af245d11STodd Fiala     uint32_t permissions,
2704*af245d11STodd Fiala     lldb::addr_t &addr)
2705*af245d11STodd Fiala {
2706*af245d11STodd Fiala     // FIXME implementing this requires the equivalent of
2707*af245d11STodd Fiala     // InferiorCallPOSIX::InferiorCallMmap, which depends on
2708*af245d11STodd Fiala     // functional ThreadPlans working with Native*Protocol.
2709*af245d11STodd Fiala #if 1
2710*af245d11STodd Fiala     return Error ("not implemented yet");
2711*af245d11STodd Fiala #else
2712*af245d11STodd Fiala     addr = LLDB_INVALID_ADDRESS;
2713*af245d11STodd Fiala 
2714*af245d11STodd Fiala     unsigned prot = 0;
2715*af245d11STodd Fiala     if (permissions & lldb::ePermissionsReadable)
2716*af245d11STodd Fiala         prot |= eMmapProtRead;
2717*af245d11STodd Fiala     if (permissions & lldb::ePermissionsWritable)
2718*af245d11STodd Fiala         prot |= eMmapProtWrite;
2719*af245d11STodd Fiala     if (permissions & lldb::ePermissionsExecutable)
2720*af245d11STodd Fiala         prot |= eMmapProtExec;
2721*af245d11STodd Fiala 
2722*af245d11STodd Fiala     // TODO implement this directly in NativeProcessLinux
2723*af245d11STodd Fiala     // (and lift to NativeProcessPOSIX if/when that class is
2724*af245d11STodd Fiala     // refactored out).
2725*af245d11STodd Fiala     if (InferiorCallMmap(this, addr, 0, size, prot,
2726*af245d11STodd Fiala                          eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
2727*af245d11STodd Fiala         m_addr_to_mmap_size[addr] = size;
2728*af245d11STodd Fiala         return Error ();
2729*af245d11STodd Fiala     } else {
2730*af245d11STodd Fiala         addr = LLDB_INVALID_ADDRESS;
2731*af245d11STodd Fiala         return Error("unable to allocate %" PRIu64 " bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
2732*af245d11STodd Fiala     }
2733*af245d11STodd Fiala #endif
2734*af245d11STodd Fiala }
2735*af245d11STodd Fiala 
2736*af245d11STodd Fiala Error
2737*af245d11STodd Fiala NativeProcessLinux::DeallocateMemory (lldb::addr_t addr)
2738*af245d11STodd Fiala {
2739*af245d11STodd Fiala     // FIXME see comments in AllocateMemory - required lower-level
2740*af245d11STodd Fiala     // bits not in place yet (ThreadPlans)
2741*af245d11STodd Fiala     return Error ("not implemented");
2742*af245d11STodd Fiala }
2743*af245d11STodd Fiala 
2744*af245d11STodd Fiala lldb::addr_t
2745*af245d11STodd Fiala NativeProcessLinux::GetSharedLibraryInfoAddress ()
2746*af245d11STodd Fiala {
2747*af245d11STodd Fiala #if 1
2748*af245d11STodd Fiala     // punt on this for now
2749*af245d11STodd Fiala     return LLDB_INVALID_ADDRESS;
2750*af245d11STodd Fiala #else
2751*af245d11STodd Fiala     // Return the image info address for the exe module
2752*af245d11STodd Fiala #if 1
2753*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2754*af245d11STodd Fiala 
2755*af245d11STodd Fiala     ModuleSP module_sp;
2756*af245d11STodd Fiala     Error error = GetExeModuleSP (module_sp);
2757*af245d11STodd Fiala     if (error.Fail ())
2758*af245d11STodd Fiala     {
2759*af245d11STodd Fiala          if (log)
2760*af245d11STodd Fiala             log->Warning ("NativeProcessLinux::%s failed to retrieve exe module: %s", __FUNCTION__, error.AsCString ());
2761*af245d11STodd Fiala         return LLDB_INVALID_ADDRESS;
2762*af245d11STodd Fiala     }
2763*af245d11STodd Fiala 
2764*af245d11STodd Fiala     if (module_sp == nullptr)
2765*af245d11STodd Fiala     {
2766*af245d11STodd Fiala          if (log)
2767*af245d11STodd Fiala             log->Warning ("NativeProcessLinux::%s exe module returned was NULL", __FUNCTION__);
2768*af245d11STodd Fiala          return LLDB_INVALID_ADDRESS;
2769*af245d11STodd Fiala     }
2770*af245d11STodd Fiala 
2771*af245d11STodd Fiala     ObjectFileSP object_file_sp = module_sp->GetObjectFile ();
2772*af245d11STodd Fiala     if (object_file_sp == nullptr)
2773*af245d11STodd Fiala     {
2774*af245d11STodd Fiala          if (log)
2775*af245d11STodd Fiala             log->Warning ("NativeProcessLinux::%s exe module returned a NULL object file", __FUNCTION__);
2776*af245d11STodd Fiala          return LLDB_INVALID_ADDRESS;
2777*af245d11STodd Fiala     }
2778*af245d11STodd Fiala 
2779*af245d11STodd Fiala     return obj_file_sp->GetImageInfoAddress();
2780*af245d11STodd Fiala #else
2781*af245d11STodd Fiala     Target *target = &GetTarget();
2782*af245d11STodd Fiala     ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
2783*af245d11STodd Fiala     Address addr = obj_file->GetImageInfoAddress(target);
2784*af245d11STodd Fiala 
2785*af245d11STodd Fiala     if (addr.IsValid())
2786*af245d11STodd Fiala         return addr.GetLoadAddress(target);
2787*af245d11STodd Fiala     return LLDB_INVALID_ADDRESS;
2788*af245d11STodd Fiala #endif
2789*af245d11STodd Fiala #endif // punt on this for now
2790*af245d11STodd Fiala }
2791*af245d11STodd Fiala 
2792*af245d11STodd Fiala size_t
2793*af245d11STodd Fiala NativeProcessLinux::UpdateThreads ()
2794*af245d11STodd Fiala {
2795*af245d11STodd Fiala     // The NativeProcessLinux monitoring threads are always up to date
2796*af245d11STodd Fiala     // with respect to thread state and they keep the thread list
2797*af245d11STodd Fiala     // populated properly. All this method needs to do is return the
2798*af245d11STodd Fiala     // thread count.
2799*af245d11STodd Fiala     Mutex::Locker locker (m_threads_mutex);
2800*af245d11STodd Fiala     return m_threads.size ();
2801*af245d11STodd Fiala }
2802*af245d11STodd Fiala 
2803*af245d11STodd Fiala bool
2804*af245d11STodd Fiala NativeProcessLinux::GetArchitecture (ArchSpec &arch) const
2805*af245d11STodd Fiala {
2806*af245d11STodd Fiala     arch = m_arch;
2807*af245d11STodd Fiala     return true;
2808*af245d11STodd Fiala }
2809*af245d11STodd Fiala 
2810*af245d11STodd Fiala Error
2811*af245d11STodd Fiala NativeProcessLinux::GetSoftwareBreakpointSize (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size)
2812*af245d11STodd Fiala {
2813*af245d11STodd Fiala     // FIXME put this behind a breakpoint protocol class that can be
2814*af245d11STodd Fiala     // set per architecture.  Need ARM, MIPS support here.
2815*af245d11STodd Fiala     static const uint8_t g_i386_opcode [] = { 0xCC };
2816*af245d11STodd Fiala 
2817*af245d11STodd Fiala     switch (m_arch.GetMachine ())
2818*af245d11STodd Fiala     {
2819*af245d11STodd Fiala         case llvm::Triple::x86:
2820*af245d11STodd Fiala         case llvm::Triple::x86_64:
2821*af245d11STodd Fiala             actual_opcode_size = static_cast<uint32_t> (sizeof(g_i386_opcode));
2822*af245d11STodd Fiala             return Error ();
2823*af245d11STodd Fiala 
2824*af245d11STodd Fiala         default:
2825*af245d11STodd Fiala             assert(false && "CPU type not supported!");
2826*af245d11STodd Fiala             return Error ("CPU type not supported");
2827*af245d11STodd Fiala     }
2828*af245d11STodd Fiala }
2829*af245d11STodd Fiala 
2830*af245d11STodd Fiala Error
2831*af245d11STodd Fiala NativeProcessLinux::SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware)
2832*af245d11STodd Fiala {
2833*af245d11STodd Fiala     if (hardware)
2834*af245d11STodd Fiala         return Error ("NativeProcessLinux does not support hardware breakpoints");
2835*af245d11STodd Fiala     else
2836*af245d11STodd Fiala         return SetSoftwareBreakpoint (addr, size);
2837*af245d11STodd Fiala }
2838*af245d11STodd Fiala 
2839*af245d11STodd Fiala Error
2840*af245d11STodd Fiala NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes)
2841*af245d11STodd Fiala {
2842*af245d11STodd Fiala     // FIXME put this behind a breakpoint protocol class that can be
2843*af245d11STodd Fiala     // set per architecture.  Need ARM, MIPS support here.
2844*af245d11STodd Fiala     static const uint8_t g_i386_opcode [] = { 0xCC };
2845*af245d11STodd Fiala 
2846*af245d11STodd Fiala     switch (m_arch.GetMachine ())
2847*af245d11STodd Fiala     {
2848*af245d11STodd Fiala     case llvm::Triple::x86:
2849*af245d11STodd Fiala     case llvm::Triple::x86_64:
2850*af245d11STodd Fiala         trap_opcode_bytes = g_i386_opcode;
2851*af245d11STodd Fiala         actual_opcode_size = sizeof(g_i386_opcode);
2852*af245d11STodd Fiala         return Error ();
2853*af245d11STodd Fiala 
2854*af245d11STodd Fiala     default:
2855*af245d11STodd Fiala         assert(false && "CPU type not supported!");
2856*af245d11STodd Fiala         return Error ("CPU type not supported");
2857*af245d11STodd Fiala     }
2858*af245d11STodd Fiala }
2859*af245d11STodd Fiala 
2860*af245d11STodd Fiala #if 0
2861*af245d11STodd Fiala ProcessMessage::CrashReason
2862*af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGSEGV(const siginfo_t *info)
2863*af245d11STodd Fiala {
2864*af245d11STodd Fiala     ProcessMessage::CrashReason reason;
2865*af245d11STodd Fiala     assert(info->si_signo == SIGSEGV);
2866*af245d11STodd Fiala 
2867*af245d11STodd Fiala     reason = ProcessMessage::eInvalidCrashReason;
2868*af245d11STodd Fiala 
2869*af245d11STodd Fiala     switch (info->si_code)
2870*af245d11STodd Fiala     {
2871*af245d11STodd Fiala     default:
2872*af245d11STodd Fiala         assert(false && "unexpected si_code for SIGSEGV");
2873*af245d11STodd Fiala         break;
2874*af245d11STodd Fiala     case SI_KERNEL:
2875*af245d11STodd Fiala         // Linux will occasionally send spurious SI_KERNEL codes.
2876*af245d11STodd Fiala         // (this is poorly documented in sigaction)
2877*af245d11STodd Fiala         // One way to get this is via unaligned SIMD loads.
2878*af245d11STodd Fiala         reason = ProcessMessage::eInvalidAddress; // for lack of anything better
2879*af245d11STodd Fiala         break;
2880*af245d11STodd Fiala     case SEGV_MAPERR:
2881*af245d11STodd Fiala         reason = ProcessMessage::eInvalidAddress;
2882*af245d11STodd Fiala         break;
2883*af245d11STodd Fiala     case SEGV_ACCERR:
2884*af245d11STodd Fiala         reason = ProcessMessage::ePrivilegedAddress;
2885*af245d11STodd Fiala         break;
2886*af245d11STodd Fiala     }
2887*af245d11STodd Fiala 
2888*af245d11STodd Fiala     return reason;
2889*af245d11STodd Fiala }
2890*af245d11STodd Fiala #endif
2891*af245d11STodd Fiala 
2892*af245d11STodd Fiala 
2893*af245d11STodd Fiala #if 0
2894*af245d11STodd Fiala ProcessMessage::CrashReason
2895*af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGILL(const siginfo_t *info)
2896*af245d11STodd Fiala {
2897*af245d11STodd Fiala     ProcessMessage::CrashReason reason;
2898*af245d11STodd Fiala     assert(info->si_signo == SIGILL);
2899*af245d11STodd Fiala 
2900*af245d11STodd Fiala     reason = ProcessMessage::eInvalidCrashReason;
2901*af245d11STodd Fiala 
2902*af245d11STodd Fiala     switch (info->si_code)
2903*af245d11STodd Fiala     {
2904*af245d11STodd Fiala     default:
2905*af245d11STodd Fiala         assert(false && "unexpected si_code for SIGILL");
2906*af245d11STodd Fiala         break;
2907*af245d11STodd Fiala     case ILL_ILLOPC:
2908*af245d11STodd Fiala         reason = ProcessMessage::eIllegalOpcode;
2909*af245d11STodd Fiala         break;
2910*af245d11STodd Fiala     case ILL_ILLOPN:
2911*af245d11STodd Fiala         reason = ProcessMessage::eIllegalOperand;
2912*af245d11STodd Fiala         break;
2913*af245d11STodd Fiala     case ILL_ILLADR:
2914*af245d11STodd Fiala         reason = ProcessMessage::eIllegalAddressingMode;
2915*af245d11STodd Fiala         break;
2916*af245d11STodd Fiala     case ILL_ILLTRP:
2917*af245d11STodd Fiala         reason = ProcessMessage::eIllegalTrap;
2918*af245d11STodd Fiala         break;
2919*af245d11STodd Fiala     case ILL_PRVOPC:
2920*af245d11STodd Fiala         reason = ProcessMessage::ePrivilegedOpcode;
2921*af245d11STodd Fiala         break;
2922*af245d11STodd Fiala     case ILL_PRVREG:
2923*af245d11STodd Fiala         reason = ProcessMessage::ePrivilegedRegister;
2924*af245d11STodd Fiala         break;
2925*af245d11STodd Fiala     case ILL_COPROC:
2926*af245d11STodd Fiala         reason = ProcessMessage::eCoprocessorError;
2927*af245d11STodd Fiala         break;
2928*af245d11STodd Fiala     case ILL_BADSTK:
2929*af245d11STodd Fiala         reason = ProcessMessage::eInternalStackError;
2930*af245d11STodd Fiala         break;
2931*af245d11STodd Fiala     }
2932*af245d11STodd Fiala 
2933*af245d11STodd Fiala     return reason;
2934*af245d11STodd Fiala }
2935*af245d11STodd Fiala #endif
2936*af245d11STodd Fiala 
2937*af245d11STodd Fiala #if 0
2938*af245d11STodd Fiala ProcessMessage::CrashReason
2939*af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGFPE(const siginfo_t *info)
2940*af245d11STodd Fiala {
2941*af245d11STodd Fiala     ProcessMessage::CrashReason reason;
2942*af245d11STodd Fiala     assert(info->si_signo == SIGFPE);
2943*af245d11STodd Fiala 
2944*af245d11STodd Fiala     reason = ProcessMessage::eInvalidCrashReason;
2945*af245d11STodd Fiala 
2946*af245d11STodd Fiala     switch (info->si_code)
2947*af245d11STodd Fiala     {
2948*af245d11STodd Fiala     default:
2949*af245d11STodd Fiala         assert(false && "unexpected si_code for SIGFPE");
2950*af245d11STodd Fiala         break;
2951*af245d11STodd Fiala     case FPE_INTDIV:
2952*af245d11STodd Fiala         reason = ProcessMessage::eIntegerDivideByZero;
2953*af245d11STodd Fiala         break;
2954*af245d11STodd Fiala     case FPE_INTOVF:
2955*af245d11STodd Fiala         reason = ProcessMessage::eIntegerOverflow;
2956*af245d11STodd Fiala         break;
2957*af245d11STodd Fiala     case FPE_FLTDIV:
2958*af245d11STodd Fiala         reason = ProcessMessage::eFloatDivideByZero;
2959*af245d11STodd Fiala         break;
2960*af245d11STodd Fiala     case FPE_FLTOVF:
2961*af245d11STodd Fiala         reason = ProcessMessage::eFloatOverflow;
2962*af245d11STodd Fiala         break;
2963*af245d11STodd Fiala     case FPE_FLTUND:
2964*af245d11STodd Fiala         reason = ProcessMessage::eFloatUnderflow;
2965*af245d11STodd Fiala         break;
2966*af245d11STodd Fiala     case FPE_FLTRES:
2967*af245d11STodd Fiala         reason = ProcessMessage::eFloatInexactResult;
2968*af245d11STodd Fiala         break;
2969*af245d11STodd Fiala     case FPE_FLTINV:
2970*af245d11STodd Fiala         reason = ProcessMessage::eFloatInvalidOperation;
2971*af245d11STodd Fiala         break;
2972*af245d11STodd Fiala     case FPE_FLTSUB:
2973*af245d11STodd Fiala         reason = ProcessMessage::eFloatSubscriptRange;
2974*af245d11STodd Fiala         break;
2975*af245d11STodd Fiala     }
2976*af245d11STodd Fiala 
2977*af245d11STodd Fiala     return reason;
2978*af245d11STodd Fiala }
2979*af245d11STodd Fiala #endif
2980*af245d11STodd Fiala 
2981*af245d11STodd Fiala #if 0
2982*af245d11STodd Fiala ProcessMessage::CrashReason
2983*af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info)
2984*af245d11STodd Fiala {
2985*af245d11STodd Fiala     ProcessMessage::CrashReason reason;
2986*af245d11STodd Fiala     assert(info->si_signo == SIGBUS);
2987*af245d11STodd Fiala 
2988*af245d11STodd Fiala     reason = ProcessMessage::eInvalidCrashReason;
2989*af245d11STodd Fiala 
2990*af245d11STodd Fiala     switch (info->si_code)
2991*af245d11STodd Fiala     {
2992*af245d11STodd Fiala     default:
2993*af245d11STodd Fiala         assert(false && "unexpected si_code for SIGBUS");
2994*af245d11STodd Fiala         break;
2995*af245d11STodd Fiala     case BUS_ADRALN:
2996*af245d11STodd Fiala         reason = ProcessMessage::eIllegalAlignment;
2997*af245d11STodd Fiala         break;
2998*af245d11STodd Fiala     case BUS_ADRERR:
2999*af245d11STodd Fiala         reason = ProcessMessage::eIllegalAddress;
3000*af245d11STodd Fiala         break;
3001*af245d11STodd Fiala     case BUS_OBJERR:
3002*af245d11STodd Fiala         reason = ProcessMessage::eHardwareError;
3003*af245d11STodd Fiala         break;
3004*af245d11STodd Fiala     }
3005*af245d11STodd Fiala 
3006*af245d11STodd Fiala     return reason;
3007*af245d11STodd Fiala }
3008*af245d11STodd Fiala #endif
3009*af245d11STodd Fiala 
3010*af245d11STodd Fiala void
3011*af245d11STodd Fiala NativeProcessLinux::ServeOperation(OperationArgs *args)
3012*af245d11STodd Fiala {
3013*af245d11STodd Fiala     NativeProcessLinux *monitor = args->m_monitor;
3014*af245d11STodd Fiala 
3015*af245d11STodd Fiala     // We are finised with the arguments and are ready to go.  Sync with the
3016*af245d11STodd Fiala     // parent thread and start serving operations on the inferior.
3017*af245d11STodd Fiala     sem_post(&args->m_semaphore);
3018*af245d11STodd Fiala 
3019*af245d11STodd Fiala     for(;;)
3020*af245d11STodd Fiala     {
3021*af245d11STodd Fiala         // wait for next pending operation
3022*af245d11STodd Fiala         if (sem_wait(&monitor->m_operation_pending))
3023*af245d11STodd Fiala         {
3024*af245d11STodd Fiala             if (errno == EINTR)
3025*af245d11STodd Fiala                 continue;
3026*af245d11STodd Fiala             assert(false && "Unexpected errno from sem_wait");
3027*af245d11STodd Fiala         }
3028*af245d11STodd Fiala 
3029*af245d11STodd Fiala         reinterpret_cast<Operation*>(monitor->m_operation)->Execute(monitor);
3030*af245d11STodd Fiala 
3031*af245d11STodd Fiala         // notify calling thread that operation is complete
3032*af245d11STodd Fiala         sem_post(&monitor->m_operation_done);
3033*af245d11STodd Fiala     }
3034*af245d11STodd Fiala }
3035*af245d11STodd Fiala 
3036*af245d11STodd Fiala void
3037*af245d11STodd Fiala NativeProcessLinux::DoOperation(void *op)
3038*af245d11STodd Fiala {
3039*af245d11STodd Fiala     Mutex::Locker lock(m_operation_mutex);
3040*af245d11STodd Fiala 
3041*af245d11STodd Fiala     m_operation = op;
3042*af245d11STodd Fiala 
3043*af245d11STodd Fiala     // notify operation thread that an operation is ready to be processed
3044*af245d11STodd Fiala     sem_post(&m_operation_pending);
3045*af245d11STodd Fiala 
3046*af245d11STodd Fiala     // wait for operation to complete
3047*af245d11STodd Fiala     while (sem_wait(&m_operation_done))
3048*af245d11STodd Fiala     {
3049*af245d11STodd Fiala         if (errno == EINTR)
3050*af245d11STodd Fiala             continue;
3051*af245d11STodd Fiala         assert(false && "Unexpected errno from sem_wait");
3052*af245d11STodd Fiala     }
3053*af245d11STodd Fiala }
3054*af245d11STodd Fiala 
3055*af245d11STodd Fiala Error
3056*af245d11STodd Fiala NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read)
3057*af245d11STodd Fiala {
3058*af245d11STodd Fiala     ReadOperation op(addr, buf, size, bytes_read);
3059*af245d11STodd Fiala     DoOperation(&op);
3060*af245d11STodd Fiala     return op.GetError ();
3061*af245d11STodd Fiala }
3062*af245d11STodd Fiala 
3063*af245d11STodd Fiala Error
3064*af245d11STodd Fiala NativeProcessLinux::WriteMemory (lldb::addr_t addr, const void *buf, lldb::addr_t size, lldb::addr_t &bytes_written)
3065*af245d11STodd Fiala {
3066*af245d11STodd Fiala     WriteOperation op(addr, buf, size, bytes_written);
3067*af245d11STodd Fiala     DoOperation(&op);
3068*af245d11STodd Fiala     return op.GetError ();
3069*af245d11STodd Fiala }
3070*af245d11STodd Fiala 
3071*af245d11STodd Fiala bool
3072*af245d11STodd Fiala NativeProcessLinux::ReadRegisterValue(lldb::tid_t tid, uint32_t offset, const char* reg_name,
3073*af245d11STodd Fiala                                   uint32_t size, RegisterValue &value)
3074*af245d11STodd Fiala {
3075*af245d11STodd Fiala     bool result;
3076*af245d11STodd Fiala     ReadRegOperation op(tid, offset, reg_name, value, result);
3077*af245d11STodd Fiala     DoOperation(&op);
3078*af245d11STodd Fiala     return result;
3079*af245d11STodd Fiala }
3080*af245d11STodd Fiala 
3081*af245d11STodd Fiala bool
3082*af245d11STodd Fiala NativeProcessLinux::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
3083*af245d11STodd Fiala                                    const char* reg_name, const RegisterValue &value)
3084*af245d11STodd Fiala {
3085*af245d11STodd Fiala     bool result;
3086*af245d11STodd Fiala     WriteRegOperation op(tid, offset, reg_name, value, result);
3087*af245d11STodd Fiala     DoOperation(&op);
3088*af245d11STodd Fiala     return result;
3089*af245d11STodd Fiala }
3090*af245d11STodd Fiala 
3091*af245d11STodd Fiala bool
3092*af245d11STodd Fiala NativeProcessLinux::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
3093*af245d11STodd Fiala {
3094*af245d11STodd Fiala     bool result;
3095*af245d11STodd Fiala     ReadGPROperation op(tid, buf, buf_size, result);
3096*af245d11STodd Fiala     DoOperation(&op);
3097*af245d11STodd Fiala     return result;
3098*af245d11STodd Fiala }
3099*af245d11STodd Fiala 
3100*af245d11STodd Fiala bool
3101*af245d11STodd Fiala NativeProcessLinux::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
3102*af245d11STodd Fiala {
3103*af245d11STodd Fiala     bool result;
3104*af245d11STodd Fiala     ReadFPROperation op(tid, buf, buf_size, result);
3105*af245d11STodd Fiala     DoOperation(&op);
3106*af245d11STodd Fiala     return result;
3107*af245d11STodd Fiala }
3108*af245d11STodd Fiala 
3109*af245d11STodd Fiala bool
3110*af245d11STodd Fiala NativeProcessLinux::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
3111*af245d11STodd Fiala {
3112*af245d11STodd Fiala     bool result;
3113*af245d11STodd Fiala     ReadRegisterSetOperation op(tid, buf, buf_size, regset, result);
3114*af245d11STodd Fiala     DoOperation(&op);
3115*af245d11STodd Fiala     return result;
3116*af245d11STodd Fiala }
3117*af245d11STodd Fiala 
3118*af245d11STodd Fiala bool
3119*af245d11STodd Fiala NativeProcessLinux::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
3120*af245d11STodd Fiala {
3121*af245d11STodd Fiala     bool result;
3122*af245d11STodd Fiala     WriteGPROperation op(tid, buf, buf_size, result);
3123*af245d11STodd Fiala     DoOperation(&op);
3124*af245d11STodd Fiala     return result;
3125*af245d11STodd Fiala }
3126*af245d11STodd Fiala 
3127*af245d11STodd Fiala bool
3128*af245d11STodd Fiala NativeProcessLinux::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
3129*af245d11STodd Fiala {
3130*af245d11STodd Fiala     bool result;
3131*af245d11STodd Fiala     WriteFPROperation op(tid, buf, buf_size, result);
3132*af245d11STodd Fiala     DoOperation(&op);
3133*af245d11STodd Fiala     return result;
3134*af245d11STodd Fiala }
3135*af245d11STodd Fiala 
3136*af245d11STodd Fiala bool
3137*af245d11STodd Fiala NativeProcessLinux::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
3138*af245d11STodd Fiala {
3139*af245d11STodd Fiala     bool result;
3140*af245d11STodd Fiala     WriteRegisterSetOperation op(tid, buf, buf_size, regset, result);
3141*af245d11STodd Fiala     DoOperation(&op);
3142*af245d11STodd Fiala     return result;
3143*af245d11STodd Fiala }
3144*af245d11STodd Fiala 
3145*af245d11STodd Fiala bool
3146*af245d11STodd Fiala NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo)
3147*af245d11STodd Fiala {
3148*af245d11STodd Fiala     bool result;
3149*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
3150*af245d11STodd Fiala 
3151*af245d11STodd Fiala     if (log)
3152*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s() resuming thread = %"  PRIu64 " with signal %s", __FUNCTION__, tid,
3153*af245d11STodd Fiala                                  GetUnixSignals().GetSignalAsCString (signo));
3154*af245d11STodd Fiala     ResumeOperation op (tid, signo, result);
3155*af245d11STodd Fiala     DoOperation (&op);
3156*af245d11STodd Fiala     if (log)
3157*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
3158*af245d11STodd Fiala     return result;
3159*af245d11STodd Fiala }
3160*af245d11STodd Fiala 
3161*af245d11STodd Fiala bool
3162*af245d11STodd Fiala NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo)
3163*af245d11STodd Fiala {
3164*af245d11STodd Fiala     bool result;
3165*af245d11STodd Fiala     SingleStepOperation op(tid, signo, result);
3166*af245d11STodd Fiala     DoOperation(&op);
3167*af245d11STodd Fiala     return result;
3168*af245d11STodd Fiala }
3169*af245d11STodd Fiala 
3170*af245d11STodd Fiala bool
3171*af245d11STodd Fiala NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err)
3172*af245d11STodd Fiala {
3173*af245d11STodd Fiala     bool result;
3174*af245d11STodd Fiala     SiginfoOperation op(tid, siginfo, result, ptrace_err);
3175*af245d11STodd Fiala     DoOperation(&op);
3176*af245d11STodd Fiala     return result;
3177*af245d11STodd Fiala }
3178*af245d11STodd Fiala 
3179*af245d11STodd Fiala bool
3180*af245d11STodd Fiala NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message)
3181*af245d11STodd Fiala {
3182*af245d11STodd Fiala     bool result;
3183*af245d11STodd Fiala     EventMessageOperation op(tid, message, result);
3184*af245d11STodd Fiala     DoOperation(&op);
3185*af245d11STodd Fiala     return result;
3186*af245d11STodd Fiala }
3187*af245d11STodd Fiala 
3188*af245d11STodd Fiala lldb_private::Error
3189*af245d11STodd Fiala NativeProcessLinux::Detach(lldb::tid_t tid)
3190*af245d11STodd Fiala {
3191*af245d11STodd Fiala     lldb_private::Error error;
3192*af245d11STodd Fiala     if (tid != LLDB_INVALID_THREAD_ID)
3193*af245d11STodd Fiala     {
3194*af245d11STodd Fiala         DetachOperation op(tid, error);
3195*af245d11STodd Fiala         DoOperation(&op);
3196*af245d11STodd Fiala     }
3197*af245d11STodd Fiala     return error;
3198*af245d11STodd Fiala }
3199*af245d11STodd Fiala 
3200*af245d11STodd Fiala bool
3201*af245d11STodd Fiala NativeProcessLinux::DupDescriptor(const char *path, int fd, int flags)
3202*af245d11STodd Fiala {
3203*af245d11STodd Fiala     int target_fd = open(path, flags, 0666);
3204*af245d11STodd Fiala 
3205*af245d11STodd Fiala     if (target_fd == -1)
3206*af245d11STodd Fiala         return false;
3207*af245d11STodd Fiala 
3208*af245d11STodd Fiala     return (dup2(target_fd, fd) == -1) ? false : true;
3209*af245d11STodd Fiala }
3210*af245d11STodd Fiala 
3211*af245d11STodd Fiala void
3212*af245d11STodd Fiala NativeProcessLinux::StopMonitoringChildProcess()
3213*af245d11STodd Fiala {
3214*af245d11STodd Fiala     lldb::thread_result_t thread_result;
3215*af245d11STodd Fiala 
3216*af245d11STodd Fiala     if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread))
3217*af245d11STodd Fiala     {
3218*af245d11STodd Fiala         Host::ThreadCancel(m_monitor_thread, NULL);
3219*af245d11STodd Fiala         Host::ThreadJoin(m_monitor_thread, &thread_result, NULL);
3220*af245d11STodd Fiala         m_monitor_thread = LLDB_INVALID_HOST_THREAD;
3221*af245d11STodd Fiala     }
3222*af245d11STodd Fiala }
3223*af245d11STodd Fiala 
3224*af245d11STodd Fiala void
3225*af245d11STodd Fiala NativeProcessLinux::StopMonitor()
3226*af245d11STodd Fiala {
3227*af245d11STodd Fiala     StopMonitoringChildProcess();
3228*af245d11STodd Fiala     StopOpThread();
3229*af245d11STodd Fiala     sem_destroy(&m_operation_pending);
3230*af245d11STodd Fiala     sem_destroy(&m_operation_done);
3231*af245d11STodd Fiala 
3232*af245d11STodd Fiala     // TODO: validate whether this still holds, fix up comment.
3233*af245d11STodd Fiala     // Note: ProcessPOSIX passes the m_terminal_fd file descriptor to
3234*af245d11STodd Fiala     // Process::SetSTDIOFileDescriptor, which in turn transfers ownership of
3235*af245d11STodd Fiala     // the descriptor to a ConnectionFileDescriptor object.  Consequently
3236*af245d11STodd Fiala     // even though still has the file descriptor, we shouldn't close it here.
3237*af245d11STodd Fiala }
3238*af245d11STodd Fiala 
3239*af245d11STodd Fiala void
3240*af245d11STodd Fiala NativeProcessLinux::StopOpThread()
3241*af245d11STodd Fiala {
3242*af245d11STodd Fiala     lldb::thread_result_t result;
3243*af245d11STodd Fiala 
3244*af245d11STodd Fiala     if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
3245*af245d11STodd Fiala         return;
3246*af245d11STodd Fiala 
3247*af245d11STodd Fiala     Host::ThreadCancel(m_operation_thread, NULL);
3248*af245d11STodd Fiala     Host::ThreadJoin(m_operation_thread, &result, NULL);
3249*af245d11STodd Fiala     m_operation_thread = LLDB_INVALID_HOST_THREAD;
3250*af245d11STodd Fiala }
3251*af245d11STodd Fiala 
3252*af245d11STodd Fiala bool
3253*af245d11STodd Fiala NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id)
3254*af245d11STodd Fiala {
3255*af245d11STodd Fiala     for (auto thread_sp : m_threads)
3256*af245d11STodd Fiala     {
3257*af245d11STodd Fiala         assert (thread_sp && "thread list should not contain NULL threads");
3258*af245d11STodd Fiala         if (thread_sp->GetID () == thread_id)
3259*af245d11STodd Fiala         {
3260*af245d11STodd Fiala             // We have this thread.
3261*af245d11STodd Fiala             return true;
3262*af245d11STodd Fiala         }
3263*af245d11STodd Fiala     }
3264*af245d11STodd Fiala 
3265*af245d11STodd Fiala     // We don't have this thread.
3266*af245d11STodd Fiala     return false;
3267*af245d11STodd Fiala }
3268*af245d11STodd Fiala 
3269*af245d11STodd Fiala NativeThreadProtocolSP
3270*af245d11STodd Fiala NativeProcessLinux::MaybeGetThreadNoLock (lldb::tid_t thread_id)
3271*af245d11STodd Fiala {
3272*af245d11STodd Fiala     // CONSIDER organize threads by map - we can do better than linear.
3273*af245d11STodd Fiala     for (auto thread_sp : m_threads)
3274*af245d11STodd Fiala     {
3275*af245d11STodd Fiala         if (thread_sp->GetID () == thread_id)
3276*af245d11STodd Fiala             return thread_sp;
3277*af245d11STodd Fiala     }
3278*af245d11STodd Fiala 
3279*af245d11STodd Fiala     // We don't have this thread.
3280*af245d11STodd Fiala     return NativeThreadProtocolSP ();
3281*af245d11STodd Fiala }
3282*af245d11STodd Fiala 
3283*af245d11STodd Fiala bool
3284*af245d11STodd Fiala NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id)
3285*af245d11STodd Fiala {
3286*af245d11STodd Fiala     Mutex::Locker locker (m_threads_mutex);
3287*af245d11STodd Fiala     for (auto it = m_threads.begin (); it != m_threads.end (); ++it)
3288*af245d11STodd Fiala     {
3289*af245d11STodd Fiala         if (*it && ((*it)->GetID () == thread_id))
3290*af245d11STodd Fiala         {
3291*af245d11STodd Fiala             m_threads.erase (it);
3292*af245d11STodd Fiala             return true;
3293*af245d11STodd Fiala         }
3294*af245d11STodd Fiala     }
3295*af245d11STodd Fiala 
3296*af245d11STodd Fiala     // Didn't find it.
3297*af245d11STodd Fiala     return false;
3298*af245d11STodd Fiala }
3299*af245d11STodd Fiala 
3300*af245d11STodd Fiala NativeThreadProtocolSP
3301*af245d11STodd Fiala NativeProcessLinux::AddThread (lldb::tid_t thread_id)
3302*af245d11STodd Fiala {
3303*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
3304*af245d11STodd Fiala 
3305*af245d11STodd Fiala     Mutex::Locker locker (m_threads_mutex);
3306*af245d11STodd Fiala 
3307*af245d11STodd Fiala     if (log)
3308*af245d11STodd Fiala     {
3309*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " adding thread with tid %" PRIu64,
3310*af245d11STodd Fiala                 __FUNCTION__,
3311*af245d11STodd Fiala                 GetID (),
3312*af245d11STodd Fiala                 thread_id);
3313*af245d11STodd Fiala     }
3314*af245d11STodd Fiala 
3315*af245d11STodd Fiala     assert (!HasThreadNoLock (thread_id) && "attempted to add a thread by id that already exists");
3316*af245d11STodd Fiala 
3317*af245d11STodd Fiala     // If this is the first thread, save it as the current thread
3318*af245d11STodd Fiala     if (m_threads.empty ())
3319*af245d11STodd Fiala         SetCurrentThreadID (thread_id);
3320*af245d11STodd Fiala 
3321*af245d11STodd Fiala     NativeThreadProtocolSP thread_sp (new NativeThreadLinux (this, thread_id));
3322*af245d11STodd Fiala     m_threads.push_back (thread_sp);
3323*af245d11STodd Fiala 
3324*af245d11STodd Fiala     return thread_sp;
3325*af245d11STodd Fiala }
3326*af245d11STodd Fiala 
3327*af245d11STodd Fiala NativeThreadProtocolSP
3328*af245d11STodd Fiala NativeProcessLinux::GetOrCreateThread (lldb::tid_t thread_id, bool &created)
3329*af245d11STodd Fiala {
3330*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
3331*af245d11STodd Fiala 
3332*af245d11STodd Fiala     Mutex::Locker locker (m_threads_mutex);
3333*af245d11STodd Fiala     if (log)
3334*af245d11STodd Fiala     {
3335*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " get/create thread with tid %" PRIu64,
3336*af245d11STodd Fiala                      __FUNCTION__,
3337*af245d11STodd Fiala                      GetID (),
3338*af245d11STodd Fiala                      thread_id);
3339*af245d11STodd Fiala     }
3340*af245d11STodd Fiala 
3341*af245d11STodd Fiala     // Retrieve the thread if it is already getting tracked.
3342*af245d11STodd Fiala     NativeThreadProtocolSP thread_sp = MaybeGetThreadNoLock (thread_id);
3343*af245d11STodd Fiala     if (thread_sp)
3344*af245d11STodd Fiala     {
3345*af245d11STodd Fiala         if (log)
3346*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": thread already tracked, returning",
3347*af245d11STodd Fiala                          __FUNCTION__,
3348*af245d11STodd Fiala                          GetID (),
3349*af245d11STodd Fiala                          thread_id);
3350*af245d11STodd Fiala         created = false;
3351*af245d11STodd Fiala         return thread_sp;
3352*af245d11STodd Fiala 
3353*af245d11STodd Fiala     }
3354*af245d11STodd Fiala 
3355*af245d11STodd Fiala     // Create the thread metadata since it isn't being tracked.
3356*af245d11STodd Fiala     if (log)
3357*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": thread didn't exist, tracking now",
3358*af245d11STodd Fiala                      __FUNCTION__,
3359*af245d11STodd Fiala                      GetID (),
3360*af245d11STodd Fiala                      thread_id);
3361*af245d11STodd Fiala 
3362*af245d11STodd Fiala     thread_sp.reset (new NativeThreadLinux (this, thread_id));
3363*af245d11STodd Fiala     m_threads.push_back (thread_sp);
3364*af245d11STodd Fiala     created = true;
3365*af245d11STodd Fiala 
3366*af245d11STodd Fiala     return thread_sp;
3367*af245d11STodd Fiala }
3368*af245d11STodd Fiala 
3369*af245d11STodd Fiala Error
3370*af245d11STodd Fiala NativeProcessLinux::FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp)
3371*af245d11STodd Fiala {
3372*af245d11STodd Fiala     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
3373*af245d11STodd Fiala 
3374*af245d11STodd Fiala     Error error;
3375*af245d11STodd Fiala 
3376*af245d11STodd Fiala     // Get a linux thread pointer.
3377*af245d11STodd Fiala     if (!thread_sp)
3378*af245d11STodd Fiala     {
3379*af245d11STodd Fiala         error.SetErrorString ("null thread_sp");
3380*af245d11STodd Fiala         if (log)
3381*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
3382*af245d11STodd Fiala         return error;
3383*af245d11STodd Fiala     }
3384*af245d11STodd Fiala     NativeThreadLinux *const linux_thread_p = reinterpret_cast<NativeThreadLinux*> (thread_sp.get());
3385*af245d11STodd Fiala 
3386*af245d11STodd Fiala     // Find out the size of a breakpoint (might depend on where we are in the code).
3387*af245d11STodd Fiala     NativeRegisterContextSP context_sp = linux_thread_p->GetRegisterContext ();
3388*af245d11STodd Fiala     if (!context_sp)
3389*af245d11STodd Fiala     {
3390*af245d11STodd Fiala         error.SetErrorString ("cannot get a NativeRegisterContext for the thread");
3391*af245d11STodd Fiala         if (log)
3392*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
3393*af245d11STodd Fiala         return error;
3394*af245d11STodd Fiala     }
3395*af245d11STodd Fiala 
3396*af245d11STodd Fiala     uint32_t breakpoint_size = 0;
3397*af245d11STodd Fiala     error = GetSoftwareBreakpointSize (context_sp, breakpoint_size);
3398*af245d11STodd Fiala     if (error.Fail ())
3399*af245d11STodd Fiala     {
3400*af245d11STodd Fiala         if (log)
3401*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s GetBreakpointSize() failed: %s", __FUNCTION__, error.AsCString ());
3402*af245d11STodd Fiala         return error;
3403*af245d11STodd Fiala     }
3404*af245d11STodd Fiala     else
3405*af245d11STodd Fiala     {
3406*af245d11STodd Fiala         if (log)
3407*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s breakpoint size: %" PRIu32, __FUNCTION__, breakpoint_size);
3408*af245d11STodd Fiala     }
3409*af245d11STodd Fiala 
3410*af245d11STodd Fiala     // First try probing for a breakpoint at a software breakpoint location: PC - breakpoint size.
3411*af245d11STodd Fiala     const lldb::addr_t initial_pc_addr = context_sp->GetPC ();
3412*af245d11STodd Fiala     lldb::addr_t breakpoint_addr = initial_pc_addr;
3413*af245d11STodd Fiala     if (breakpoint_size > static_cast<lldb::addr_t> (0))
3414*af245d11STodd Fiala     {
3415*af245d11STodd Fiala         // Do not allow breakpoint probe to wrap around.
3416*af245d11STodd Fiala         if (breakpoint_addr >= static_cast<lldb::addr_t> (breakpoint_size))
3417*af245d11STodd Fiala             breakpoint_addr -= static_cast<lldb::addr_t> (breakpoint_size);
3418*af245d11STodd Fiala     }
3419*af245d11STodd Fiala 
3420*af245d11STodd Fiala     // Check if we stopped because of a breakpoint.
3421*af245d11STodd Fiala     NativeBreakpointSP breakpoint_sp;
3422*af245d11STodd Fiala     error = m_breakpoint_list.GetBreakpoint (breakpoint_addr, breakpoint_sp);
3423*af245d11STodd Fiala     if (!error.Success () || !breakpoint_sp)
3424*af245d11STodd Fiala     {
3425*af245d11STodd Fiala         // We didn't find one at a software probe location.  Nothing to do.
3426*af245d11STodd Fiala         if (log)
3427*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64, __FUNCTION__, GetID (), breakpoint_addr);
3428*af245d11STodd Fiala         return Error ();
3429*af245d11STodd Fiala     }
3430*af245d11STodd Fiala 
3431*af245d11STodd Fiala     // If the breakpoint is not a software breakpoint, nothing to do.
3432*af245d11STodd Fiala     if (!breakpoint_sp->IsSoftwareBreakpoint ())
3433*af245d11STodd Fiala     {
3434*af245d11STodd Fiala         if (log)
3435*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", not software, nothing to adjust", __FUNCTION__, GetID (), breakpoint_addr);
3436*af245d11STodd Fiala         return Error ();
3437*af245d11STodd Fiala     }
3438*af245d11STodd Fiala 
3439*af245d11STodd Fiala     //
3440*af245d11STodd Fiala     // We have a software breakpoint and need to adjust the PC.
3441*af245d11STodd Fiala     //
3442*af245d11STodd Fiala 
3443*af245d11STodd Fiala     // Sanity check.
3444*af245d11STodd Fiala     if (breakpoint_size == 0)
3445*af245d11STodd Fiala     {
3446*af245d11STodd Fiala         // Nothing to do!  How did we get here?
3447*af245d11STodd Fiala         if (log)
3448*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", it is software, but the size is zero, nothing to do (unexpected)", __FUNCTION__, GetID (), breakpoint_addr);
3449*af245d11STodd Fiala         return Error ();
3450*af245d11STodd Fiala     }
3451*af245d11STodd Fiala 
3452*af245d11STodd Fiala     // Change the program counter.
3453*af245d11STodd Fiala     if (log)
3454*af245d11STodd Fiala         log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID (), linux_thread_p->GetID (), initial_pc_addr, breakpoint_addr);
3455*af245d11STodd Fiala 
3456*af245d11STodd Fiala     error = context_sp->SetPC (breakpoint_addr);
3457*af245d11STodd Fiala     if (error.Fail ())
3458*af245d11STodd Fiala     {
3459*af245d11STodd Fiala         if (log)
3460*af245d11STodd Fiala             log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID (), linux_thread_p->GetID (), error.AsCString ());
3461*af245d11STodd Fiala         return error;
3462*af245d11STodd Fiala     }
3463*af245d11STodd Fiala 
3464*af245d11STodd Fiala     return error;
3465*af245d11STodd Fiala }
3466