Bug Summary

File:tools/lldb/source/Host/common/Host.cpp
Warning:line 290, column 5
Use of memory after it is freed

Annotated Source Code

1//===-- Host.cpp ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C includes
11#include <errno(*__errno_location ()).h>
12#include <limits.h>
13#include <stdlib.h>
14#include <sys/types.h>
15#ifndef _WIN32
16#include <dlfcn.h>
17#include <grp.h>
18#include <netdb.h>
19#include <pwd.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#endif
23
24#if defined(__APPLE__)
25#include <mach-o/dyld.h>
26#include <mach/mach_init.h>
27#include <mach/mach_port.h>
28#endif
29
30#if defined(__linux__1) || defined(__FreeBSD__) || \
31 defined(__FreeBSD_kernel__) || defined(__APPLE__) || \
32 defined(__NetBSD__) || defined(__OpenBSD__)
33#if !defined(__ANDROID__)
34#include <spawn.h>
35#endif
36#include <sys/syscall.h>
37#include <sys/wait.h>
38#endif
39
40#if defined(__FreeBSD__)
41#include <pthread_np.h>
42#endif
43
44#if defined(__NetBSD__)
45#include <lwp.h>
46#endif
47
48// C++ Includes
49#include <csignal>
50
51#include "lldb/Host/Host.h"
52#include "lldb/Host/HostInfo.h"
53#include "lldb/Host/HostProcess.h"
54#include "lldb/Host/MonitoringProcessLauncher.h"
55#include "lldb/Host/Predicate.h"
56#include "lldb/Host/ProcessLauncher.h"
57#include "lldb/Host/ThreadLauncher.h"
58#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
59#include "lldb/Target/FileAction.h"
60#include "lldb/Target/ProcessLaunchInfo.h"
61#include "lldb/Target/UnixSignals.h"
62#include "lldb/Utility/CleanUp.h"
63#include "lldb/Utility/DataBufferLLVM.h"
64#include "lldb/Utility/FileSpec.h"
65#include "lldb/Utility/Log.h"
66#include "lldb/Utility/Status.h"
67#include "lldb/lldb-private-forward.h"
68#include "llvm/ADT/SmallString.h"
69#include "llvm/ADT/StringSwitch.h"
70#include "llvm/Support/Errno.h"
71#include "llvm/Support/FileSystem.h"
72
73#if defined(_WIN32)
74#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
75#include "lldb/Host/windows/ProcessLauncherWindows.h"
76#else
77#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
78#endif
79
80#if defined(__APPLE__)
81#ifndef _POSIX_SPAWN_DISABLE_ASLR
82#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
83#endif
84
85extern "C" {
86int __pthread_chdir(const char *path);
87int __pthread_fchdir(int fildes);
88}
89
90#endif
91
92using namespace lldb;
93using namespace lldb_private;
94
95#if !defined(__APPLE__) && !defined(_WIN32)
96struct MonitorInfo {
97 lldb::pid_t pid; // The process ID to monitor
98 Host::MonitorChildProcessCallback
99 callback; // The callback function to call when "pid" exits or signals
100 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
101};
102
103static thread_result_t MonitorChildProcessThreadFunction(void *arg);
104
105HostThread Host::StartMonitoringChildProcess(
106 const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
107 bool monitor_signals) {
108 MonitorInfo *info_ptr = new MonitorInfo();
109
110 info_ptr->pid = pid;
111 info_ptr->callback = callback;
112 info_ptr->monitor_signals = monitor_signals;
113
114 char thread_name[256];
115 ::snprintf(thread_name, sizeof(thread_name),
116 "<lldb.host.wait4(pid=%" PRIu64"l" "u" ")>", pid);
117 return ThreadLauncher::LaunchThread(
118 thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL__null);
119}
120
121#ifndef __linux__1
122//------------------------------------------------------------------
123// Scoped class that will disable thread canceling when it is
124// constructed, and exception safely restore the previous value it
125// when it goes out of scope.
126//------------------------------------------------------------------
127class ScopedPThreadCancelDisabler {
128public:
129 ScopedPThreadCancelDisabler() {
130 // Disable the ability for this thread to be cancelled
131 int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLEPTHREAD_CANCEL_DISABLE, &m_old_state);
132 if (err != 0)
133 m_old_state = -1;
134 }
135
136 ~ScopedPThreadCancelDisabler() {
137 // Restore the ability for this thread to be cancelled to what it
138 // previously was.
139 if (m_old_state != -1)
140 ::pthread_setcancelstate(m_old_state, 0);
141 }
142
143private:
144 int m_old_state; // Save the old cancelability state.
145};
146#endif // __linux__
147
148#ifdef __linux__1
149#if defined(__GNUC__4) && (__GNUC__4 < 4 || (__GNUC__4 == 4 && __GNUC_MINOR__2 < 8))
150static __thread volatile sig_atomic_t g_usr1_called;
151#else
152static thread_local volatile sig_atomic_t g_usr1_called;
153#endif
154
155static void SigUsr1Handler(int) { g_usr1_called = 1; }
156#endif // __linux__
157
158static bool CheckForMonitorCancellation() {
159#ifdef __linux__1
160 if (g_usr1_called) {
161 g_usr1_called = 0;
162 return true;
163 }
164#else
165 ::pthread_testcancel();
166#endif
167 return false;
168}
169
170static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
171 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS(1u << 1)));
172 const char *function = __FUNCTION__;
173 if (log)
1
Assuming 'log' is null
2
Taking false branch
174 log->Printf("%s (arg = %p) thread starting...", function, arg);
175
176 MonitorInfo *info = (MonitorInfo *)arg;
177
178 const Host::MonitorChildProcessCallback callback = info->callback;
179 const bool monitor_signals = info->monitor_signals;
180
181 assert(info->pid <= UINT32_MAX)(static_cast <bool> (info->pid <= (4294967295U)) ?
void (0) : __assert_fail ("info->pid <= UINT32_MAX", "/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, 181, __extension__ __PRETTY_FUNCTION__))
;
182 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
3
Assuming 'monitor_signals' is 0
4
'?' condition is false
183
184 delete info;
5
Memory is released
185
186 int status = -1;
187#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
188#define __WALL0x40000000 0
189#endif
190 const int options = __WALL0x40000000;
191
192#ifdef __linux__1
193 // This signal is only used to interrupt the thread from waitpid
194 struct sigaction sigUsr1Action;
195 memset(&sigUsr1Action, 0, sizeof(sigUsr1Action));
196 sigUsr1Action.sa_handler__sigaction_handler.sa_handler = SigUsr1Handler;
197 ::sigaction(SIGUSR110, &sigUsr1Action, nullptr);
198#endif // __linux__
199
200 while (1) {
6
Loop condition is true. Entering loop body
201 log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS(1u << 1));
202 if (log)
7
Assuming 'log' is null
8
Taking false branch
203 log->Printf("%s ::waitpid (pid = %" PRIi32"i" ", &status, options = %i)...",
204 function, pid, options);
205
206 if (CheckForMonitorCancellation())
9
Taking true branch
207 break;
10
Execution continues on line 288
208
209 // Get signals from all children with same process group of pid
210 const ::pid_t wait_pid = ::waitpid(pid, &status, options);
211
212 if (CheckForMonitorCancellation())
213 break;
214
215 if (wait_pid == -1) {
216 if (errno(*__errno_location ()) == EINTR4)
217 continue;
218 else {
219 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, __FUNCTION__, "arg = {0}, thread exiting because waitpid failed ({1})..."
, arg, llvm::sys::StrError()); } while (0)
220 "arg = {0}, thread exiting because waitpid failed ({1})...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, __FUNCTION__, "arg = {0}, thread exiting because waitpid failed ({1})..."
, arg, llvm::sys::StrError()); } while (0)
221 arg, llvm::sys::StrError())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, __FUNCTION__, "arg = {0}, thread exiting because waitpid failed ({1})..."
, arg, llvm::sys::StrError()); } while (0)
;
222 break;
223 }
224 } else if (wait_pid > 0) {
225 bool exited = false;
226 int signal = 0;
227 int exit_status = 0;
228 const char *status_cstr = NULL__null;
229 if (WIFSTOPPED(status)(((status) & 0xff) == 0x7f)) {
230 signal = WSTOPSIG(status)(((status) & 0xff00) >> 8);
231 status_cstr = "STOPPED";
232 } else if (WIFEXITED(status)(((status) & 0x7f) == 0)) {
233 exit_status = WEXITSTATUS(status)(((status) & 0xff00) >> 8);
234 status_cstr = "EXITED";
235 exited = true;
236 } else if (WIFSIGNALED(status)(((signed char) (((status) & 0x7f) + 1) >> 1) > 0
)
) {
237 signal = WTERMSIG(status)((status) & 0x7f);
238 status_cstr = "SIGNALED";
239 if (wait_pid == abs(pid)) {
240 exited = true;
241 exit_status = -1;
242 }
243 } else {
244 status_cstr = "(\?\?\?)";
245 }
246
247 // Scope for pthread_cancel_disabler
248 {
249#ifndef __linux__1
250 ScopedPThreadCancelDisabler pthread_cancel_disabler;
251#endif
252
253 log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS(1u << 1));
254 if (log)
255 log->Printf("%s ::waitpid (pid = %" PRIi32"i"
256 ", &status, options = %i) => pid = %" PRIi32"i"
257 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
258 function, pid, options, wait_pid, status, status_cstr,
259 signal, exit_status);
260
261 if (exited || (signal != 0 && monitor_signals)) {
262 bool callback_return = false;
263 if (callback)
264 callback_return = callback(wait_pid, exited, signal, exit_status);
265
266 // If our process exited, then this thread should exit
267 if (exited && wait_pid == abs(pid)) {
268 if (log)
269 log->Printf("%s (arg = %p) thread exiting because pid received "
270 "exit signal...",
271 __FUNCTION__, arg);
272 break;
273 }
274 // If the callback returns true, it means this process should
275 // exit
276 if (callback_return) {
277 if (log)
278 log->Printf("%s (arg = %p) thread exiting because callback "
279 "returned true...",
280 __FUNCTION__, arg);
281 break;
282 }
283 }
284 }
285 }
286 }
287
288 log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS(1u << 1));
289 if (log)
11
Assuming 'log' is non-null
12
Taking true branch
290 log->Printf("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
13
Use of memory after it is freed
291
292 return NULL__null;
293}
294
295#endif // #if !defined (__APPLE__) && !defined (_WIN32)
296
297#if !defined(__APPLE__)
298
299void Host::SystemLog(SystemLogType type, const char *format, va_list args) {
300 vfprintf(stderrstderr, format, args);
301}
302
303#endif
304
305void Host::SystemLog(SystemLogType type, const char *format, ...) {
306 va_list args;
307 va_start(args, format)__builtin_va_start(args, format);
308 SystemLog(type, format, args);
309 va_end(args)__builtin_va_end(args);
310}
311
312lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); }
313
314#ifndef _WIN32
315
316lldb::thread_t Host::GetCurrentThread() {
317 return lldb::thread_t(pthread_self());
318}
319
320const char *Host::GetSignalAsCString(int signo) {
321 switch (signo) {
322 case SIGHUP1:
323 return "SIGHUP"; // 1 hangup
324 case SIGINT2:
325 return "SIGINT"; // 2 interrupt
326 case SIGQUIT3:
327 return "SIGQUIT"; // 3 quit
328 case SIGILL4:
329 return "SIGILL"; // 4 illegal instruction (not reset when caught)
330 case SIGTRAP5:
331 return "SIGTRAP"; // 5 trace trap (not reset when caught)
332 case SIGABRT6:
333 return "SIGABRT"; // 6 abort()
334#if defined(SIGPOLL29)
335#if !defined(SIGIO29) || (SIGPOLL29 != SIGIO29)
336 // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
337 // fail with 'multiple define cases with same value'
338 case SIGPOLL29:
339 return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
340#endif
341#endif
342#if defined(SIGEMT)
343 case SIGEMT:
344 return "SIGEMT"; // 7 EMT instruction
345#endif
346 case SIGFPE8:
347 return "SIGFPE"; // 8 floating point exception
348 case SIGKILL9:
349 return "SIGKILL"; // 9 kill (cannot be caught or ignored)
350 case SIGBUS7:
351 return "SIGBUS"; // 10 bus error
352 case SIGSEGV11:
353 return "SIGSEGV"; // 11 segmentation violation
354 case SIGSYS31:
355 return "SIGSYS"; // 12 bad argument to system call
356 case SIGPIPE13:
357 return "SIGPIPE"; // 13 write on a pipe with no one to read it
358 case SIGALRM14:
359 return "SIGALRM"; // 14 alarm clock
360 case SIGTERM15:
361 return "SIGTERM"; // 15 software termination signal from kill
362 case SIGURG23:
363 return "SIGURG"; // 16 urgent condition on IO channel
364 case SIGSTOP19:
365 return "SIGSTOP"; // 17 sendable stop signal not from tty
366 case SIGTSTP20:
367 return "SIGTSTP"; // 18 stop signal from tty
368 case SIGCONT18:
369 return "SIGCONT"; // 19 continue a stopped process
370 case SIGCHLD17:
371 return "SIGCHLD"; // 20 to parent on child stop or exit
372 case SIGTTIN21:
373 return "SIGTTIN"; // 21 to readers pgrp upon background tty read
374 case SIGTTOU22:
375 return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
376#if defined(SIGIO29)
377 case SIGIO29:
378 return "SIGIO"; // 23 input/output possible signal
379#endif
380 case SIGXCPU24:
381 return "SIGXCPU"; // 24 exceeded CPU time limit
382 case SIGXFSZ25:
383 return "SIGXFSZ"; // 25 exceeded file size limit
384 case SIGVTALRM26:
385 return "SIGVTALRM"; // 26 virtual time alarm
386 case SIGPROF27:
387 return "SIGPROF"; // 27 profiling time alarm
388#if defined(SIGWINCH28)
389 case SIGWINCH28:
390 return "SIGWINCH"; // 28 window size changes
391#endif
392#if defined(SIGINFO)
393 case SIGINFO:
394 return "SIGINFO"; // 29 information request
395#endif
396 case SIGUSR110:
397 return "SIGUSR1"; // 30 user defined signal 1
398 case SIGUSR212:
399 return "SIGUSR2"; // 31 user defined signal 2
400 default:
401 break;
402 }
403 return NULL__null;
404}
405
406#endif
407
408#if !defined(__APPLE__) // see Host.mm
409
410bool Host::GetBundleDirectory(const FileSpec &file, FileSpec &bundle) {
411 bundle.Clear();
412 return false;
413}
414
415bool Host::ResolveExecutableInBundle(FileSpec &file) { return false; }
416#endif
417
418#ifndef _WIN32
419
420FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
421 FileSpec module_filespec;
422#if !defined(__ANDROID__)
423 Dl_info info;
424 if (::dladdr(host_addr, &info)) {
425 if (info.dli_fname)
426 module_filespec.SetFile(info.dli_fname, true);
427 }
428#endif
429 return module_filespec;
430}
431
432#endif
433
434#if !defined(__linux__1)
435bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
436 return false;
437}
438#endif
439
440struct ShellInfo {
441 ShellInfo()
442 : process_reaped(false), pid(LLDB_INVALID_PROCESS_ID0), signo(-1),
443 status(-1) {}
444
445 lldb_private::Predicate<bool> process_reaped;
446 lldb::pid_t pid;
447 int signo;
448 int status;
449};
450
451static bool
452MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
453 bool exited, // True if the process did exit
454 int signo, // Zero for no signal
455 int status) // Exit value of process if signal is zero
456{
457 shell_info->pid = pid;
458 shell_info->signo = signo;
459 shell_info->status = status;
460 // Let the thread running Host::RunShellCommand() know that the process
461 // exited and that ShellInfo has been filled in by broadcasting to it
462 shell_info->process_reaped.SetValue(true, eBroadcastAlways);
463 return true;
464}
465
466Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
467 int *status_ptr, int *signo_ptr,
468 std::string *command_output_ptr,
469 uint32_t timeout_sec, bool run_in_default_shell) {
470 return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
471 command_output_ptr, timeout_sec, run_in_default_shell);
472}
473
474Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
475 int *status_ptr, int *signo_ptr,
476 std::string *command_output_ptr,
477 uint32_t timeout_sec, bool run_in_default_shell) {
478 Status error;
479 ProcessLaunchInfo launch_info;
480 launch_info.SetArchitecture(HostInfo::GetArchitecture());
481 if (run_in_default_shell) {
482 // Run the command in a shell
483 launch_info.SetShell(HostInfo::GetDefaultShell());
484 launch_info.GetArguments().AppendArguments(args);
485 const bool localhost = true;
486 const bool will_debug = false;
487 const bool first_arg_is_full_shell_command = false;
488 launch_info.ConvertArgumentsForLaunchingInShell(
489 error, localhost, will_debug, first_arg_is_full_shell_command, 0);
490 } else {
491 // No shell, just run it
492 const bool first_arg_is_executable = true;
493 launch_info.SetArguments(args, first_arg_is_executable);
494 }
495
496 if (working_dir)
497 launch_info.SetWorkingDirectory(working_dir);
498 llvm::SmallString<PATH_MAX4096> output_file_path;
499
500 if (command_output_ptr) {
501 // Create a temporary file to get the stdout/stderr and redirect the
502 // output of the command into this file. We will later read this file
503 // if all goes well and fill the data into "command_output_ptr"
504 FileSpec tmpdir_file_spec;
505 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) {
506 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
507 llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
508 output_file_path);
509 } else {
510 llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "",
511 output_file_path);
512 }
513 }
514
515 FileSpec output_file_spec{output_file_path.c_str(), false};
516
517 launch_info.AppendSuppressFileAction(STDIN_FILENO0, true, false);
518 if (output_file_spec) {
519 launch_info.AppendOpenFileAction(STDOUT_FILENO1, output_file_spec, false,
520 true);
521 launch_info.AppendDuplicateFileAction(STDOUT_FILENO1, STDERR_FILENO2);
522 } else {
523 launch_info.AppendSuppressFileAction(STDOUT_FILENO1, false, true);
524 launch_info.AppendSuppressFileAction(STDERR_FILENO2, false, true);
525 }
526
527 std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
528 const bool monitor_signals = false;
529 launch_info.SetMonitorProcessCallback(
530 std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1,
531 std::placeholders::_2, std::placeholders::_3,
532 std::placeholders::_4),
533 monitor_signals);
534
535 error = LaunchProcess(launch_info);
536 const lldb::pid_t pid = launch_info.GetProcessID();
537
538 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID0)
539 error.SetErrorString("failed to get process ID");
540
541 if (error.Success()) {
542 bool timed_out = false;
543 shell_info_sp->process_reaped.WaitForValueEqualTo(
544 true, std::chrono::seconds(timeout_sec), &timed_out);
545 if (timed_out) {
546 error.SetErrorString("timed out waiting for shell command to complete");
547
548 // Kill the process since it didn't complete within the timeout specified
549 Kill(pid, SIGKILL9);
550 // Wait for the monitor callback to get the message
551 timed_out = false;
552 shell_info_sp->process_reaped.WaitForValueEqualTo(
553 true, std::chrono::seconds(1), &timed_out);
554 } else {
555 if (status_ptr)
556 *status_ptr = shell_info_sp->status;
557
558 if (signo_ptr)
559 *signo_ptr = shell_info_sp->signo;
560
561 if (command_output_ptr) {
562 command_output_ptr->clear();
563 uint64_t file_size = output_file_spec.GetByteSize();
564 if (file_size > 0) {
565 if (file_size > command_output_ptr->max_size()) {
566 error.SetErrorStringWithFormat(
567 "shell command output is too large to fit into a std::string");
568 } else {
569 auto Buffer =
570 DataBufferLLVM::CreateFromPath(output_file_spec.GetPath());
571 if (error.Success())
572 command_output_ptr->assign(Buffer->GetChars(),
573 Buffer->GetByteSize());
574 }
575 }
576 }
577 }
578 }
579
580 llvm::sys::fs::remove(output_file_spec.GetPath());
581 return error;
582}
583
584// The functions below implement process launching for non-Apple-based platforms
585#if !defined(__APPLE__)
586Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
587 std::unique_ptr<ProcessLauncher> delegate_launcher;
588#if defined(_WIN32)
589 delegate_launcher.reset(new ProcessLauncherWindows());
590#else
591 delegate_launcher.reset(new ProcessLauncherPosixFork());
592#endif
593 MonitoringProcessLauncher launcher(std::move(delegate_launcher));
594
595 Status error;
596 HostProcess process = launcher.LaunchProcess(launch_info, error);
597
598 // TODO(zturner): It would be better if the entire HostProcess were returned
599 // instead of writing
600 // it into this structure.
601 launch_info.SetProcessID(process.GetProcessId());
602
603 return error;
604}
605#endif // !defined(__APPLE__)
606
607#ifndef _WIN32
608void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); }
609
610#endif
611
612#if !defined(__APPLE__)
613bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
614 uint32_t line_no) {
615 return false;
616}
617
618#endif
619
620const UnixSignalsSP &Host::GetUnixSignals() {
621 static const auto s_unix_signals_sp =
622 UnixSignals::Create(HostInfo::GetArchitecture());
623 return s_unix_signals_sp;
624}
625
626std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) {
627#if defined(_WIN32)
628 if (url.startswith("file://"))
629 return std::unique_ptr<Connection>(new ConnectionGenericFile());
630#endif
631 return std::unique_ptr<Connection>(new ConnectionFileDescriptor());
632}
633
634#if defined(LLVM_ON_UNIX1)
635WaitStatus WaitStatus::Decode(int wstatus) {
636 if (WIFEXITED(wstatus)(((wstatus) & 0x7f) == 0))
637 return {Exit, uint8_t(WEXITSTATUS(wstatus)(((wstatus) & 0xff00) >> 8))};
638 else if (WIFSIGNALED(wstatus)(((signed char) (((wstatus) & 0x7f) + 1) >> 1) >
0)
)
639 return {Signal, uint8_t(WTERMSIG(wstatus)((wstatus) & 0x7f))};
640 else if (WIFSTOPPED(wstatus)(((wstatus) & 0xff) == 0x7f))
641 return {Stop, uint8_t(WSTOPSIG(wstatus)(((wstatus) & 0xff00) >> 8))};
642 llvm_unreachable("Unknown wait status")::llvm::llvm_unreachable_internal("Unknown wait status", "/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, 642)
;
643}
644#endif
645
646void llvm::format_provider<WaitStatus>::format(const WaitStatus &WS,
647 raw_ostream &OS,
648 StringRef Options) {
649 if (Options == "g") {
650 char type;
651 switch (WS.type) {
652 case WaitStatus::Exit:
653 type = 'W';
654 break;
655 case WaitStatus::Signal:
656 type = 'X';
657 break;
658 case WaitStatus::Stop:
659 type = 'S';
660 break;
661 }
662 OS << formatv("{0}{1:x-2}", type, WS.status);
663 return;
664 }
665
666 assert(Options.empty())(static_cast <bool> (Options.empty()) ? void (0) : __assert_fail
("Options.empty()", "/build/llvm-toolchain-snapshot-6.0~svn320613/tools/lldb/source/Host/common/Host.cpp"
, 666, __extension__ __PRETTY_FUNCTION__))
;
667 const char *desc;
668 switch(WS.type) {
669 case WaitStatus::Exit:
670 desc = "Exited with status";
671 break;
672 case WaitStatus::Signal:
673 desc = "Killed by signal";
674 break;
675 case WaitStatus::Stop:
676 desc = "Stopped by signal";
677 break;
678 }
679 OS << desc << " " << int(WS.status);
680}