File: | tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp |
Location: | line 2123, column 5 |
Description: | Value stored to 'reason' is never read |
1 | //===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "lldb/lldb-python.h" |
11 | |
12 | // C Includes |
13 | #include <errno(*__errno_location ()).h> |
14 | #include <poll.h> |
15 | #include <string.h> |
16 | #include <stdint.h> |
17 | #include <unistd.h> |
18 | #include <elf.h> |
19 | #if defined(__ANDROID_NDK__) && defined (__arm__) |
20 | #include <linux/personality.h> |
21 | #include <linux/user.h> |
22 | #else |
23 | #include <sys/personality.h> |
24 | #include <sys/user.h> |
25 | #endif |
26 | #ifndef __ANDROID__ |
27 | #include <sys/procfs.h> |
28 | #endif |
29 | #include <sys/ptrace.h> |
30 | #include <sys/uio.h> |
31 | #include <sys/socket.h> |
32 | #include <sys/syscall.h> |
33 | #include <sys/types.h> |
34 | #include <sys/wait.h> |
35 | |
36 | // C++ Includes |
37 | // Other libraries and framework includes |
38 | #include "lldb/Core/Debugger.h" |
39 | #include "lldb/Core/Error.h" |
40 | #include "lldb/Core/RegisterValue.h" |
41 | #include "lldb/Core/Scalar.h" |
42 | #include "lldb/Host/Host.h" |
43 | #include "lldb/Host/HostThread.h" |
44 | #include "lldb/Host/ThreadLauncher.h" |
45 | #include "lldb/Target/Thread.h" |
46 | #include "lldb/Target/RegisterContext.h" |
47 | #include "lldb/Utility/PseudoTerminal.h" |
48 | |
49 | #include "Plugins/Process/POSIX/POSIXThread.h" |
50 | #include "ProcessLinux.h" |
51 | #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" |
52 | #include "ProcessMonitor.h" |
53 | |
54 | #ifdef __ANDROID__ |
55 | #define __ptrace_request int |
56 | #define PT_DETACHPTRACE_DETACH PTRACE_DETACH |
57 | #endif |
58 | |
59 | #define DEBUG_PTRACE_MAXBYTES20 20 |
60 | |
61 | // Support ptrace extensions even when compiled without required kernel support |
62 | #ifndef PTRACE_GETREGSETPTRACE_GETREGSET |
63 | #define PTRACE_GETREGSETPTRACE_GETREGSET 0x4204 |
64 | #endif |
65 | #ifndef PTRACE_SETREGSETPTRACE_SETREGSET |
66 | #define PTRACE_SETREGSETPTRACE_SETREGSET 0x4205 |
67 | #endif |
68 | #ifndef PTRACE_GET_THREAD_AREA25 |
69 | #define PTRACE_GET_THREAD_AREA25 25 |
70 | #endif |
71 | #ifndef PTRACE_ARCH_PRCTL30 |
72 | #define PTRACE_ARCH_PRCTL30 30 |
73 | #endif |
74 | #ifndef ARCH_GET_FS0x1003 |
75 | #define ARCH_SET_GS0x1001 0x1001 |
76 | #define ARCH_SET_FS0x1002 0x1002 |
77 | #define ARCH_GET_FS0x1003 0x1003 |
78 | #define ARCH_GET_GS0x1004 0x1004 |
79 | #endif |
80 | |
81 | #define LLDB_PERSONALITY_GET_CURRENT_SETTINGS0xffffffff 0xffffffff |
82 | |
83 | #define LLDB_PTRACE_NT_ARM_TLS0x401 0x401 // ARM TLS register |
84 | |
85 | // Support hardware breakpoints in case it has not been defined |
86 | #ifndef TRAP_HWBKPT4 |
87 | #define TRAP_HWBKPT4 4 |
88 | #endif |
89 | |
90 | // Try to define a macro to encapsulate the tgkill syscall |
91 | // fall back on kill() if tgkill isn't available |
92 | #define tgkill(pid, tid, sig)syscall(234, pid, tid, sig) syscall(SYS_tgkill234, pid, tid, sig) |
93 | |
94 | using namespace lldb_private; |
95 | |
96 | // FIXME: this code is host-dependent with respect to types and |
97 | // endianness and needs to be fixed. For example, lldb::addr_t is |
98 | // hard-coded to uint64_t, but on a 32-bit Linux host, ptrace requires |
99 | // 32-bit pointer arguments. This code uses casts to work around the |
100 | // problem. |
101 | |
102 | // We disable the tracing of ptrace calls for integration builds to |
103 | // avoid the additional indirection and checks. |
104 | #ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION |
105 | |
106 | static void |
107 | DisplayBytes (lldb_private::StreamString &s, void *bytes, uint32_t count) |
108 | { |
109 | uint8_t *ptr = (uint8_t *)bytes; |
110 | const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES20, count); |
111 | for(uint32_t i=0; i<loop_count; i++) |
112 | { |
113 | s.Printf ("[%x]", *ptr); |
114 | ptr++; |
115 | } |
116 | } |
117 | |
118 | static void PtraceDisplayBytes(int &req, void *data, size_t data_size) |
119 | { |
120 | StreamString buf; |
121 | Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet ( |
122 | POSIX_LOG_PTRACE(1u << 12) | POSIX_LOG_VERBOSE(1u << 0))); |
123 | |
124 | if (verbose_log) |
125 | { |
126 | switch(req) |
127 | { |
128 | case PTRACE_POKETEXT: |
129 | { |
130 | DisplayBytes(buf, &data, 8); |
131 | verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData()); |
132 | break; |
133 | } |
134 | case PTRACE_POKEDATA: |
135 | { |
136 | DisplayBytes(buf, &data, 8); |
137 | verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData()); |
138 | break; |
139 | } |
140 | case PTRACE_POKEUSER: |
141 | { |
142 | DisplayBytes(buf, &data, 8); |
143 | verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData()); |
144 | break; |
145 | } |
146 | #if !defined (__arm64__) && !defined (__aarch64__) |
147 | case PTRACE_SETREGS: |
148 | { |
149 | DisplayBytes(buf, data, data_size); |
150 | verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData()); |
151 | break; |
152 | } |
153 | case PTRACE_SETFPREGS: |
154 | { |
155 | DisplayBytes(buf, data, data_size); |
156 | verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData()); |
157 | break; |
158 | } |
159 | #endif |
160 | case PTRACE_SETSIGINFO: |
161 | { |
162 | DisplayBytes(buf, data, sizeof(siginfo_t)); |
163 | verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData()); |
164 | break; |
165 | } |
166 | case PTRACE_SETREGSETPTRACE_SETREGSET: |
167 | { |
168 | // Extract iov_base from data, which is a pointer to the struct IOVEC |
169 | DisplayBytes(buf, *(void **)data, data_size); |
170 | verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData()); |
171 | break; |
172 | } |
173 | default: |
174 | { |
175 | } |
176 | } |
177 | } |
178 | } |
179 | |
180 | // Wrapper for ptrace to catch errors and log calls. |
181 | // Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*) |
182 | extern long |
183 | PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, |
184 | const char* reqName, const char* file, int line) |
185 | { |
186 | long int result; |
187 | |
188 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE(1u << 12))); |
189 | |
190 | PtraceDisplayBytes(req, data, data_size); |
191 | |
192 | errno(*__errno_location ()) = 0; |
193 | if (req == PTRACE_GETREGSETPTRACE_GETREGSET || req == PTRACE_SETREGSETPTRACE_SETREGSET) |
194 | result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), *(unsigned int *)addr, data); |
195 | else |
196 | result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), addr, data); |
197 | |
198 | if (log) |
199 | log->Printf("ptrace(%s, %" PRIu64"l" "u" ", %p, %p, %zu)=%lX called from file %s line %d", |
200 | reqName, pid, addr, data, data_size, result, file, line); |
201 | |
202 | PtraceDisplayBytes(req, data, data_size); |
203 | |
204 | if (log && errno(*__errno_location ()) != 0) |
205 | { |
206 | const char* str; |
207 | switch (errno(*__errno_location ())) |
208 | { |
209 | case ESRCH3: str = "ESRCH"; break; |
210 | case EINVAL22: str = "EINVAL"; break; |
211 | case EBUSY16: str = "EBUSY"; break; |
212 | case EPERM1: str = "EPERM"; break; |
213 | default: str = "<unknown>"; |
214 | } |
215 | log->Printf("ptrace() failed; errno=%d (%s)", errno(*__errno_location ()), str); |
216 | } |
217 | |
218 | return result; |
219 | } |
220 | |
221 | // Wrapper for ptrace when logging is not required. |
222 | // Sets errno to 0 prior to calling ptrace. |
223 | extern long |
224 | PtraceWrapper(int req, pid_t pid, void *addr, void *data, size_t data_size) |
225 | { |
226 | long result = 0; |
227 | errno(*__errno_location ()) = 0; |
228 | if (req == PTRACE_GETREGSETPTRACE_GETREGSET || req == PTRACE_SETREGSETPTRACE_SETREGSET) |
229 | result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data); |
230 | else |
231 | result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data); |
232 | return result; |
233 | } |
234 | |
235 | #define PTRACE(req, pid, addr, data, data_size)PtraceWrapper((req), (pid), (addr), (data), (data_size), "req" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 235) \ |
236 | PtraceWrapper((req), (pid), (addr), (data), (data_size), #req, __FILE__"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp", __LINE__236) |
237 | #else |
238 | PtraceWrapper((req), (pid), (addr), (data), (data_size)) |
239 | #endif |
240 | |
241 | //------------------------------------------------------------------------------ |
242 | // Static implementations of ProcessMonitor::ReadMemory and |
243 | // ProcessMonitor::WriteMemory. This enables mutual recursion between these |
244 | // functions without needed to go thru the thread funnel. |
245 | |
246 | static size_t |
247 | DoReadMemory(lldb::pid_t pid, |
248 | lldb::addr_t vm_addr, void *buf, size_t size, Error &error) |
249 | { |
250 | // ptrace word size is determined by the host, not the child |
251 | static const unsigned word_size = sizeof(void*); |
252 | unsigned char *dst = static_cast<unsigned char*>(buf); |
253 | size_t bytes_read; |
254 | size_t remainder; |
255 | long data; |
256 | |
257 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL((4294967295U)))); |
258 | if (log) |
259 | ProcessPOSIXLog::IncNestLevel(); |
260 | if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY(1u << 4))) |
261 | log->Printf ("ProcessMonitor::%s(%" PRIu64"l" "u" ", %d, %p, %p, %zd, _)", __FUNCTION__, |
262 | pid, word_size, (void*)vm_addr, buf, size); |
263 | |
264 | assert(sizeof(data) >= word_size)((sizeof(data) >= word_size) ? static_cast<void> (0) : __assert_fail ("sizeof(data) >= word_size", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 264, __PRETTY_FUNCTION__)); |
265 | for (bytes_read = 0; bytes_read < size; bytes_read += remainder) |
266 | { |
267 | errno(*__errno_location ()) = 0; |
268 | data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL, 0)PtraceWrapper((PTRACE_PEEKDATA), (pid), ((void*)vm_addr), (__null ), (0), "PTRACE_PEEKDATA", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 268); |
269 | if (errno(*__errno_location ())) |
270 | { |
271 | error.SetErrorToErrno(); |
272 | if (log) |
273 | ProcessPOSIXLog::DecNestLevel(); |
274 | return bytes_read; |
275 | } |
276 | |
277 | remainder = size - bytes_read; |
278 | remainder = remainder > word_size ? word_size : remainder; |
279 | |
280 | // Copy the data into our buffer |
281 | for (unsigned i = 0; i < remainder; ++i) |
282 | dst[i] = ((data >> i*8) & 0xFF); |
283 | |
284 | if (log && ProcessPOSIXLog::AtTopNestLevel() && |
285 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG(1u << 6)) || |
286 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT(1u << 5)) && |
287 | size <= POSIX_LOG_MEMORY_SHORT_BYTES(4 * sizeof(ptrdiff_t))))) |
288 | { |
289 | uintptr_t print_dst = 0; |
290 | // Format bytes from data by moving into print_dst for log output |
291 | for (unsigned i = 0; i < remainder; ++i) |
292 | print_dst |= (((data >> i*8) & 0xFF) << i*8); |
293 | log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, |
294 | (void*)vm_addr, print_dst, (unsigned long)data); |
295 | } |
296 | |
297 | vm_addr += word_size; |
298 | dst += word_size; |
299 | } |
300 | |
301 | if (log) |
302 | ProcessPOSIXLog::DecNestLevel(); |
303 | return bytes_read; |
304 | } |
305 | |
306 | static size_t |
307 | DoWriteMemory(lldb::pid_t pid, |
308 | lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) |
309 | { |
310 | // ptrace word size is determined by the host, not the child |
311 | static const unsigned word_size = sizeof(void*); |
312 | const unsigned char *src = static_cast<const unsigned char*>(buf); |
313 | size_t bytes_written = 0; |
314 | size_t remainder; |
315 | |
316 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL((4294967295U)))); |
317 | if (log) |
318 | ProcessPOSIXLog::IncNestLevel(); |
319 | if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY(1u << 4))) |
320 | log->Printf ("ProcessMonitor::%s(%" PRIu64"l" "u" ", %d, %p, %p, %zd, _)", __FUNCTION__, |
321 | pid, word_size, (void*)vm_addr, buf, size); |
322 | |
323 | for (bytes_written = 0; bytes_written < size; bytes_written += remainder) |
324 | { |
325 | remainder = size - bytes_written; |
326 | remainder = remainder > word_size ? word_size : remainder; |
327 | |
328 | if (remainder == word_size) |
329 | { |
330 | unsigned long data = 0; |
331 | assert(sizeof(data) >= word_size)((sizeof(data) >= word_size) ? static_cast<void> (0) : __assert_fail ("sizeof(data) >= word_size", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 331, __PRETTY_FUNCTION__)); |
332 | for (unsigned i = 0; i < word_size; ++i) |
333 | data |= (unsigned long)src[i] << i*8; |
334 | |
335 | if (log && ProcessPOSIXLog::AtTopNestLevel() && |
336 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG(1u << 6)) || |
337 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT(1u << 5)) && |
338 | size <= POSIX_LOG_MEMORY_SHORT_BYTES(4 * sizeof(ptrdiff_t))))) |
339 | log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, |
340 | (void*)vm_addr, *(unsigned long*)src, data); |
341 | |
342 | if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0)PtraceWrapper((PTRACE_POKEDATA), (pid), ((void*)vm_addr), ((void *)data), (0), "PTRACE_POKEDATA", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 342)) |
343 | { |
344 | error.SetErrorToErrno(); |
345 | if (log) |
346 | ProcessPOSIXLog::DecNestLevel(); |
347 | return bytes_written; |
348 | } |
349 | } |
350 | else |
351 | { |
352 | unsigned char buff[8]; |
353 | if (DoReadMemory(pid, vm_addr, |
354 | buff, word_size, error) != word_size) |
355 | { |
356 | if (log) |
357 | ProcessPOSIXLog::DecNestLevel(); |
358 | return bytes_written; |
359 | } |
360 | |
361 | memcpy(buff, src, remainder); |
362 | |
363 | if (DoWriteMemory(pid, vm_addr, |
364 | buff, word_size, error) != word_size) |
365 | { |
366 | if (log) |
367 | ProcessPOSIXLog::DecNestLevel(); |
368 | return bytes_written; |
369 | } |
370 | |
371 | if (log && ProcessPOSIXLog::AtTopNestLevel() && |
372 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG(1u << 6)) || |
373 | (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT(1u << 5)) && |
374 | size <= POSIX_LOG_MEMORY_SHORT_BYTES(4 * sizeof(ptrdiff_t))))) |
375 | log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, |
376 | (void*)vm_addr, *(unsigned long*)src, *(unsigned long*)buff); |
377 | } |
378 | |
379 | vm_addr += word_size; |
380 | src += word_size; |
381 | } |
382 | if (log) |
383 | ProcessPOSIXLog::DecNestLevel(); |
384 | return bytes_written; |
385 | } |
386 | |
387 | // Simple helper function to ensure flags are enabled on the given file |
388 | // descriptor. |
389 | static bool |
390 | EnsureFDFlags(int fd, int flags, Error &error) |
391 | { |
392 | int status; |
393 | |
394 | if ((status = fcntl(fd, F_GETFL3)) == -1) |
395 | { |
396 | error.SetErrorToErrno(); |
397 | return false; |
398 | } |
399 | |
400 | if (fcntl(fd, F_SETFL4, status | flags) == -1) |
401 | { |
402 | error.SetErrorToErrno(); |
403 | return false; |
404 | } |
405 | |
406 | return true; |
407 | } |
408 | |
409 | //------------------------------------------------------------------------------ |
410 | /// @class Operation |
411 | /// @brief Represents a ProcessMonitor operation. |
412 | /// |
413 | /// Under Linux, it is not possible to ptrace() from any other thread but the |
414 | /// one that spawned or attached to the process from the start. Therefore, when |
415 | /// a ProcessMonitor is asked to deliver or change the state of an inferior |
416 | /// process the operation must be "funneled" to a specific thread to perform the |
417 | /// task. The Operation class provides an abstract base for all services the |
418 | /// ProcessMonitor must perform via the single virtual function Execute, thus |
419 | /// encapsulating the code that needs to run in the privileged context. |
420 | class Operation |
421 | { |
422 | public: |
423 | virtual ~Operation() {} |
424 | virtual void Execute(ProcessMonitor *monitor) = 0; |
425 | }; |
426 | |
427 | //------------------------------------------------------------------------------ |
428 | /// @class ReadOperation |
429 | /// @brief Implements ProcessMonitor::ReadMemory. |
430 | class ReadOperation : public Operation |
431 | { |
432 | public: |
433 | ReadOperation(lldb::addr_t addr, void *buff, size_t size, |
434 | Error &error, size_t &result) |
435 | : m_addr(addr), m_buff(buff), m_size(size), |
436 | m_error(error), m_result(result) |
437 | { } |
438 | |
439 | void Execute(ProcessMonitor *monitor); |
440 | |
441 | private: |
442 | lldb::addr_t m_addr; |
443 | void *m_buff; |
444 | size_t m_size; |
445 | Error &m_error; |
446 | size_t &m_result; |
447 | }; |
448 | |
449 | void |
450 | ReadOperation::Execute(ProcessMonitor *monitor) |
451 | { |
452 | lldb::pid_t pid = monitor->GetPID(); |
453 | |
454 | m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error); |
455 | } |
456 | |
457 | //------------------------------------------------------------------------------ |
458 | /// @class WriteOperation |
459 | /// @brief Implements ProcessMonitor::WriteMemory. |
460 | class WriteOperation : public Operation |
461 | { |
462 | public: |
463 | WriteOperation(lldb::addr_t addr, const void *buff, size_t size, |
464 | Error &error, size_t &result) |
465 | : m_addr(addr), m_buff(buff), m_size(size), |
466 | m_error(error), m_result(result) |
467 | { } |
468 | |
469 | void Execute(ProcessMonitor *monitor); |
470 | |
471 | private: |
472 | lldb::addr_t m_addr; |
473 | const void *m_buff; |
474 | size_t m_size; |
475 | Error &m_error; |
476 | size_t &m_result; |
477 | }; |
478 | |
479 | void |
480 | WriteOperation::Execute(ProcessMonitor *monitor) |
481 | { |
482 | lldb::pid_t pid = monitor->GetPID(); |
483 | |
484 | m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error); |
485 | } |
486 | |
487 | |
488 | //------------------------------------------------------------------------------ |
489 | /// @class ReadRegOperation |
490 | /// @brief Implements ProcessMonitor::ReadRegisterValue. |
491 | class ReadRegOperation : public Operation |
492 | { |
493 | public: |
494 | ReadRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, |
495 | RegisterValue &value, bool &result) |
496 | : m_tid(tid), m_offset(offset), m_reg_name(reg_name), |
497 | m_value(value), m_result(result) |
498 | { } |
499 | |
500 | void Execute(ProcessMonitor *monitor); |
501 | |
502 | private: |
503 | lldb::tid_t m_tid; |
504 | uintptr_t m_offset; |
505 | const char *m_reg_name; |
506 | RegisterValue &m_value; |
507 | bool &m_result; |
508 | }; |
509 | |
510 | void |
511 | ReadRegOperation::Execute(ProcessMonitor *monitor) |
512 | { |
513 | #if defined (__arm64__) || defined (__aarch64__) |
514 | if (m_offset > sizeof(struct user_pt_regs)) |
515 | { |
516 | uintptr_t offset = m_offset - sizeof(struct user_pt_regs); |
517 | if (offset > sizeof(struct user_fpsimd_state)) |
518 | { |
519 | m_result = false; |
520 | } |
521 | else |
522 | { |
523 | elf_fpregset_t regs; |
524 | int regset = NT_FPREGSET2; |
525 | struct iovec ioVec; |
526 | |
527 | ioVec.iov_base = ®s; |
528 | ioVec.iov_len = sizeof regs; |
529 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 529) < 0) |
530 | m_result = false; |
531 | else |
532 | { |
533 | m_result = true; |
534 | m_value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, monitor->GetProcess().GetByteOrder()); |
535 | } |
536 | } |
537 | } |
538 | else |
539 | { |
540 | elf_gregset_t regs; |
541 | int regset = NT_PRSTATUS1; |
542 | struct iovec ioVec; |
543 | |
544 | ioVec.iov_base = ®s; |
545 | ioVec.iov_len = sizeof regs; |
546 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 546) < 0) |
547 | m_result = false; |
548 | else |
549 | { |
550 | m_result = true; |
551 | m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, monitor->GetProcess().GetByteOrder()); |
552 | } |
553 | } |
554 | #else |
555 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS(1u << 13))); |
556 | |
557 | // Set errno to zero so that we can detect a failed peek. |
558 | errno(*__errno_location ()) = 0; |
559 | lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL, 0)PtraceWrapper((PTRACE_PEEKUSER), (m_tid), ((void*)m_offset), ( __null), (0), "PTRACE_PEEKUSER", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 559); |
560 | if (errno(*__errno_location ())) |
561 | m_result = false; |
562 | else |
563 | { |
564 | m_value = data; |
565 | m_result = true; |
566 | } |
567 | if (log) |
568 | log->Printf ("ProcessMonitor::%s() reg %s: 0x%" PRIx64"l" "x", __FUNCTION__, |
569 | m_reg_name, data); |
570 | #endif |
571 | } |
572 | |
573 | //------------------------------------------------------------------------------ |
574 | /// @class WriteRegOperation |
575 | /// @brief Implements ProcessMonitor::WriteRegisterValue. |
576 | class WriteRegOperation : public Operation |
577 | { |
578 | public: |
579 | WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, |
580 | const RegisterValue &value, bool &result) |
581 | : m_tid(tid), m_offset(offset), m_reg_name(reg_name), |
582 | m_value(value), m_result(result) |
583 | { } |
584 | |
585 | void Execute(ProcessMonitor *monitor); |
586 | |
587 | private: |
588 | lldb::tid_t m_tid; |
589 | uintptr_t m_offset; |
590 | const char *m_reg_name; |
591 | const RegisterValue &m_value; |
592 | bool &m_result; |
593 | }; |
594 | |
595 | void |
596 | WriteRegOperation::Execute(ProcessMonitor *monitor) |
597 | { |
598 | #if defined (__arm64__) || defined (__aarch64__) |
599 | if (m_offset > sizeof(struct user_pt_regs)) |
600 | { |
601 | uintptr_t offset = m_offset - sizeof(struct user_pt_regs); |
602 | if (offset > sizeof(struct user_fpsimd_state)) |
603 | { |
604 | m_result = false; |
605 | } |
606 | else |
607 | { |
608 | elf_fpregset_t regs; |
609 | int regset = NT_FPREGSET2; |
610 | struct iovec ioVec; |
611 | |
612 | ioVec.iov_base = ®s; |
613 | ioVec.iov_len = sizeof regs; |
614 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 614) < 0) |
615 | m_result = false; |
616 | else |
617 | { |
618 | ::memcpy((void *)(((unsigned char *)(®s)) + offset), m_value.GetBytes(), 16); |
619 | if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_SETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_SETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 619) < 0) |
620 | m_result = false; |
621 | else |
622 | m_result = true; |
623 | } |
624 | } |
625 | } |
626 | else |
627 | { |
628 | elf_gregset_t regs; |
629 | int regset = NT_PRSTATUS1; |
630 | struct iovec ioVec; |
631 | |
632 | ioVec.iov_base = ®s; |
633 | ioVec.iov_len = sizeof regs; |
634 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 634) < 0) |
635 | m_result = false; |
636 | else |
637 | { |
638 | ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); |
639 | if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs)PtraceWrapper((PTRACE_SETREGSET), (m_tid), (®set), (& ioVec), (sizeof regs), "PTRACE_SETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 639) < 0) |
640 | m_result = false; |
641 | else |
642 | m_result = true; |
643 | } |
644 | } |
645 | #else |
646 | void* buf; |
647 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS(1u << 13))); |
648 | |
649 | buf = (void*) m_value.GetAsUInt64(); |
650 | |
651 | if (log) |
652 | log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf); |
653 | if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0)PtraceWrapper((PTRACE_POKEUSER), (m_tid), ((void*)m_offset), ( buf), (0), "PTRACE_POKEUSER", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 653)) |
654 | m_result = false; |
655 | else |
656 | m_result = true; |
657 | #endif |
658 | } |
659 | |
660 | //------------------------------------------------------------------------------ |
661 | /// @class ReadGPROperation |
662 | /// @brief Implements ProcessMonitor::ReadGPR. |
663 | class ReadGPROperation : public Operation |
664 | { |
665 | public: |
666 | ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result) |
667 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result) |
668 | { } |
669 | |
670 | void Execute(ProcessMonitor *monitor); |
671 | |
672 | private: |
673 | lldb::tid_t m_tid; |
674 | void *m_buf; |
675 | size_t m_buf_size; |
676 | bool &m_result; |
677 | }; |
678 | |
679 | void |
680 | ReadGPROperation::Execute(ProcessMonitor *monitor) |
681 | { |
682 | #if defined (__arm64__) || defined (__aarch64__) |
683 | int regset = NT_PRSTATUS1; |
684 | struct iovec ioVec; |
685 | |
686 | ioVec.iov_base = m_buf; |
687 | ioVec.iov_len = m_buf_size; |
688 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (m_buf_size), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 688) < 0) |
689 | m_result = false; |
690 | else |
691 | m_result = true; |
692 | #else |
693 | if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf, m_buf_size)PtraceWrapper((PTRACE_GETREGS), (m_tid), (__null), (m_buf), ( m_buf_size), "PTRACE_GETREGS", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 693) < 0) |
694 | m_result = false; |
695 | else |
696 | m_result = true; |
697 | #endif |
698 | } |
699 | |
700 | //------------------------------------------------------------------------------ |
701 | /// @class ReadFPROperation |
702 | /// @brief Implements ProcessMonitor::ReadFPR. |
703 | class ReadFPROperation : public Operation |
704 | { |
705 | public: |
706 | ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result) |
707 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result) |
708 | { } |
709 | |
710 | void Execute(ProcessMonitor *monitor); |
711 | |
712 | private: |
713 | lldb::tid_t m_tid; |
714 | void *m_buf; |
715 | size_t m_buf_size; |
716 | bool &m_result; |
717 | }; |
718 | |
719 | void |
720 | ReadFPROperation::Execute(ProcessMonitor *monitor) |
721 | { |
722 | #if defined (__arm64__) || defined (__aarch64__) |
723 | int regset = NT_FPREGSET2; |
724 | struct iovec ioVec; |
725 | |
726 | ioVec.iov_base = m_buf; |
727 | ioVec.iov_len = m_buf_size; |
728 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (m_buf_size), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 728) < 0) |
729 | m_result = false; |
730 | else |
731 | m_result = true; |
732 | #else |
733 | if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf, m_buf_size)PtraceWrapper((PTRACE_GETFPREGS), (m_tid), (__null), (m_buf), (m_buf_size), "PTRACE_GETFPREGS", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 733) < 0) |
734 | m_result = false; |
735 | else |
736 | m_result = true; |
737 | #endif |
738 | } |
739 | |
740 | //------------------------------------------------------------------------------ |
741 | /// @class ReadRegisterSetOperation |
742 | /// @brief Implements ProcessMonitor::ReadRegisterSet. |
743 | class ReadRegisterSetOperation : public Operation |
744 | { |
745 | public: |
746 | ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result) |
747 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result) |
748 | { } |
749 | |
750 | void Execute(ProcessMonitor *monitor); |
751 | |
752 | private: |
753 | lldb::tid_t m_tid; |
754 | void *m_buf; |
755 | size_t m_buf_size; |
756 | const unsigned int m_regset; |
757 | bool &m_result; |
758 | }; |
759 | |
760 | void |
761 | ReadRegisterSetOperation::Execute(ProcessMonitor *monitor) |
762 | { |
763 | if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size)PtraceWrapper((PTRACE_GETREGSET), (m_tid), ((void *)&m_regset ), (m_buf), (m_buf_size), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 763) < 0) |
764 | m_result = false; |
765 | else |
766 | m_result = true; |
767 | } |
768 | |
769 | //------------------------------------------------------------------------------ |
770 | /// @class WriteGPROperation |
771 | /// @brief Implements ProcessMonitor::WriteGPR. |
772 | class WriteGPROperation : public Operation |
773 | { |
774 | public: |
775 | WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result) |
776 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result) |
777 | { } |
778 | |
779 | void Execute(ProcessMonitor *monitor); |
780 | |
781 | private: |
782 | lldb::tid_t m_tid; |
783 | void *m_buf; |
784 | size_t m_buf_size; |
785 | bool &m_result; |
786 | }; |
787 | |
788 | void |
789 | WriteGPROperation::Execute(ProcessMonitor *monitor) |
790 | { |
791 | #if defined (__arm64__) || defined (__aarch64__) |
792 | int regset = NT_PRSTATUS1; |
793 | struct iovec ioVec; |
794 | |
795 | ioVec.iov_base = m_buf; |
796 | ioVec.iov_len = m_buf_size; |
797 | if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size)PtraceWrapper((PTRACE_SETREGSET), (m_tid), (®set), (& ioVec), (m_buf_size), "PTRACE_SETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 797) < 0) |
798 | m_result = false; |
799 | else |
800 | m_result = true; |
801 | #else |
802 | if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size)PtraceWrapper((PTRACE_SETREGS), (m_tid), (__null), (m_buf), ( m_buf_size), "PTRACE_SETREGS", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 802) < 0) |
803 | m_result = false; |
804 | else |
805 | m_result = true; |
806 | #endif |
807 | } |
808 | |
809 | //------------------------------------------------------------------------------ |
810 | /// @class WriteFPROperation |
811 | /// @brief Implements ProcessMonitor::WriteFPR. |
812 | class WriteFPROperation : public Operation |
813 | { |
814 | public: |
815 | WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result) |
816 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result) |
817 | { } |
818 | |
819 | void Execute(ProcessMonitor *monitor); |
820 | |
821 | private: |
822 | lldb::tid_t m_tid; |
823 | void *m_buf; |
824 | size_t m_buf_size; |
825 | bool &m_result; |
826 | }; |
827 | |
828 | void |
829 | WriteFPROperation::Execute(ProcessMonitor *monitor) |
830 | { |
831 | #if defined (__arm64__) || defined (__aarch64__) |
832 | int regset = NT_FPREGSET2; |
833 | struct iovec ioVec; |
834 | |
835 | ioVec.iov_base = m_buf; |
836 | ioVec.iov_len = m_buf_size; |
837 | if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size)PtraceWrapper((PTRACE_SETREGSET), (m_tid), (®set), (& ioVec), (m_buf_size), "PTRACE_SETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 837) < 0) |
838 | m_result = false; |
839 | else |
840 | m_result = true; |
841 | #else |
842 | if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size)PtraceWrapper((PTRACE_SETFPREGS), (m_tid), (__null), (m_buf), (m_buf_size), "PTRACE_SETFPREGS", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 842) < 0) |
843 | m_result = false; |
844 | else |
845 | m_result = true; |
846 | #endif |
847 | } |
848 | |
849 | //------------------------------------------------------------------------------ |
850 | /// @class WriteRegisterSetOperation |
851 | /// @brief Implements ProcessMonitor::WriteRegisterSet. |
852 | class WriteRegisterSetOperation : public Operation |
853 | { |
854 | public: |
855 | WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result) |
856 | : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result) |
857 | { } |
858 | |
859 | void Execute(ProcessMonitor *monitor); |
860 | |
861 | private: |
862 | lldb::tid_t m_tid; |
863 | void *m_buf; |
864 | size_t m_buf_size; |
865 | const unsigned int m_regset; |
866 | bool &m_result; |
867 | }; |
868 | |
869 | void |
870 | WriteRegisterSetOperation::Execute(ProcessMonitor *monitor) |
871 | { |
872 | if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size)PtraceWrapper((PTRACE_SETREGSET), (m_tid), ((void *)&m_regset ), (m_buf), (m_buf_size), "PTRACE_SETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 872) < 0) |
873 | m_result = false; |
874 | else |
875 | m_result = true; |
876 | } |
877 | |
878 | //------------------------------------------------------------------------------ |
879 | /// @class ReadThreadPointerOperation |
880 | /// @brief Implements ProcessMonitor::ReadThreadPointer. |
881 | class ReadThreadPointerOperation : public Operation |
882 | { |
883 | public: |
884 | ReadThreadPointerOperation(lldb::tid_t tid, lldb::addr_t *addr, bool &result) |
885 | : m_tid(tid), m_addr(addr), m_result(result) |
886 | { } |
887 | |
888 | void Execute(ProcessMonitor *monitor); |
889 | |
890 | private: |
891 | lldb::tid_t m_tid; |
892 | lldb::addr_t *m_addr; |
893 | bool &m_result; |
894 | }; |
895 | |
896 | void |
897 | ReadThreadPointerOperation::Execute(ProcessMonitor *monitor) |
898 | { |
899 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS(1u << 13))); |
900 | if (log) |
901 | log->Printf ("ProcessMonitor::%s()", __FUNCTION__); |
902 | |
903 | // The process for getting the thread area on Linux is |
904 | // somewhat... obscure. There's several different ways depending on |
905 | // what arch you're on, and what kernel version you have. |
906 | |
907 | const ArchSpec& arch = monitor->GetProcess().GetTarget().GetArchitecture(); |
908 | switch(arch.GetMachine()) |
909 | { |
910 | case llvm::Triple::aarch64: |
911 | { |
912 | int regset = LLDB_PTRACE_NT_ARM_TLS0x401; |
913 | struct iovec ioVec; |
914 | |
915 | ioVec.iov_base = m_addr; |
916 | ioVec.iov_len = sizeof(lldb::addr_t); |
917 | if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, ioVec.iov_len)PtraceWrapper((PTRACE_GETREGSET), (m_tid), (®set), (& ioVec), (ioVec.iov_len), "PTRACE_GETREGSET", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 917) < 0) |
918 | m_result = false; |
919 | else |
920 | m_result = true; |
921 | break; |
922 | } |
923 | #if defined(__i386__) || defined(__x86_64__1) |
924 | // Note that struct user below has a field named i387 which is x86-specific. |
925 | // Therefore, this case should be compiled only for x86-based systems. |
926 | case llvm::Triple::x86: |
927 | { |
928 | // Find the GS register location for our host architecture. |
929 | size_t gs_user_offset = offsetof(struct user, regs)__builtin_offsetof(struct user, regs); |
930 | #ifdef __x86_64__1 |
931 | gs_user_offset += offsetof(struct user_regs_struct, gs)__builtin_offsetof(struct user_regs_struct, gs); |
932 | #endif |
933 | #ifdef __i386__ |
934 | gs_user_offset += offsetof(struct user_regs_struct, xgs)__builtin_offsetof(struct user_regs_struct, xgs); |
935 | #endif |
936 | |
937 | // Read the GS register value to get the selector. |
938 | errno(*__errno_location ()) = 0; |
939 | long gs = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)gs_user_offset, NULL, 0)PtraceWrapper((PTRACE_PEEKUSER), (m_tid), ((void*)gs_user_offset ), (__null), (0), "PTRACE_PEEKUSER", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 939); |
940 | if (errno(*__errno_location ())) |
941 | { |
942 | m_result = false; |
943 | break; |
944 | } |
945 | |
946 | // Read the LDT base for that selector. |
947 | uint32_t tmp[4]; |
948 | m_result = (PTRACE(PTRACE_GET_THREAD_AREA, m_tid, (void *)(gs >> 3), &tmp, 0)PtraceWrapper((25), (m_tid), ((void *)(gs >> 3)), (& tmp), (0), "PTRACE_GET_THREAD_AREA", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 948) == 0); |
949 | *m_addr = tmp[1]; |
950 | break; |
951 | } |
952 | #endif |
953 | case llvm::Triple::x86_64: |
954 | // Read the FS register base. |
955 | m_result = (PTRACE(PTRACE_ARCH_PRCTL, m_tid, m_addr, (void *)ARCH_GET_FS, 0)PtraceWrapper((30), (m_tid), (m_addr), ((void *)0x1003), (0), "PTRACE_ARCH_PRCTL", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 955) == 0); |
956 | break; |
957 | default: |
958 | m_result = false; |
959 | break; |
960 | } |
961 | } |
962 | |
963 | //------------------------------------------------------------------------------ |
964 | /// @class ResumeOperation |
965 | /// @brief Implements ProcessMonitor::Resume. |
966 | class ResumeOperation : public Operation |
967 | { |
968 | public: |
969 | ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) : |
970 | m_tid(tid), m_signo(signo), m_result(result) { } |
971 | |
972 | void Execute(ProcessMonitor *monitor); |
973 | |
974 | private: |
975 | lldb::tid_t m_tid; |
976 | uint32_t m_signo; |
977 | bool &m_result; |
978 | }; |
979 | |
980 | void |
981 | ResumeOperation::Execute(ProcessMonitor *monitor) |
982 | { |
983 | intptr_t data = 0; |
984 | |
985 | if (m_signo != LLDB_INVALID_SIGNAL_NUMBER(2147483647)) |
986 | data = m_signo; |
987 | |
988 | if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data, 0)PtraceWrapper((PTRACE_CONT), (m_tid), (__null), ((void*)data) , (0), "PTRACE_CONT", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 988)) |
989 | { |
990 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
991 | |
992 | if (log) |
993 | log->Printf ("ResumeOperation (%" PRIu64"l" "u" ") failed: %s", m_tid, strerror(errno(*__errno_location ()))); |
994 | m_result = false; |
995 | } |
996 | else |
997 | m_result = true; |
998 | } |
999 | |
1000 | //------------------------------------------------------------------------------ |
1001 | /// @class SingleStepOperation |
1002 | /// @brief Implements ProcessMonitor::SingleStep. |
1003 | class SingleStepOperation : public Operation |
1004 | { |
1005 | public: |
1006 | SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result) |
1007 | : m_tid(tid), m_signo(signo), m_result(result) { } |
1008 | |
1009 | void Execute(ProcessMonitor *monitor); |
1010 | |
1011 | private: |
1012 | lldb::tid_t m_tid; |
1013 | uint32_t m_signo; |
1014 | bool &m_result; |
1015 | }; |
1016 | |
1017 | void |
1018 | SingleStepOperation::Execute(ProcessMonitor *monitor) |
1019 | { |
1020 | intptr_t data = 0; |
1021 | |
1022 | if (m_signo != LLDB_INVALID_SIGNAL_NUMBER(2147483647)) |
1023 | data = m_signo; |
1024 | |
1025 | if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data, 0)PtraceWrapper((PTRACE_SINGLESTEP), (m_tid), (__null), ((void* )data), (0), "PTRACE_SINGLESTEP", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1025)) |
1026 | m_result = false; |
1027 | else |
1028 | m_result = true; |
1029 | } |
1030 | |
1031 | //------------------------------------------------------------------------------ |
1032 | /// @class SiginfoOperation |
1033 | /// @brief Implements ProcessMonitor::GetSignalInfo. |
1034 | class SiginfoOperation : public Operation |
1035 | { |
1036 | public: |
1037 | SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err) |
1038 | : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { } |
1039 | |
1040 | void Execute(ProcessMonitor *monitor); |
1041 | |
1042 | private: |
1043 | lldb::tid_t m_tid; |
1044 | void *m_info; |
1045 | bool &m_result; |
1046 | int &m_err; |
1047 | }; |
1048 | |
1049 | void |
1050 | SiginfoOperation::Execute(ProcessMonitor *monitor) |
1051 | { |
1052 | if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info, 0)PtraceWrapper((PTRACE_GETSIGINFO), (m_tid), (__null), (m_info ), (0), "PTRACE_GETSIGINFO", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1052)) { |
1053 | m_result = false; |
1054 | m_err = errno(*__errno_location ()); |
1055 | } |
1056 | else |
1057 | m_result = true; |
1058 | } |
1059 | |
1060 | //------------------------------------------------------------------------------ |
1061 | /// @class EventMessageOperation |
1062 | /// @brief Implements ProcessMonitor::GetEventMessage. |
1063 | class EventMessageOperation : public Operation |
1064 | { |
1065 | public: |
1066 | EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result) |
1067 | : m_tid(tid), m_message(message), m_result(result) { } |
1068 | |
1069 | void Execute(ProcessMonitor *monitor); |
1070 | |
1071 | private: |
1072 | lldb::tid_t m_tid; |
1073 | unsigned long *m_message; |
1074 | bool &m_result; |
1075 | }; |
1076 | |
1077 | void |
1078 | EventMessageOperation::Execute(ProcessMonitor *monitor) |
1079 | { |
1080 | if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message, 0)PtraceWrapper((PTRACE_GETEVENTMSG), (m_tid), (__null), (m_message ), (0), "PTRACE_GETEVENTMSG", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1080)) |
1081 | m_result = false; |
1082 | else |
1083 | m_result = true; |
1084 | } |
1085 | |
1086 | //------------------------------------------------------------------------------ |
1087 | /// @class DetachOperation |
1088 | /// @brief Implements ProcessMonitor::Detach. |
1089 | class DetachOperation : public Operation |
1090 | { |
1091 | public: |
1092 | DetachOperation(lldb::tid_t tid, Error &result) : m_tid(tid), m_error(result) { } |
1093 | |
1094 | void Execute(ProcessMonitor *monitor); |
1095 | |
1096 | private: |
1097 | lldb::tid_t m_tid; |
1098 | Error &m_error; |
1099 | }; |
1100 | |
1101 | void |
1102 | DetachOperation::Execute(ProcessMonitor *monitor) |
1103 | { |
1104 | if (ptrace(PT_DETACHPTRACE_DETACH, m_tid, NULL__null, 0) < 0) |
1105 | m_error.SetErrorToErrno(); |
1106 | } |
1107 | |
1108 | ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor) |
1109 | : m_monitor(monitor) |
1110 | { |
1111 | sem_init(&m_semaphore, 0, 0); |
1112 | } |
1113 | |
1114 | ProcessMonitor::OperationArgs::~OperationArgs() |
1115 | { |
1116 | sem_destroy(&m_semaphore); |
1117 | } |
1118 | |
1119 | ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor, |
1120 | lldb_private::Module *module, |
1121 | char const **argv, |
1122 | char const **envp, |
1123 | const char *stdin_path, |
1124 | const char *stdout_path, |
1125 | const char *stderr_path, |
1126 | const char *working_dir, |
1127 | const lldb_private::ProcessLaunchInfo &launch_info) |
1128 | : OperationArgs(monitor), |
1129 | m_module(module), |
1130 | m_argv(argv), |
1131 | m_envp(envp), |
1132 | m_stdin_path(stdin_path), |
1133 | m_stdout_path(stdout_path), |
1134 | m_stderr_path(stderr_path), |
1135 | m_working_dir(working_dir), |
1136 | m_launch_info(launch_info) |
1137 | { |
1138 | } |
1139 | |
1140 | ProcessMonitor::LaunchArgs::~LaunchArgs() |
1141 | { } |
1142 | |
1143 | ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, |
1144 | lldb::pid_t pid) |
1145 | : OperationArgs(monitor), m_pid(pid) { } |
1146 | |
1147 | ProcessMonitor::AttachArgs::~AttachArgs() |
1148 | { } |
1149 | |
1150 | //------------------------------------------------------------------------------ |
1151 | /// The basic design of the ProcessMonitor is built around two threads. |
1152 | /// |
1153 | /// One thread (@see SignalThread) simply blocks on a call to waitpid() looking |
1154 | /// for changes in the debugee state. When a change is detected a |
1155 | /// ProcessMessage is sent to the associated ProcessLinux instance. This thread |
1156 | /// "drives" state changes in the debugger. |
1157 | /// |
1158 | /// The second thread (@see OperationThread) is responsible for two things 1) |
1159 | /// launching or attaching to the inferior process, and then 2) servicing |
1160 | /// operations such as register reads/writes, stepping, etc. See the comments |
1161 | /// on the Operation class for more info as to why this is needed. |
1162 | ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, |
1163 | Module *module, |
1164 | const char *argv[], |
1165 | const char *envp[], |
1166 | const char *stdin_path, |
1167 | const char *stdout_path, |
1168 | const char *stderr_path, |
1169 | const char *working_dir, |
1170 | const lldb_private::ProcessLaunchInfo &launch_info, |
1171 | lldb_private::Error &error) |
1172 | : m_process(static_cast<ProcessLinux *>(process)), |
1173 | m_operation_thread(LLDB_INVALID_HOST_THREAD((lldb::thread_t)__null)), |
1174 | m_monitor_thread(LLDB_INVALID_HOST_THREAD((lldb::thread_t)__null)), |
1175 | m_pid(LLDB_INVALID_PROCESS_ID0), |
1176 | m_terminal_fd(-1), |
1177 | m_operation(0) |
1178 | { |
1179 | std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp, |
1180 | stdin_path, stdout_path, stderr_path, |
1181 | working_dir, launch_info)); |
1182 | |
1183 | sem_init(&m_operation_pending, 0, 0); |
1184 | sem_init(&m_operation_done, 0, 0); |
1185 | |
1186 | StartLaunchOpThread(args.get(), error); |
1187 | if (!error.Success()) |
1188 | return; |
1189 | |
1190 | WAIT_AGAIN: |
1191 | // Wait for the operation thread to initialize. |
1192 | if (sem_wait(&args->m_semaphore)) |
1193 | { |
1194 | if (errno(*__errno_location ()) == EINTR4) |
1195 | goto WAIT_AGAIN; |
1196 | else |
1197 | { |
1198 | error.SetErrorToErrno(); |
1199 | return; |
1200 | } |
1201 | } |
1202 | |
1203 | // Check that the launch was a success. |
1204 | if (!args->m_error.Success()) |
1205 | { |
1206 | StopOpThread(); |
1207 | error = args->m_error; |
1208 | return; |
1209 | } |
1210 | |
1211 | // Finally, start monitoring the child process for change in state. |
1212 | m_monitor_thread = Host::StartMonitoringChildProcess( |
1213 | ProcessMonitor::MonitorCallback, this, GetPID(), true); |
1214 | if (!m_monitor_thread.IsJoinable()) |
1215 | { |
1216 | error.SetErrorToGenericError(); |
1217 | error.SetErrorString("Process launch failed."); |
1218 | return; |
1219 | } |
1220 | } |
1221 | |
1222 | ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, |
1223 | lldb::pid_t pid, |
1224 | lldb_private::Error &error) |
1225 | : m_process(static_cast<ProcessLinux *>(process)), |
1226 | m_operation_thread(LLDB_INVALID_HOST_THREAD((lldb::thread_t)__null)), |
1227 | m_monitor_thread(LLDB_INVALID_HOST_THREAD((lldb::thread_t)__null)), |
1228 | m_pid(LLDB_INVALID_PROCESS_ID0), |
1229 | m_terminal_fd(-1), |
1230 | m_operation(0) |
1231 | { |
1232 | sem_init(&m_operation_pending, 0, 0); |
1233 | sem_init(&m_operation_done, 0, 0); |
1234 | |
1235 | std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid)); |
1236 | |
1237 | StartAttachOpThread(args.get(), error); |
1238 | if (!error.Success()) |
1239 | return; |
1240 | |
1241 | WAIT_AGAIN: |
1242 | // Wait for the operation thread to initialize. |
1243 | if (sem_wait(&args->m_semaphore)) |
1244 | { |
1245 | if (errno(*__errno_location ()) == EINTR4) |
1246 | goto WAIT_AGAIN; |
1247 | else |
1248 | { |
1249 | error.SetErrorToErrno(); |
1250 | return; |
1251 | } |
1252 | } |
1253 | |
1254 | // Check that the attach was a success. |
1255 | if (!args->m_error.Success()) |
1256 | { |
1257 | StopOpThread(); |
1258 | error = args->m_error; |
1259 | return; |
1260 | } |
1261 | |
1262 | // Finally, start monitoring the child process for change in state. |
1263 | m_monitor_thread = Host::StartMonitoringChildProcess( |
1264 | ProcessMonitor::MonitorCallback, this, GetPID(), true); |
1265 | if (!m_monitor_thread.IsJoinable()) |
1266 | { |
1267 | error.SetErrorToGenericError(); |
1268 | error.SetErrorString("Process attach failed."); |
1269 | return; |
1270 | } |
1271 | } |
1272 | |
1273 | ProcessMonitor::~ProcessMonitor() |
1274 | { |
1275 | StopMonitor(); |
1276 | } |
1277 | |
1278 | //------------------------------------------------------------------------------ |
1279 | // Thread setup and tear down. |
1280 | void |
1281 | ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) |
1282 | { |
1283 | static const char *g_thread_name = "lldb.process.linux.operation"; |
1284 | |
1285 | if (m_operation_thread.IsJoinable()) |
1286 | return; |
1287 | |
1288 | m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error); |
1289 | } |
1290 | |
1291 | void * |
1292 | ProcessMonitor::LaunchOpThread(void *arg) |
1293 | { |
1294 | LaunchArgs *args = static_cast<LaunchArgs*>(arg); |
1295 | |
1296 | if (!Launch(args)) { |
1297 | sem_post(&args->m_semaphore); |
1298 | return NULL__null; |
1299 | } |
1300 | |
1301 | ServeOperation(args); |
1302 | return NULL__null; |
1303 | } |
1304 | |
1305 | bool |
1306 | ProcessMonitor::Launch(LaunchArgs *args) |
1307 | { |
1308 | assert (args && "null args")((args && "null args") ? static_cast<void> (0) : __assert_fail ("args && \"null args\"", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1308, __PRETTY_FUNCTION__)); |
1309 | if (!args) |
1310 | return false; |
1311 | |
1312 | ProcessMonitor *monitor = args->m_monitor; |
1313 | ProcessLinux &process = monitor->GetProcess(); |
1314 | const char **argv = args->m_argv; |
1315 | const char **envp = args->m_envp; |
1316 | const char *stdin_path = args->m_stdin_path; |
1317 | const char *stdout_path = args->m_stdout_path; |
1318 | const char *stderr_path = args->m_stderr_path; |
1319 | const char *working_dir = args->m_working_dir; |
1320 | |
1321 | lldb_utility::PseudoTerminal terminal; |
1322 | const size_t err_len = 1024; |
1323 | char err_str[err_len]; |
1324 | lldb::pid_t pid; |
1325 | |
1326 | lldb::ThreadSP inferior; |
1327 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1328 | |
1329 | // Propagate the environment if one is not supplied. |
1330 | if (envp == NULL__null || envp[0] == NULL__null) |
1331 | envp = const_cast<const char **>(environ); |
1332 | |
1333 | if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t>(-1)) |
1334 | { |
1335 | args->m_error.SetErrorToGenericError(); |
1336 | args->m_error.SetErrorString("Process fork failed."); |
1337 | goto FINISH; |
1338 | } |
1339 | |
1340 | // Recognized child exit status codes. |
1341 | enum { |
1342 | ePtraceFailed = 1, |
1343 | eDupStdinFailed, |
1344 | eDupStdoutFailed, |
1345 | eDupStderrFailed, |
1346 | eChdirFailed, |
1347 | eExecFailed, |
1348 | eSetGidFailed |
1349 | }; |
1350 | |
1351 | // Child process. |
1352 | if (pid == 0) |
1353 | { |
1354 | // Trace this process. |
1355 | if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL, 0)PtraceWrapper((PTRACE_TRACEME), (0), (__null), (__null), (0), "PTRACE_TRACEME", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1355) < 0) |
1356 | exit(ePtraceFailed); |
1357 | |
1358 | // Do not inherit setgid powers. |
1359 | if (setgid(getgid()) != 0) |
1360 | exit(eSetGidFailed); |
1361 | |
1362 | // Let us have our own process group. |
1363 | setpgid(0, 0); |
1364 | |
1365 | // Dup file descriptors if needed. |
1366 | // |
1367 | // FIXME: If two or more of the paths are the same we needlessly open |
1368 | // the same file multiple times. |
1369 | if (stdin_path != NULL__null && stdin_path[0]) |
1370 | if (!DupDescriptor(stdin_path, STDIN_FILENO0, O_RDONLY00)) |
1371 | exit(eDupStdinFailed); |
1372 | |
1373 | if (stdout_path != NULL__null && stdout_path[0]) |
1374 | if (!DupDescriptor(stdout_path, STDOUT_FILENO1, O_WRONLY01 | O_CREAT0100)) |
1375 | exit(eDupStdoutFailed); |
1376 | |
1377 | if (stderr_path != NULL__null && stderr_path[0]) |
1378 | if (!DupDescriptor(stderr_path, STDERR_FILENO2, O_WRONLY01 | O_CREAT0100)) |
1379 | exit(eDupStderrFailed); |
1380 | |
1381 | // Change working directory |
1382 | if (working_dir != NULL__null && working_dir[0]) |
1383 | if (0 != ::chdir(working_dir)) |
1384 | exit(eChdirFailed); |
1385 | |
1386 | // Disable ASLR if requested. |
1387 | if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR)) |
1388 | { |
1389 | const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS0xffffffff); |
1390 | if (old_personality == -1) |
1391 | { |
1392 | if (log) |
1393 | log->Printf ("ProcessMonitor::%s retrieval of Linux personality () failed: %s. Cannot disable ASLR.", __FUNCTION__, strerror (errno(*__errno_location ()))); |
1394 | } |
1395 | else |
1396 | { |
1397 | const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality); |
1398 | if (new_personality == -1) |
1399 | { |
1400 | if (log) |
1401 | log->Printf ("ProcessMonitor::%s setting of Linux personality () to disable ASLR failed, ignoring: %s", __FUNCTION__, strerror (errno(*__errno_location ()))); |
1402 | |
1403 | } |
1404 | else |
1405 | { |
1406 | if (log) |
1407 | log->Printf ("ProcessMonitor::%s disabling ASLR: SUCCESS", __FUNCTION__); |
1408 | |
1409 | } |
1410 | } |
1411 | } |
1412 | |
1413 | // Execute. We should never return. |
1414 | execve(argv[0], |
1415 | const_cast<char *const *>(argv), |
1416 | const_cast<char *const *>(envp)); |
1417 | exit(eExecFailed); |
1418 | } |
1419 | |
1420 | // Wait for the child process to to trap on its call to execve. |
1421 | lldb::pid_t wpid; |
1422 | ::pid_t raw_pid; |
1423 | int status; |
1424 | |
1425 | raw_pid = waitpid(pid, &status, 0); |
1426 | wpid = static_cast <lldb::pid_t> (raw_pid); |
1427 | if (raw_pid < 0) |
1428 | { |
1429 | args->m_error.SetErrorToErrno(); |
1430 | goto FINISH; |
1431 | } |
1432 | else if (WIFEXITED(status)((((*(int *) &(status))) & 0x7f) == 0)) |
1433 | { |
1434 | // open, dup or execve likely failed for some reason. |
1435 | args->m_error.SetErrorToGenericError(); |
1436 | switch (WEXITSTATUS(status)((((*(int *) &(status))) & 0xff00) >> 8)) |
1437 | { |
1438 | case ePtraceFailed: |
1439 | args->m_error.SetErrorString("Child ptrace failed."); |
1440 | break; |
1441 | case eDupStdinFailed: |
1442 | args->m_error.SetErrorString("Child open stdin failed."); |
1443 | break; |
1444 | case eDupStdoutFailed: |
1445 | args->m_error.SetErrorString("Child open stdout failed."); |
1446 | break; |
1447 | case eDupStderrFailed: |
1448 | args->m_error.SetErrorString("Child open stderr failed."); |
1449 | break; |
1450 | case eChdirFailed: |
1451 | args->m_error.SetErrorString("Child failed to set working directory."); |
1452 | break; |
1453 | case eExecFailed: |
1454 | args->m_error.SetErrorString("Child exec failed."); |
1455 | break; |
1456 | case eSetGidFailed: |
1457 | args->m_error.SetErrorString("Child setgid failed."); |
1458 | break; |
1459 | default: |
1460 | args->m_error.SetErrorString("Child returned unknown exit status."); |
1461 | break; |
1462 | } |
1463 | goto FINISH; |
1464 | } |
1465 | assert(WIFSTOPPED(status) && wpid == pid &&((((((*(int *) &(status))) & 0xff) == 0x7f) && wpid == pid && "Could not sync with inferior process." ) ? static_cast<void> (0) : __assert_fail ("((((*(int *) &(status))) & 0xff) == 0x7f) && wpid == pid && \"Could not sync with inferior process.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1466, __PRETTY_FUNCTION__)) |
1466 | "Could not sync with inferior process.")((((((*(int *) &(status))) & 0xff) == 0x7f) && wpid == pid && "Could not sync with inferior process." ) ? static_cast<void> (0) : __assert_fail ("((((*(int *) &(status))) & 0xff) == 0x7f) && wpid == pid && \"Could not sync with inferior process.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1466, __PRETTY_FUNCTION__)); |
1467 | |
1468 | if (!SetDefaultPtraceOpts(pid)) |
1469 | { |
1470 | args->m_error.SetErrorToErrno(); |
1471 | goto FINISH; |
1472 | } |
1473 | |
1474 | // Release the master terminal descriptor and pass it off to the |
1475 | // ProcessMonitor instance. Similarly stash the inferior pid. |
1476 | monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor(); |
1477 | monitor->m_pid = pid; |
1478 | |
1479 | // Set the terminal fd to be in non blocking mode (it simplifies the |
1480 | // implementation of ProcessLinux::GetSTDOUT to have a non-blocking |
1481 | // descriptor to read from). |
1482 | if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK04000, args->m_error)) |
1483 | goto FINISH; |
1484 | |
1485 | // Update the process thread list with this new thread. |
1486 | // FIXME: should we be letting UpdateThreadList handle this? |
1487 | // FIXME: by using pids instead of tids, we can only support one thread. |
1488 | inferior.reset(process.CreateNewPOSIXThread(process, pid)); |
1489 | |
1490 | if (log) |
1491 | log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1492 | process.GetThreadList().AddThread(inferior); |
1493 | |
1494 | process.AddThreadForInitialStopIfNeeded(pid); |
1495 | |
1496 | // Let our process instance know the thread has stopped. |
1497 | process.SendMessage(ProcessMessage::Trace(pid)); |
1498 | |
1499 | FINISH: |
1500 | return args->m_error.Success(); |
1501 | } |
1502 | |
1503 | void |
1504 | ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error) |
1505 | { |
1506 | static const char *g_thread_name = "lldb.process.linux.operation"; |
1507 | |
1508 | if (m_operation_thread.IsJoinable()) |
1509 | return; |
1510 | |
1511 | m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error); |
1512 | } |
1513 | |
1514 | void * |
1515 | ProcessMonitor::AttachOpThread(void *arg) |
1516 | { |
1517 | AttachArgs *args = static_cast<AttachArgs*>(arg); |
1518 | |
1519 | if (!Attach(args)) { |
1520 | sem_post(&args->m_semaphore); |
1521 | return NULL__null; |
1522 | } |
1523 | |
1524 | ServeOperation(args); |
1525 | return NULL__null; |
1526 | } |
1527 | |
1528 | bool |
1529 | ProcessMonitor::Attach(AttachArgs *args) |
1530 | { |
1531 | lldb::pid_t pid = args->m_pid; |
1532 | |
1533 | ProcessMonitor *monitor = args->m_monitor; |
1534 | ProcessLinux &process = monitor->GetProcess(); |
1535 | lldb::ThreadSP inferior; |
1536 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1537 | |
1538 | // Use a map to keep track of the threads which we have attached/need to attach. |
1539 | Host::TidMap tids_to_attach; |
1540 | if (pid <= 1) |
1541 | { |
1542 | args->m_error.SetErrorToGenericError(); |
1543 | args->m_error.SetErrorString("Attaching to process 1 is not allowed."); |
1544 | goto FINISH; |
1545 | } |
1546 | |
1547 | while (Host::FindProcessThreads(pid, tids_to_attach)) |
1548 | { |
1549 | for (Host::TidMap::iterator it = tids_to_attach.begin(); |
1550 | it != tids_to_attach.end(); ++it) |
1551 | { |
1552 | if (it->second == false) |
1553 | { |
1554 | lldb::tid_t tid = it->first; |
1555 | |
1556 | // Attach to the requested process. |
1557 | // An attach will cause the thread to stop with a SIGSTOP. |
1558 | if (PTRACE(PTRACE_ATTACH, tid, NULL, NULL, 0)PtraceWrapper((PTRACE_ATTACH), (tid), (__null), (__null), (0) , "PTRACE_ATTACH", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1558) < 0) |
1559 | { |
1560 | // No such thread. The thread may have exited. |
1561 | // More error handling may be needed. |
1562 | if (errno(*__errno_location ()) == ESRCH3) |
1563 | { |
1564 | tids_to_attach.erase(it); |
1565 | continue; |
1566 | } |
1567 | else |
1568 | { |
1569 | args->m_error.SetErrorToErrno(); |
1570 | goto FINISH; |
1571 | } |
1572 | } |
1573 | |
1574 | ::pid_t wpid; |
1575 | // Need to use __WALL otherwise we receive an error with errno=ECHLD |
1576 | // At this point we should have a thread stopped if waitpid succeeds. |
1577 | if ((wpid = waitpid(tid, NULL__null, __WALL0x40000000)) < 0) |
1578 | { |
1579 | // No such thread. The thread may have exited. |
1580 | // More error handling may be needed. |
1581 | if (errno(*__errno_location ()) == ESRCH3) |
1582 | { |
1583 | tids_to_attach.erase(it); |
1584 | continue; |
1585 | } |
1586 | else |
1587 | { |
1588 | args->m_error.SetErrorToErrno(); |
1589 | goto FINISH; |
1590 | } |
1591 | } |
1592 | |
1593 | if (!SetDefaultPtraceOpts(tid)) |
1594 | { |
1595 | args->m_error.SetErrorToErrno(); |
1596 | goto FINISH; |
1597 | } |
1598 | |
1599 | // Update the process thread list with the attached thread. |
1600 | inferior.reset(process.CreateNewPOSIXThread(process, tid)); |
1601 | |
1602 | if (log) |
1603 | log->Printf ("ProcessMonitor::%s() adding tid = %" PRIu64"l" "u", __FUNCTION__, tid); |
1604 | process.GetThreadList().AddThread(inferior); |
1605 | it->second = true; |
1606 | process.AddThreadForInitialStopIfNeeded(tid); |
1607 | } |
1608 | } |
1609 | } |
1610 | |
1611 | if (tids_to_attach.size() > 0) |
1612 | { |
1613 | monitor->m_pid = pid; |
1614 | // Let our process instance know the thread has stopped. |
1615 | process.SendMessage(ProcessMessage::Trace(pid)); |
1616 | } |
1617 | else |
1618 | { |
1619 | args->m_error.SetErrorToGenericError(); |
1620 | args->m_error.SetErrorString("No such process."); |
1621 | } |
1622 | |
1623 | FINISH: |
1624 | return args->m_error.Success(); |
1625 | } |
1626 | |
1627 | bool |
1628 | ProcessMonitor::SetDefaultPtraceOpts(lldb::pid_t pid) |
1629 | { |
1630 | long ptrace_opts = 0; |
1631 | |
1632 | // Have the child raise an event on exit. This is used to keep the child in |
1633 | // limbo until it is destroyed. |
1634 | ptrace_opts |= PTRACE_O_TRACEEXIT; |
1635 | |
1636 | // Have the tracer trace threads which spawn in the inferior process. |
1637 | // TODO: if we want to support tracing the inferiors' child, add the |
1638 | // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK) |
1639 | ptrace_opts |= PTRACE_O_TRACECLONE; |
1640 | |
1641 | // Have the tracer notify us before execve returns |
1642 | // (needed to disable legacy SIGTRAP generation) |
1643 | ptrace_opts |= PTRACE_O_TRACEEXEC; |
1644 | |
1645 | return PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts, 0)PtraceWrapper((PTRACE_SETOPTIONS), (pid), (__null), ((void*)ptrace_opts ), (0), "PTRACE_SETOPTIONS", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1645) >= 0; |
1646 | } |
1647 | |
1648 | bool |
1649 | ProcessMonitor::MonitorCallback(void *callback_baton, |
1650 | lldb::pid_t pid, |
1651 | bool exited, |
1652 | int signal, |
1653 | int status) |
1654 | { |
1655 | ProcessMessage message; |
1656 | ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton); |
1657 | ProcessLinux *process = monitor->m_process; |
1658 | assert(process)((process) ? static_cast<void> (0) : __assert_fail ("process" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1658, __PRETTY_FUNCTION__)); |
1659 | bool stop_monitoring; |
1660 | siginfo_t info; |
1661 | int ptrace_err; |
1662 | |
1663 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1664 | |
1665 | if (exited) |
1666 | { |
1667 | if (log) |
1668 | log->Printf ("ProcessMonitor::%s() got exit signal, tid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1669 | message = ProcessMessage::Exit(pid, status); |
1670 | process->SendMessage(message); |
1671 | return pid == process->GetID(); |
1672 | } |
1673 | |
1674 | if (!monitor->GetSignalInfo(pid, &info, ptrace_err)) { |
1675 | if (ptrace_err == EINVAL22) { |
1676 | if (log) |
1677 | log->Printf ("ProcessMonitor::%s() resuming from group-stop", __FUNCTION__); |
1678 | // inferior process is in 'group-stop', so deliver SIGSTOP signal |
1679 | if (!monitor->Resume(pid, SIGSTOP19)) { |
1680 | assert(0 && "SIGSTOP delivery failed while in 'group-stop' state")((0 && "SIGSTOP delivery failed while in 'group-stop' state" ) ? static_cast<void> (0) : __assert_fail ("0 && \"SIGSTOP delivery failed while in 'group-stop' state\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1680, __PRETTY_FUNCTION__)); |
1681 | } |
1682 | stop_monitoring = false; |
1683 | } else { |
1684 | // ptrace(GETSIGINFO) failed (but not due to group-stop). Most likely, |
1685 | // this means the child pid is gone (or not being debugged) therefore |
1686 | // stop the monitor thread if this is the main pid. |
1687 | if (log) |
1688 | log->Printf ("ProcessMonitor::%s() GetSignalInfo failed: %s, tid = %" PRIu64"l" "u" ", signal = %d, status = %d", |
1689 | __FUNCTION__, strerror(ptrace_err), pid, signal, status); |
1690 | stop_monitoring = pid == monitor->m_process->GetID(); |
1691 | // If we are going to stop monitoring, we need to notify our process object |
1692 | if (stop_monitoring) |
1693 | { |
1694 | message = ProcessMessage::Exit(pid, status); |
1695 | process->SendMessage(message); |
1696 | } |
1697 | } |
1698 | } |
1699 | else { |
1700 | switch (info.si_signo) |
1701 | { |
1702 | case SIGTRAP5: |
1703 | message = MonitorSIGTRAP(monitor, &info, pid); |
1704 | break; |
1705 | |
1706 | default: |
1707 | message = MonitorSignal(monitor, &info, pid); |
1708 | break; |
1709 | } |
1710 | |
1711 | process->SendMessage(message); |
1712 | stop_monitoring = false; |
1713 | } |
1714 | |
1715 | return stop_monitoring; |
1716 | } |
1717 | |
1718 | ProcessMessage |
1719 | ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, |
1720 | const siginfo_t *info, lldb::pid_t pid) |
1721 | { |
1722 | ProcessMessage message; |
1723 | |
1724 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1725 | |
1726 | assert(monitor)((monitor) ? static_cast<void> (0) : __assert_fail ("monitor" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1726, __PRETTY_FUNCTION__)); |
1727 | assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!")((info && info->si_signo == 5 && "Unexpected child signal!" ) ? static_cast<void> (0) : __assert_fail ("info && info->si_signo == 5 && \"Unexpected child signal!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1727, __PRETTY_FUNCTION__)); |
1728 | |
1729 | switch (info->si_code) |
1730 | { |
1731 | default: |
1732 | assert(false && "Unexpected SIGTRAP code!")((false && "Unexpected SIGTRAP code!") ? static_cast< void> (0) : __assert_fail ("false && \"Unexpected SIGTRAP code!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1732, __PRETTY_FUNCTION__)); |
1733 | break; |
1734 | |
1735 | // TODO: these two cases are required if we want to support tracing |
1736 | // of the inferiors' children |
1737 | // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)): |
1738 | // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)): |
1739 | |
1740 | case (SIGTRAP5 | (PTRACE_EVENT_CLONE << 8)): |
1741 | { |
1742 | if (log) |
1743 | log->Printf ("ProcessMonitor::%s() received thread creation event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP5); |
1744 | |
1745 | unsigned long tid = 0; |
1746 | if (!monitor->GetEventMessage(pid, &tid)) |
1747 | tid = -1; |
1748 | message = ProcessMessage::NewThread(pid, tid); |
1749 | break; |
1750 | } |
1751 | |
1752 | case (SIGTRAP5 | (PTRACE_EVENT_EXEC << 8)): |
1753 | if (log) |
1754 | log->Printf ("ProcessMonitor::%s() received exec event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP5); |
1755 | |
1756 | message = ProcessMessage::Exec(pid); |
1757 | break; |
1758 | |
1759 | case (SIGTRAP5 | (PTRACE_EVENT_EXIT << 8)): |
1760 | { |
1761 | // The inferior process or one of its threads is about to exit. |
1762 | // Maintain the process or thread in a state of "limbo" until we are |
1763 | // explicitly commanded to detach, destroy, resume, etc. |
1764 | unsigned long data = 0; |
1765 | if (!monitor->GetEventMessage(pid, &data)) |
1766 | data = -1; |
1767 | if (log) |
1768 | log->Printf ("ProcessMonitor::%s() received limbo event, data = %lx, pid = %" PRIu64"l" "u", __FUNCTION__, data, pid); |
1769 | message = ProcessMessage::Limbo(pid, (data >> 8)); |
1770 | break; |
1771 | } |
1772 | |
1773 | case 0: |
1774 | case TRAP_TRACETRAP_TRACE: |
1775 | if (log) |
1776 | log->Printf ("ProcessMonitor::%s() received trace event, pid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1777 | message = ProcessMessage::Trace(pid); |
1778 | break; |
1779 | |
1780 | case SI_KERNELSI_KERNEL: |
1781 | case TRAP_BRKPTTRAP_BRKPT: |
1782 | if (log) |
1783 | log->Printf ("ProcessMonitor::%s() received breakpoint event, pid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1784 | message = ProcessMessage::Break(pid); |
1785 | break; |
1786 | |
1787 | case TRAP_HWBKPT4: |
1788 | if (log) |
1789 | log->Printf ("ProcessMonitor::%s() received watchpoint event, pid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1790 | message = ProcessMessage::Watch(pid, (lldb::addr_t)info->si_addr_sifields._sigfault.si_addr); |
1791 | break; |
1792 | |
1793 | case SIGTRAP5: |
1794 | case (SIGTRAP5 | 0x80): |
1795 | if (log) |
1796 | log->Printf ("ProcessMonitor::%s() received system call stop event, pid = %" PRIu64"l" "u", __FUNCTION__, pid); |
1797 | // Ignore these signals until we know more about them |
1798 | monitor->Resume(pid, eResumeSignalNone); |
1799 | } |
1800 | |
1801 | return message; |
1802 | } |
1803 | |
1804 | ProcessMessage |
1805 | ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, |
1806 | const siginfo_t *info, lldb::pid_t pid) |
1807 | { |
1808 | ProcessMessage message; |
1809 | int signo = info->si_signo; |
1810 | |
1811 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1812 | |
1813 | // POSIX says that process behaviour is undefined after it ignores a SIGFPE, |
1814 | // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a |
1815 | // kill(2) or raise(3). Similarly for tgkill(2) on Linux. |
1816 | // |
1817 | // IOW, user generated signals never generate what we consider to be a |
1818 | // "crash". |
1819 | // |
1820 | // Similarly, ACK signals generated by this monitor. |
1821 | if (info->si_code == SI_TKILLSI_TKILL || info->si_code == SI_USERSI_USER) |
1822 | { |
1823 | if (log) |
1824 | log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d", |
1825 | __FUNCTION__, |
1826 | monitor->m_process->GetUnixSignals().GetSignalAsCString (signo), |
1827 | (info->si_code == SI_TKILLSI_TKILL ? "SI_TKILL" : "SI_USER"), |
1828 | info->si_pid_sifields._kill.si_pid); |
1829 | |
1830 | if (info->si_pid_sifields._kill.si_pid == getpid()) |
1831 | return ProcessMessage::SignalDelivered(pid, signo); |
1832 | else |
1833 | return ProcessMessage::Signal(pid, signo); |
1834 | } |
1835 | |
1836 | if (log) |
1837 | log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo)); |
1838 | |
1839 | if (signo == SIGSEGV11) { |
1840 | lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr_sifields._sigfault.si_addr); |
1841 | ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info); |
1842 | return ProcessMessage::Crash(pid, reason, signo, fault_addr); |
1843 | } |
1844 | |
1845 | if (signo == SIGILL4) { |
1846 | lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr_sifields._sigfault.si_addr); |
1847 | ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info); |
1848 | return ProcessMessage::Crash(pid, reason, signo, fault_addr); |
1849 | } |
1850 | |
1851 | if (signo == SIGFPE8) { |
1852 | lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr_sifields._sigfault.si_addr); |
1853 | ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info); |
1854 | return ProcessMessage::Crash(pid, reason, signo, fault_addr); |
1855 | } |
1856 | |
1857 | if (signo == SIGBUS7) { |
1858 | lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr_sifields._sigfault.si_addr); |
1859 | ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info); |
1860 | return ProcessMessage::Crash(pid, reason, signo, fault_addr); |
1861 | } |
1862 | |
1863 | // Everything else is "normal" and does not require any special action on |
1864 | // our part. |
1865 | return ProcessMessage::Signal(pid, signo); |
1866 | } |
1867 | |
1868 | // On Linux, when a new thread is created, we receive to notifications, |
1869 | // (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the |
1870 | // child thread id as additional information, and (2) a SIGSTOP|SI_USER from |
1871 | // the new child thread indicating that it has is stopped because we attached. |
1872 | // We have no guarantee of the order in which these arrive, but we need both |
1873 | // before we are ready to proceed. We currently keep a list of threads which |
1874 | // have sent the initial SIGSTOP|SI_USER event. Then when we receive the |
1875 | // SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not occurred |
1876 | // we call ProcessMonitor::WaitForInitialTIDStop() to wait for it. |
1877 | |
1878 | bool |
1879 | ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) |
1880 | { |
1881 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1882 | if (log) |
1883 | log->Printf ("ProcessMonitor::%s(%" PRIu64"l" "u" ") waiting for thread to stop...", __FUNCTION__, tid); |
1884 | |
1885 | // Wait for the thread to stop |
1886 | while (true) |
1887 | { |
1888 | int status = -1; |
1889 | if (log) |
1890 | log->Printf ("ProcessMonitor::%s(%" PRIu64"l" "u" ") waitpid...", __FUNCTION__, tid); |
1891 | ::pid_t wait_pid = waitpid(tid, &status, __WALL0x40000000); |
1892 | if (status == -1) |
1893 | { |
1894 | // If we got interrupted by a signal (in our process, not the |
1895 | // inferior) try again. |
1896 | if (errno(*__errno_location ()) == EINTR4) |
1897 | continue; |
1898 | else |
1899 | { |
1900 | if (log) |
1901 | log->Printf("ProcessMonitor::%s(%" PRIu64"l" "u" ") waitpid error -- %s", __FUNCTION__, tid, strerror(errno(*__errno_location ()))); |
1902 | return false; // This is bad, but there's nothing we can do. |
1903 | } |
1904 | } |
1905 | |
1906 | if (log) |
1907 | log->Printf ("ProcessMonitor::%s(%" PRIu64"l" "u" ") waitpid, status = %d", __FUNCTION__, tid, status); |
1908 | |
1909 | assert(static_cast<lldb::tid_t>(wait_pid) == tid)((static_cast<lldb::tid_t>(wait_pid) == tid) ? static_cast <void> (0) : __assert_fail ("static_cast<lldb::tid_t>(wait_pid) == tid" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1909, __PRETTY_FUNCTION__)); |
1910 | |
1911 | siginfo_t info; |
1912 | int ptrace_err; |
1913 | if (!GetSignalInfo(wait_pid, &info, ptrace_err)) |
1914 | { |
1915 | if (log) |
1916 | { |
1917 | log->Printf ("ProcessMonitor::%s() GetSignalInfo failed. errno=%d (%s)", __FUNCTION__, ptrace_err, strerror(ptrace_err)); |
1918 | } |
1919 | return false; |
1920 | } |
1921 | |
1922 | // If this is a thread exit, we won't get any more information. |
1923 | if (WIFEXITED(status)((((*(int *) &(status))) & 0x7f) == 0)) |
1924 | { |
1925 | m_process->SendMessage(ProcessMessage::Exit(wait_pid, WEXITSTATUS(status)((((*(int *) &(status))) & 0xff00) >> 8))); |
1926 | if (static_cast<lldb::tid_t>(wait_pid) == tid) |
1927 | return true; |
1928 | continue; |
1929 | } |
1930 | |
1931 | assert(info.si_code == SI_USER)((info.si_code == SI_USER) ? static_cast<void> (0) : __assert_fail ("info.si_code == SI_USER", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1931, __PRETTY_FUNCTION__)); |
1932 | assert(WSTOPSIG(status) == SIGSTOP)((((((*(int *) &(status))) & 0xff00) >> 8) == 19 ) ? static_cast<void> (0) : __assert_fail ("((((*(int *) &(status))) & 0xff00) >> 8) == 19" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1932, __PRETTY_FUNCTION__)); |
1933 | |
1934 | if (log) |
1935 | log->Printf ("ProcessMonitor::%s(bp) received thread stop signal", __FUNCTION__); |
1936 | m_process->AddThreadForInitialStopIfNeeded(wait_pid); |
1937 | return true; |
1938 | } |
1939 | return false; |
1940 | } |
1941 | |
1942 | bool |
1943 | ProcessMonitor::StopThread(lldb::tid_t tid) |
1944 | { |
1945 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
1946 | |
1947 | // FIXME: Try to use tgkill or tkill |
1948 | int ret = tgkill(m_pid, tid, SIGSTOP)syscall(234, m_pid, tid, 19); |
1949 | if (log) |
1950 | log->Printf ("ProcessMonitor::%s(bp) stopping thread, tid = %" PRIu64"l" "u" ", ret = %d", __FUNCTION__, tid, ret); |
1951 | |
1952 | // This can happen if a thread exited while we were trying to stop it. That's OK. |
1953 | // We'll get the signal for that later. |
1954 | if (ret < 0) |
1955 | return false; |
1956 | |
1957 | // Wait for the thread to stop |
1958 | while (true) |
1959 | { |
1960 | int status = -1; |
1961 | if (log) |
1962 | log->Printf ("ProcessMonitor::%s(bp) waitpid...", __FUNCTION__); |
1963 | ::pid_t wait_pid = ::waitpid (-1*getpgid(m_pid), &status, __WALL0x40000000); |
1964 | if (log) |
1965 | log->Printf ("ProcessMonitor::%s(bp) waitpid, pid = %" PRIu64"l" "u" ", status = %d", |
1966 | __FUNCTION__, static_cast<lldb::pid_t>(wait_pid), status); |
1967 | |
1968 | if (wait_pid == -1) |
1969 | { |
1970 | // If we got interrupted by a signal (in our process, not the |
1971 | // inferior) try again. |
1972 | if (errno(*__errno_location ()) == EINTR4) |
1973 | continue; |
1974 | else |
1975 | return false; // This is bad, but there's nothing we can do. |
1976 | } |
1977 | |
1978 | // If this is a thread exit, we won't get any more information. |
1979 | if (WIFEXITED(status)((((*(int *) &(status))) & 0x7f) == 0)) |
1980 | { |
1981 | m_process->SendMessage(ProcessMessage::Exit(wait_pid, WEXITSTATUS(status)((((*(int *) &(status))) & 0xff00) >> 8))); |
1982 | if (static_cast<lldb::tid_t>(wait_pid) == tid) |
1983 | return true; |
1984 | continue; |
1985 | } |
1986 | |
1987 | siginfo_t info; |
1988 | int ptrace_err; |
1989 | if (!GetSignalInfo(wait_pid, &info, ptrace_err)) |
1990 | { |
1991 | // another signal causing a StopAllThreads may have been received |
1992 | // before wait_pid's group-stop was processed, handle it now |
1993 | if (ptrace_err == EINVAL22) |
1994 | { |
1995 | assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)((((((*(int *) &(status))) & 0xff) == 0x7f) && ((((*(int *) &(status))) & 0xff00) >> 8) == 19 ) ? static_cast<void> (0) : __assert_fail ("((((*(int *) &(status))) & 0xff) == 0x7f) && ((((*(int *) &(status))) & 0xff00) >> 8) == 19" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 1995, __PRETTY_FUNCTION__)); |
1996 | |
1997 | if (log) |
1998 | log->Printf ("ProcessMonitor::%s() resuming from group-stop", __FUNCTION__); |
1999 | // inferior process is in 'group-stop', so deliver SIGSTOP signal |
2000 | if (!Resume(wait_pid, SIGSTOP19)) { |
2001 | assert(0 && "SIGSTOP delivery failed while in 'group-stop' state")((0 && "SIGSTOP delivery failed while in 'group-stop' state" ) ? static_cast<void> (0) : __assert_fail ("0 && \"SIGSTOP delivery failed while in 'group-stop' state\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2001, __PRETTY_FUNCTION__)); |
2002 | } |
2003 | continue; |
2004 | } |
2005 | |
2006 | if (log) |
2007 | log->Printf ("ProcessMonitor::%s() GetSignalInfo failed.", __FUNCTION__); |
2008 | return false; |
2009 | } |
2010 | |
2011 | // Handle events from other threads |
2012 | if (log) |
2013 | log->Printf ("ProcessMonitor::%s(bp) handling event, tid == %" PRIu64"l" "u", |
2014 | __FUNCTION__, static_cast<lldb::tid_t>(wait_pid)); |
2015 | |
2016 | ProcessMessage message; |
2017 | if (info.si_signo == SIGTRAP5) |
2018 | message = MonitorSIGTRAP(this, &info, wait_pid); |
2019 | else |
2020 | message = MonitorSignal(this, &info, wait_pid); |
2021 | |
2022 | POSIXThread *thread = static_cast<POSIXThread*>(m_process->GetThreadList().FindThreadByID(wait_pid).get()); |
2023 | |
2024 | // When a new thread is created, we may get a SIGSTOP for the new thread |
2025 | // just before we get the SIGTRAP that we use to add the thread to our |
2026 | // process thread list. We don't need to worry about that signal here. |
2027 | assert(thread || message.GetKind() == ProcessMessage::eSignalMessage)((thread || message.GetKind() == ProcessMessage::eSignalMessage ) ? static_cast<void> (0) : __assert_fail ("thread || message.GetKind() == ProcessMessage::eSignalMessage" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2027, __PRETTY_FUNCTION__)); |
2028 | |
2029 | if (!thread) |
2030 | { |
2031 | m_process->SendMessage(message); |
2032 | continue; |
2033 | } |
2034 | |
2035 | switch (message.GetKind()) |
2036 | { |
2037 | case ProcessMessage::eExecMessage: |
2038 | llvm_unreachable("unexpected message")::llvm::llvm_unreachable_internal("unexpected message", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2038); |
2039 | case ProcessMessage::eAttachMessage: |
2040 | case ProcessMessage::eInvalidMessage: |
2041 | break; |
2042 | |
2043 | // These need special handling because we don't want to send a |
2044 | // resume even if we already sent a SIGSTOP to this thread. In |
2045 | // this case the resume will cause the thread to disappear. It is |
2046 | // unlikely that we'll ever get eExitMessage here, but the same |
2047 | // reasoning applies. |
2048 | case ProcessMessage::eLimboMessage: |
2049 | case ProcessMessage::eExitMessage: |
2050 | if (log) |
2051 | log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__); |
2052 | // SendMessage will set the thread state as needed. |
2053 | m_process->SendMessage(message); |
2054 | // If this is the thread we're waiting for, stop waiting. Even |
2055 | // though this wasn't the signal we expected, it's the last |
2056 | // signal we'll see while this thread is alive. |
2057 | if (static_cast<lldb::tid_t>(wait_pid) == tid) |
2058 | return true; |
2059 | break; |
2060 | |
2061 | case ProcessMessage::eSignalMessage: |
2062 | if (log) |
2063 | log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__); |
2064 | if (WSTOPSIG(status)((((*(int *) &(status))) & 0xff00) >> 8) == SIGSTOP19) |
2065 | { |
2066 | m_process->AddThreadForInitialStopIfNeeded(tid); |
2067 | thread->SetState(lldb::eStateStopped); |
2068 | } |
2069 | else |
2070 | { |
2071 | m_process->SendMessage(message); |
2072 | // This isn't the stop we were expecting, but the thread is |
2073 | // stopped. SendMessage will handle processing of this event, |
2074 | // but we need to resume here to get the stop we are waiting |
2075 | // for (otherwise the thread will stop again immediately when |
2076 | // we try to resume). |
2077 | if (static_cast<lldb::tid_t>(wait_pid) == tid) |
2078 | Resume(wait_pid, eResumeSignalNone); |
2079 | } |
2080 | break; |
2081 | |
2082 | case ProcessMessage::eSignalDeliveredMessage: |
2083 | // This is the stop we're expecting. |
2084 | if (static_cast<lldb::tid_t>(wait_pid) == tid && |
2085 | WIFSTOPPED(status)((((*(int *) &(status))) & 0xff) == 0x7f) && |
2086 | WSTOPSIG(status)((((*(int *) &(status))) & 0xff00) >> 8) == SIGSTOP19 && |
2087 | info.si_code == SI_TKILLSI_TKILL) |
2088 | { |
2089 | if (log) |
2090 | log->Printf ("ProcessMonitor::%s(bp) received signal, done waiting", __FUNCTION__); |
2091 | thread->SetState(lldb::eStateStopped); |
2092 | return true; |
2093 | } |
2094 | // else fall-through |
2095 | case ProcessMessage::eBreakpointMessage: |
2096 | case ProcessMessage::eTraceMessage: |
2097 | case ProcessMessage::eWatchpointMessage: |
2098 | case ProcessMessage::eCrashMessage: |
2099 | case ProcessMessage::eNewThreadMessage: |
2100 | if (log) |
2101 | log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__); |
2102 | // SendMessage will set the thread state as needed. |
2103 | m_process->SendMessage(message); |
2104 | // This isn't the stop we were expecting, but the thread is |
2105 | // stopped. SendMessage will handle processing of this event, |
2106 | // but we need to resume here to get the stop we are waiting |
2107 | // for (otherwise the thread will stop again immediately when |
2108 | // we try to resume). |
2109 | if (static_cast<lldb::tid_t>(wait_pid) == tid) |
2110 | Resume(wait_pid, eResumeSignalNone); |
2111 | break; |
2112 | } |
2113 | } |
2114 | return false; |
2115 | } |
2116 | |
2117 | ProcessMessage::CrashReason |
2118 | ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info) |
2119 | { |
2120 | ProcessMessage::CrashReason reason; |
2121 | assert(info->si_signo == SIGSEGV)((info->si_signo == 11) ? static_cast<void> (0) : __assert_fail ("info->si_signo == 11", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2121, __PRETTY_FUNCTION__)); |
2122 | |
2123 | reason = ProcessMessage::eInvalidCrashReason; |
Value stored to 'reason' is never read | |
2124 | |
2125 | switch (info->si_code) |
2126 | { |
2127 | default: |
2128 | assert(false && "unexpected si_code for SIGSEGV")((false && "unexpected si_code for SIGSEGV") ? static_cast <void> (0) : __assert_fail ("false && \"unexpected si_code for SIGSEGV\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2128, __PRETTY_FUNCTION__)); |
2129 | break; |
2130 | case SI_KERNELSI_KERNEL: |
2131 | // Linux will occasionally send spurious SI_KERNEL codes. |
2132 | // (this is poorly documented in sigaction) |
2133 | // One way to get this is via unaligned SIMD loads. |
2134 | reason = ProcessMessage::eInvalidAddress; // for lack of anything better |
2135 | break; |
2136 | case SEGV_MAPERRSEGV_MAPERR: |
2137 | reason = ProcessMessage::eInvalidAddress; |
2138 | break; |
2139 | case SEGV_ACCERRSEGV_ACCERR: |
2140 | reason = ProcessMessage::ePrivilegedAddress; |
2141 | break; |
2142 | } |
2143 | |
2144 | return reason; |
2145 | } |
2146 | |
2147 | ProcessMessage::CrashReason |
2148 | ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info) |
2149 | { |
2150 | ProcessMessage::CrashReason reason; |
2151 | assert(info->si_signo == SIGILL)((info->si_signo == 4) ? static_cast<void> (0) : __assert_fail ("info->si_signo == 4", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2151, __PRETTY_FUNCTION__)); |
2152 | |
2153 | reason = ProcessMessage::eInvalidCrashReason; |
2154 | |
2155 | switch (info->si_code) |
2156 | { |
2157 | default: |
2158 | assert(false && "unexpected si_code for SIGILL")((false && "unexpected si_code for SIGILL") ? static_cast <void> (0) : __assert_fail ("false && \"unexpected si_code for SIGILL\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2158, __PRETTY_FUNCTION__)); |
2159 | break; |
2160 | case ILL_ILLOPCILL_ILLOPC: |
2161 | reason = ProcessMessage::eIllegalOpcode; |
2162 | break; |
2163 | case ILL_ILLOPNILL_ILLOPN: |
2164 | reason = ProcessMessage::eIllegalOperand; |
2165 | break; |
2166 | case ILL_ILLADRILL_ILLADR: |
2167 | reason = ProcessMessage::eIllegalAddressingMode; |
2168 | break; |
2169 | case ILL_ILLTRPILL_ILLTRP: |
2170 | reason = ProcessMessage::eIllegalTrap; |
2171 | break; |
2172 | case ILL_PRVOPCILL_PRVOPC: |
2173 | reason = ProcessMessage::ePrivilegedOpcode; |
2174 | break; |
2175 | case ILL_PRVREGILL_PRVREG: |
2176 | reason = ProcessMessage::ePrivilegedRegister; |
2177 | break; |
2178 | case ILL_COPROCILL_COPROC: |
2179 | reason = ProcessMessage::eCoprocessorError; |
2180 | break; |
2181 | case ILL_BADSTKILL_BADSTK: |
2182 | reason = ProcessMessage::eInternalStackError; |
2183 | break; |
2184 | } |
2185 | |
2186 | return reason; |
2187 | } |
2188 | |
2189 | ProcessMessage::CrashReason |
2190 | ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info) |
2191 | { |
2192 | ProcessMessage::CrashReason reason; |
2193 | assert(info->si_signo == SIGFPE)((info->si_signo == 8) ? static_cast<void> (0) : __assert_fail ("info->si_signo == 8", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2193, __PRETTY_FUNCTION__)); |
2194 | |
2195 | reason = ProcessMessage::eInvalidCrashReason; |
2196 | |
2197 | switch (info->si_code) |
2198 | { |
2199 | default: |
2200 | assert(false && "unexpected si_code for SIGFPE")((false && "unexpected si_code for SIGFPE") ? static_cast <void> (0) : __assert_fail ("false && \"unexpected si_code for SIGFPE\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2200, __PRETTY_FUNCTION__)); |
2201 | break; |
2202 | case FPE_INTDIVFPE_INTDIV: |
2203 | reason = ProcessMessage::eIntegerDivideByZero; |
2204 | break; |
2205 | case FPE_INTOVFFPE_INTOVF: |
2206 | reason = ProcessMessage::eIntegerOverflow; |
2207 | break; |
2208 | case FPE_FLTDIVFPE_FLTDIV: |
2209 | reason = ProcessMessage::eFloatDivideByZero; |
2210 | break; |
2211 | case FPE_FLTOVFFPE_FLTOVF: |
2212 | reason = ProcessMessage::eFloatOverflow; |
2213 | break; |
2214 | case FPE_FLTUNDFPE_FLTUND: |
2215 | reason = ProcessMessage::eFloatUnderflow; |
2216 | break; |
2217 | case FPE_FLTRESFPE_FLTRES: |
2218 | reason = ProcessMessage::eFloatInexactResult; |
2219 | break; |
2220 | case FPE_FLTINVFPE_FLTINV: |
2221 | reason = ProcessMessage::eFloatInvalidOperation; |
2222 | break; |
2223 | case FPE_FLTSUBFPE_FLTSUB: |
2224 | reason = ProcessMessage::eFloatSubscriptRange; |
2225 | break; |
2226 | } |
2227 | |
2228 | return reason; |
2229 | } |
2230 | |
2231 | ProcessMessage::CrashReason |
2232 | ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info) |
2233 | { |
2234 | ProcessMessage::CrashReason reason; |
2235 | assert(info->si_signo == SIGBUS)((info->si_signo == 7) ? static_cast<void> (0) : __assert_fail ("info->si_signo == 7", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2235, __PRETTY_FUNCTION__)); |
2236 | |
2237 | reason = ProcessMessage::eInvalidCrashReason; |
2238 | |
2239 | switch (info->si_code) |
2240 | { |
2241 | default: |
2242 | assert(false && "unexpected si_code for SIGBUS")((false && "unexpected si_code for SIGBUS") ? static_cast <void> (0) : __assert_fail ("false && \"unexpected si_code for SIGBUS\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2242, __PRETTY_FUNCTION__)); |
2243 | break; |
2244 | case BUS_ADRALNBUS_ADRALN: |
2245 | reason = ProcessMessage::eIllegalAlignment; |
2246 | break; |
2247 | case BUS_ADRERRBUS_ADRERR: |
2248 | reason = ProcessMessage::eIllegalAddress; |
2249 | break; |
2250 | case BUS_OBJERRBUS_OBJERR: |
2251 | reason = ProcessMessage::eHardwareError; |
2252 | break; |
2253 | } |
2254 | |
2255 | return reason; |
2256 | } |
2257 | |
2258 | void |
2259 | ProcessMonitor::ServeOperation(OperationArgs *args) |
2260 | { |
2261 | ProcessMonitor *monitor = args->m_monitor; |
2262 | |
2263 | // We are finised with the arguments and are ready to go. Sync with the |
2264 | // parent thread and start serving operations on the inferior. |
2265 | sem_post(&args->m_semaphore); |
2266 | |
2267 | for(;;) |
2268 | { |
2269 | // wait for next pending operation |
2270 | if (sem_wait(&monitor->m_operation_pending)) |
2271 | { |
2272 | if (errno(*__errno_location ()) == EINTR4) |
2273 | continue; |
2274 | assert(false && "Unexpected errno from sem_wait")((false && "Unexpected errno from sem_wait") ? static_cast <void> (0) : __assert_fail ("false && \"Unexpected errno from sem_wait\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2274, __PRETTY_FUNCTION__)); |
2275 | } |
2276 | |
2277 | monitor->m_operation->Execute(monitor); |
2278 | |
2279 | // notify calling thread that operation is complete |
2280 | sem_post(&monitor->m_operation_done); |
2281 | } |
2282 | } |
2283 | |
2284 | void |
2285 | ProcessMonitor::DoOperation(Operation *op) |
2286 | { |
2287 | Mutex::Locker lock(m_operation_mutex); |
2288 | |
2289 | m_operation = op; |
2290 | |
2291 | // notify operation thread that an operation is ready to be processed |
2292 | sem_post(&m_operation_pending); |
2293 | |
2294 | // wait for operation to complete |
2295 | while (sem_wait(&m_operation_done)) |
2296 | { |
2297 | if (errno(*__errno_location ()) == EINTR4) |
2298 | continue; |
2299 | assert(false && "Unexpected errno from sem_wait")((false && "Unexpected errno from sem_wait") ? static_cast <void> (0) : __assert_fail ("false && \"Unexpected errno from sem_wait\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn227765/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp" , 2299, __PRETTY_FUNCTION__)); |
2300 | } |
2301 | } |
2302 | |
2303 | size_t |
2304 | ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, |
2305 | Error &error) |
2306 | { |
2307 | size_t result; |
2308 | ReadOperation op(vm_addr, buf, size, error, result); |
2309 | DoOperation(&op); |
2310 | return result; |
2311 | } |
2312 | |
2313 | size_t |
2314 | ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, |
2315 | lldb_private::Error &error) |
2316 | { |
2317 | size_t result; |
2318 | WriteOperation op(vm_addr, buf, size, error, result); |
2319 | DoOperation(&op); |
2320 | return result; |
2321 | } |
2322 | |
2323 | bool |
2324 | ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char* reg_name, |
2325 | unsigned size, RegisterValue &value) |
2326 | { |
2327 | bool result; |
2328 | ReadRegOperation op(tid, offset, reg_name, value, result); |
2329 | DoOperation(&op); |
2330 | return result; |
2331 | } |
2332 | |
2333 | bool |
2334 | ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset, |
2335 | const char* reg_name, const RegisterValue &value) |
2336 | { |
2337 | bool result; |
2338 | WriteRegOperation op(tid, offset, reg_name, value, result); |
2339 | DoOperation(&op); |
2340 | return result; |
2341 | } |
2342 | |
2343 | bool |
2344 | ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) |
2345 | { |
2346 | bool result; |
2347 | ReadGPROperation op(tid, buf, buf_size, result); |
2348 | DoOperation(&op); |
2349 | return result; |
2350 | } |
2351 | |
2352 | bool |
2353 | ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) |
2354 | { |
2355 | bool result; |
2356 | ReadFPROperation op(tid, buf, buf_size, result); |
2357 | DoOperation(&op); |
2358 | return result; |
2359 | } |
2360 | |
2361 | bool |
2362 | ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) |
2363 | { |
2364 | bool result; |
2365 | ReadRegisterSetOperation op(tid, buf, buf_size, regset, result); |
2366 | DoOperation(&op); |
2367 | return result; |
2368 | } |
2369 | |
2370 | bool |
2371 | ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) |
2372 | { |
2373 | bool result; |
2374 | WriteGPROperation op(tid, buf, buf_size, result); |
2375 | DoOperation(&op); |
2376 | return result; |
2377 | } |
2378 | |
2379 | bool |
2380 | ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) |
2381 | { |
2382 | bool result; |
2383 | WriteFPROperation op(tid, buf, buf_size, result); |
2384 | DoOperation(&op); |
2385 | return result; |
2386 | } |
2387 | |
2388 | bool |
2389 | ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) |
2390 | { |
2391 | bool result; |
2392 | WriteRegisterSetOperation op(tid, buf, buf_size, regset, result); |
2393 | DoOperation(&op); |
2394 | return result; |
2395 | } |
2396 | |
2397 | bool |
2398 | ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) |
2399 | { |
2400 | bool result; |
2401 | ReadThreadPointerOperation op(tid, &value, result); |
2402 | DoOperation(&op); |
2403 | return result; |
2404 | } |
2405 | |
2406 | bool |
2407 | ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo) |
2408 | { |
2409 | bool result; |
2410 | Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS(1u << 1))); |
2411 | |
2412 | if (log) |
2413 | log->Printf ("ProcessMonitor::%s() resuming thread = %" PRIu64"l" "u" " with signal %s", __FUNCTION__, tid, |
2414 | m_process->GetUnixSignals().GetSignalAsCString (signo)); |
2415 | ResumeOperation op(tid, signo, result); |
2416 | DoOperation(&op); |
2417 | if (log) |
2418 | log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false"); |
2419 | return result; |
2420 | } |
2421 | |
2422 | bool |
2423 | ProcessMonitor::SingleStep(lldb::tid_t tid, uint32_t signo) |
2424 | { |
2425 | bool result; |
2426 | SingleStepOperation op(tid, signo, result); |
2427 | DoOperation(&op); |
2428 | return result; |
2429 | } |
2430 | |
2431 | bool |
2432 | ProcessMonitor::Kill() |
2433 | { |
2434 | return kill(GetPID(), SIGKILL9) == 0; |
2435 | } |
2436 | |
2437 | bool |
2438 | ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err) |
2439 | { |
2440 | bool result; |
2441 | SiginfoOperation op(tid, siginfo, result, ptrace_err); |
2442 | DoOperation(&op); |
2443 | return result; |
2444 | } |
2445 | |
2446 | bool |
2447 | ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) |
2448 | { |
2449 | bool result; |
2450 | EventMessageOperation op(tid, message, result); |
2451 | DoOperation(&op); |
2452 | return result; |
2453 | } |
2454 | |
2455 | lldb_private::Error |
2456 | ProcessMonitor::Detach(lldb::tid_t tid) |
2457 | { |
2458 | lldb_private::Error error; |
2459 | if (tid != LLDB_INVALID_THREAD_ID0) |
2460 | { |
2461 | DetachOperation op(tid, error); |
2462 | DoOperation(&op); |
2463 | } |
2464 | return error; |
2465 | } |
2466 | |
2467 | bool |
2468 | ProcessMonitor::DupDescriptor(const char *path, int fd, int flags) |
2469 | { |
2470 | int target_fd = open(path, flags, 0666); |
2471 | |
2472 | if (target_fd == -1) |
2473 | return false; |
2474 | |
2475 | return (dup2(target_fd, fd) == -1) ? false : true; |
2476 | } |
2477 | |
2478 | void |
2479 | ProcessMonitor::StopMonitoringChildProcess() |
2480 | { |
2481 | if (m_monitor_thread.IsJoinable()) |
2482 | { |
2483 | m_monitor_thread.Cancel(); |
2484 | m_monitor_thread.Join(nullptr); |
2485 | } |
2486 | } |
2487 | |
2488 | void |
2489 | ProcessMonitor::StopMonitor() |
2490 | { |
2491 | StopMonitoringChildProcess(); |
2492 | StopOpThread(); |
2493 | sem_destroy(&m_operation_pending); |
2494 | sem_destroy(&m_operation_done); |
2495 | |
2496 | // Note: ProcessPOSIX passes the m_terminal_fd file descriptor to |
2497 | // Process::SetSTDIOFileDescriptor, which in turn transfers ownership of |
2498 | // the descriptor to a ConnectionFileDescriptor object. Consequently |
2499 | // even though still has the file descriptor, we shouldn't close it here. |
2500 | } |
2501 | |
2502 | void |
2503 | ProcessMonitor::StopOpThread() |
2504 | { |
2505 | if (!m_operation_thread.IsJoinable()) |
2506 | return; |
2507 | |
2508 | m_operation_thread.Cancel(); |
2509 | m_operation_thread.Join(nullptr); |
2510 | } |