Bug Summary

File:tools/lldb/source/Host/common/Host.cpp
Location:line 192, column 21
Description: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 <unistd.h>
17#include <dlfcn.h>
18#include <grp.h>
19#include <netdb.h>
20#include <pwd.h>
21#include <sys/stat.h>
22#endif
23
24#if defined (__APPLE__)
25#include <mach/mach_port.h>
26#include <mach/mach_init.h>
27#include <mach-o/dyld.h>
28#endif
29
30#if defined (__linux__1) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__)
31#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
32#include <spawn.h>
33#endif
34#include <sys/wait.h>
35#include <sys/syscall.h>
36#endif
37
38#if defined (__FreeBSD__)
39#include <pthread_np.h>
40#endif
41
42// C++ includes
43#include <limits>
44
45#include "lldb/Host/FileSystem.h"
46#include "lldb/Host/Host.h"
47#include "lldb/Host/HostInfo.h"
48#include "lldb/Core/ArchSpec.h"
49#include "lldb/Core/Error.h"
50#include "lldb/Core/Log.h"
51#include "lldb/Host/FileSpec.h"
52#include "lldb/Host/HostProcess.h"
53#include "lldb/Host/MonitoringProcessLauncher.h"
54#include "lldb/Host/Predicate.h"
55#include "lldb/Host/ProcessLauncher.h"
56#include "lldb/Host/ThreadLauncher.h"
57#include "lldb/lldb-private-forward.h"
58#include "llvm/Support/FileSystem.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 "llvm/ADT/SmallString.h"
64
65#if defined(_WIN32)
66#include "lldb/Host/windows/ProcessLauncherWindows.h"
67#elif defined(__ANDROID__) || defined(__ANDROID_NDK__)
68#include "lldb/Host/android/ProcessLauncherAndroid.h"
69#else
70#include "lldb/Host/posix/ProcessLauncherPosix.h"
71#endif
72
73#if defined (__APPLE__)
74#ifndef _POSIX_SPAWN_DISABLE_ASLR
75#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
76#endif
77
78extern "C"
79{
80 int __pthread_chdir(const char *path);
81 int __pthread_fchdir (int fildes);
82}
83
84#endif
85
86using namespace lldb;
87using namespace lldb_private;
88
89#if !defined (__APPLE__) && !defined (_WIN32)
90struct MonitorInfo
91{
92 lldb::pid_t pid; // The process ID to monitor
93 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
94 void *callback_baton; // The callback baton for the callback function
95 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
96};
97
98static thread_result_t
99MonitorChildProcessThreadFunction (void *arg);
100
101HostThread
102Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
103{
104 MonitorInfo * info_ptr = new MonitorInfo();
105
106 info_ptr->pid = pid;
107 info_ptr->callback = callback;
108 info_ptr->callback_baton = callback_baton;
109 info_ptr->monitor_signals = monitor_signals;
110
111 char thread_name[256];
112 ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64"l" "u" ")>", pid);
113 return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL__null);
114}
115
116#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
117//------------------------------------------------------------------
118// Scoped class that will disable thread canceling when it is
119// constructed, and exception safely restore the previous value it
120// when it goes out of scope.
121//------------------------------------------------------------------
122class ScopedPThreadCancelDisabler
123{
124public:
125 ScopedPThreadCancelDisabler()
126 {
127 // Disable the ability for this thread to be cancelled
128 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLEPTHREAD_CANCEL_DISABLE, &m_old_state);
129 if (err != 0)
130 m_old_state = -1;
131 }
132
133 ~ScopedPThreadCancelDisabler()
134 {
135 // Restore the ability for this thread to be cancelled to what it
136 // previously was.
137 if (m_old_state != -1)
138 ::pthread_setcancelstate (m_old_state, 0);
139 }
140private:
141 int m_old_state; // Save the old cancelability state.
142};
143#endif // __ANDROID_NDK__
144
145static thread_result_t
146MonitorChildProcessThreadFunction (void *arg)
147{
148 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1)));
149 const char *function = __FUNCTION__;
150 if (log)
1
Assuming 'log' is null
2
Taking false branch
151 log->Printf ("%s (arg = %p) thread starting...", function, arg);
152
153 MonitorInfo *info = (MonitorInfo *)arg;
154
155 const Host::MonitorChildProcessCallback callback = info->callback;
156 void * const callback_baton = info->callback_baton;
157 const bool monitor_signals = info->monitor_signals;
158
159 assert (info->pid <= UINT32_MAX)((info->pid <= (4294967295U)) ? static_cast<void>
(0) : __assert_fail ("info->pid <= (4294967295U)", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn232022/tools/lldb/source/Host/common/Host.cpp"
, 159, __PRETTY_FUNCTION__))
;
160 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
3
Assuming 'monitor_signals' is 0
4
'?' condition is false
161
162 delete info;
5
Memory is released
163
164 int status = -1;
165#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
166 #define __WALL0x40000000 0
167#endif
168 const int options = __WALL0x40000000;
169
170 while (1)
6
Loop condition is true. Entering loop body
12
Loop condition is true. Entering loop body
171 {
172 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1));
173 if (log)
7
Assuming 'log' is null
8
Taking false branch
13
Assuming 'log' is non-null
14
Taking true branch
174 log->Printf("%s ::waitpid (pid = %" PRIi32"i" ", &status, options = %i)...", function, pid, options);
175
176 // Wait for all child processes
177#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
178 ::pthread_testcancel ();
179#endif
180 // Get signals from all children with same process group of pid
181 const ::pid_t wait_pid = ::waitpid (pid, &status, options);
182#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
183 ::pthread_testcancel ();
184#endif
185 if (wait_pid == -1)
9
Taking false branch
15
Taking true branch
186 {
187 if (errno(*__errno_location ()) == EINTR4)
16
Taking false branch
188 continue;
189 else
190 {
191 if (log)
17
Taking true branch
192 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno(*__errno_location ())));
18
Use of memory after it is freed
193 break;
194 }
195 }
196 else if (wait_pid > 0)
10
Assuming 'wait_pid' is <= 0
11
Taking false branch
197 {
198 bool exited = false;
199 int signal = 0;
200 int exit_status = 0;
201 const char *status_cstr = NULL__null;
202 if (WIFSTOPPED(status)((((*(int *) &(status))) & 0xff) == 0x7f))
203 {
204 signal = WSTOPSIG(status)((((*(int *) &(status))) & 0xff00) >> 8);
205 status_cstr = "STOPPED";
206 }
207 else if (WIFEXITED(status)((((*(int *) &(status))) & 0x7f) == 0))
208 {
209 exit_status = WEXITSTATUS(status)((((*(int *) &(status))) & 0xff00) >> 8);
210 status_cstr = "EXITED";
211 exited = true;
212 }
213 else if (WIFSIGNALED(status)(((signed char) ((((*(int *) &(status))) & 0x7f) + 1)
>> 1) > 0)
)
214 {
215 signal = WTERMSIG(status)(((*(int *) &(status))) & 0x7f);
216 status_cstr = "SIGNALED";
217 if (wait_pid == abs(pid)) {
218 exited = true;
219 exit_status = -1;
220 }
221 }
222 else
223 {
224 status_cstr = "(\?\?\?)";
225 }
226
227 // Scope for pthread_cancel_disabler
228 {
229#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
230 ScopedPThreadCancelDisabler pthread_cancel_disabler;
231#endif
232
233 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1));
234 if (log)
235 log->Printf ("%s ::waitpid (pid = %" PRIi32"i" ", &status, options = %i) => pid = %" PRIi32"i" ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
236 function,
237 pid,
238 options,
239 wait_pid,
240 status,
241 status_cstr,
242 signal,
243 exit_status);
244
245 if (exited || (signal != 0 && monitor_signals))
246 {
247 bool callback_return = false;
248 if (callback)
249 callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
250
251 // If our process exited, then this thread should exit
252 if (exited && wait_pid == abs(pid))
253 {
254 if (log)
255 log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
256 break;
257 }
258 // If the callback returns true, it means this process should
259 // exit
260 if (callback_return)
261 {
262 if (log)
263 log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
264 break;
265 }
266 }
267 }
268 }
269 }
270
271 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1));
272 if (log)
273 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
274
275 return NULL__null;
276}
277
278#endif // #if !defined (__APPLE__) && !defined (_WIN32)
279
280#if !defined (__APPLE__)
281
282void
283Host::SystemLog (SystemLogType type, const char *format, va_list args)
284{
285 vfprintf (stderrstderr, format, args);
286}
287
288#endif
289
290void
291Host::SystemLog (SystemLogType type, const char *format, ...)
292{
293 va_list args;
294 va_start (args, format)__builtin_va_start(args, format);
295 SystemLog (type, format, args);
296 va_end (args)__builtin_va_end(args);
297}
298
299lldb::pid_t
300Host::GetCurrentProcessID()
301{
302 return ::getpid();
303}
304
305#ifndef _WIN32
306
307lldb::tid_t
308Host::GetCurrentThreadID()
309{
310#if defined (__APPLE__)
311 // Calling "mach_thread_self()" bumps the reference count on the thread
312 // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
313 // count.
314 thread_port_t thread_self = mach_thread_self();
315 mach_port_deallocate(mach_task_self(), thread_self);
316 return thread_self;
317#elif defined(__FreeBSD__)
318 return lldb::tid_t(pthread_getthreadid_np());
319#elif defined(__ANDROID_NDK__)
320 return lldb::tid_t(gettid());
321#elif defined(__linux__1)
322 return lldb::tid_t(syscall(SYS_gettid186));
323#else
324 return lldb::tid_t(pthread_self());
325#endif
326}
327
328lldb::thread_t
329Host::GetCurrentThread ()
330{
331 return lldb::thread_t(pthread_self());
332}
333
334const char *
335Host::GetSignalAsCString (int signo)
336{
337 switch (signo)
338 {
339 case SIGHUP1: return "SIGHUP"; // 1 hangup
340 case SIGINT2: return "SIGINT"; // 2 interrupt
341 case SIGQUIT3: return "SIGQUIT"; // 3 quit
342 case SIGILL4: return "SIGILL"; // 4 illegal instruction (not reset when caught)
343 case SIGTRAP5: return "SIGTRAP"; // 5 trace trap (not reset when caught)
344 case SIGABRT6: return "SIGABRT"; // 6 abort()
345#if defined(SIGPOLL29)
346#if !defined(SIGIO29) || (SIGPOLL29 != SIGIO29)
347// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
348// fail with 'multiple define cases with same value'
349 case SIGPOLL29: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
350#endif
351#endif
352#if defined(SIGEMT)
353 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
354#endif
355 case SIGFPE8: return "SIGFPE"; // 8 floating point exception
356 case SIGKILL9: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
357 case SIGBUS7: return "SIGBUS"; // 10 bus error
358 case SIGSEGV11: return "SIGSEGV"; // 11 segmentation violation
359 case SIGSYS31: return "SIGSYS"; // 12 bad argument to system call
360 case SIGPIPE13: return "SIGPIPE"; // 13 write on a pipe with no one to read it
361 case SIGALRM14: return "SIGALRM"; // 14 alarm clock
362 case SIGTERM15: return "SIGTERM"; // 15 software termination signal from kill
363 case SIGURG23: return "SIGURG"; // 16 urgent condition on IO channel
364 case SIGSTOP19: return "SIGSTOP"; // 17 sendable stop signal not from tty
365 case SIGTSTP20: return "SIGTSTP"; // 18 stop signal from tty
366 case SIGCONT18: return "SIGCONT"; // 19 continue a stopped process
367 case SIGCHLD17: return "SIGCHLD"; // 20 to parent on child stop or exit
368 case SIGTTIN21: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
369 case SIGTTOU22: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
370#if defined(SIGIO29)
371 case SIGIO29: return "SIGIO"; // 23 input/output possible signal
372#endif
373 case SIGXCPU24: return "SIGXCPU"; // 24 exceeded CPU time limit
374 case SIGXFSZ25: return "SIGXFSZ"; // 25 exceeded file size limit
375 case SIGVTALRM26: return "SIGVTALRM"; // 26 virtual time alarm
376 case SIGPROF27: return "SIGPROF"; // 27 profiling time alarm
377#if defined(SIGWINCH28)
378 case SIGWINCH28: return "SIGWINCH"; // 28 window size changes
379#endif
380#if defined(SIGINFO)
381 case SIGINFO: return "SIGINFO"; // 29 information request
382#endif
383 case SIGUSR110: return "SIGUSR1"; // 30 user defined signal 1
384 case SIGUSR212: return "SIGUSR2"; // 31 user defined signal 2
385 default:
386 break;
387 }
388 return NULL__null;
389}
390
391#endif
392
393void
394Host::WillTerminate ()
395{
396}
397
398#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__1) // see macosx/Host.mm
399
400size_t
401Host::GetEnvironment (StringList &env)
402{
403 // TODO: Is there a way to the host environment for this process on other systems?
404 return 0;
405}
406
407#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__)
408
409#ifndef _WIN32
410
411lldb::thread_key_t
412Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback)
413{
414 pthread_key_t key;
415 ::pthread_key_create (&key, callback);
416 return key;
417}
418
419void*
420Host::ThreadLocalStorageGet(lldb::thread_key_t key)
421{
422 return ::pthread_getspecific (key);
423}
424
425void
426Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value)
427{
428 ::pthread_setspecific (key, value);
429}
430
431#endif
432
433#if !defined (__APPLE__) // see Host.mm
434
435bool
436Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
437{
438 bundle.Clear();
439 return false;
440}
441
442bool
443Host::ResolveExecutableInBundle (FileSpec &file)
444{
445 return false;
446}
447#endif
448
449#ifndef _WIN32
450
451FileSpec
452Host::GetModuleFileSpecForHostAddress (const void *host_addr)
453{
454 FileSpec module_filespec;
455#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
456 Dl_info info;
457 if (::dladdr (host_addr, &info))
458 {
459 if (info.dli_fname)
460 module_filespec.SetFile(info.dli_fname, true);
461 }
462#else
463 assert(false && "dladdr() not supported on Android")((false && "dladdr() not supported on Android") ? static_cast
<void> (0) : __assert_fail ("false && \"dladdr() not supported on Android\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn232022/tools/lldb/source/Host/common/Host.cpp"
, 463, __PRETTY_FUNCTION__))
;
464#endif
465 return module_filespec;
466}
467
468#endif
469
470#if !defined(__linux__1)
471bool
472Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
473{
474 return false;
475}
476#endif
477
478struct ShellInfo
479{
480 ShellInfo () :
481 process_reaped (false),
482 can_delete (false),
483 pid (LLDB_INVALID_PROCESS_ID0),
484 signo(-1),
485 status(-1)
486 {
487 }
488
489 lldb_private::Predicate<bool> process_reaped;
490 lldb_private::Predicate<bool> can_delete;
491 lldb::pid_t pid;
492 int signo;
493 int status;
494};
495
496static bool
497MonitorShellCommand (void *callback_baton,
498 lldb::pid_t pid,
499 bool exited, // True if the process did exit
500 int signo, // Zero for no signal
501 int status) // Exit value of process if signal is zero
502{
503 ShellInfo *shell_info = (ShellInfo *)callback_baton;
504 shell_info->pid = pid;
505 shell_info->signo = signo;
506 shell_info->status = status;
507 // Let the thread running Host::RunShellCommand() know that the process
508 // exited and that ShellInfo has been filled in by broadcasting to it
509 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
510 // Now wait for a handshake back from that thread running Host::RunShellCommand
511 // so we know that we can delete shell_info_ptr
512 shell_info->can_delete.WaitForValueEqualTo(true);
513 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
514 usleep(1000);
515 // Now delete the shell info that was passed into this function
516 delete shell_info;
517 return true;
518}
519
520Error
521Host::RunShellCommand (const char *command,
522 const char *working_dir,
523 int *status_ptr,
524 int *signo_ptr,
525 std::string *command_output_ptr,
526 uint32_t timeout_sec,
527 bool run_in_default_shell)
528{
529 Error error;
530 ProcessLaunchInfo launch_info;
531 launch_info.SetArchitecture(HostInfo::GetArchitecture());
532 if (run_in_default_shell)
533 {
534 // Run the command in a shell
535 launch_info.SetShell(HostInfo::GetDefaultShell());
536 launch_info.GetArguments().AppendArgument(command);
537 const bool localhost = true;
538 const bool will_debug = false;
539 const bool first_arg_is_full_shell_command = true;
540 launch_info.ConvertArgumentsForLaunchingInShell (error,
541 localhost,
542 will_debug,
543 first_arg_is_full_shell_command,
544 0);
545 }
546 else
547 {
548 // No shell, just run it
549 Args args (command);
550 const bool first_arg_is_executable = true;
551 launch_info.SetArguments(args, first_arg_is_executable);
552 }
553
554 if (working_dir)
555 launch_info.SetWorkingDirectory(working_dir);
556 llvm::SmallString<PATH_MAX4096> output_file_path;
557
558 if (command_output_ptr)
559 {
560 // Create a temporary file to get the stdout/stderr and redirect the
561 // output of the command into this file. We will later read this file
562 // if all goes well and fill the data into "command_output_ptr"
563 FileSpec tmpdir_file_spec;
564 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
565 {
566 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
567 llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path);
568 }
569 else
570 {
571 llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path);
572 }
573 }
574
575 launch_info.AppendSuppressFileAction (STDIN_FILENO0, true, false);
576 if (!output_file_path.empty())
577 {
578 launch_info.AppendOpenFileAction(STDOUT_FILENO1, output_file_path.c_str(), false, true);
579 launch_info.AppendDuplicateFileAction(STDOUT_FILENO1, STDERR_FILENO2);
580 }
581 else
582 {
583 launch_info.AppendSuppressFileAction (STDOUT_FILENO1, false, true);
584 launch_info.AppendSuppressFileAction (STDERR_FILENO2, false, true);
585 }
586
587 // The process monitor callback will delete the 'shell_info_ptr' below...
588 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
589
590 const bool monitor_signals = false;
591 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
592
593 error = LaunchProcess (launch_info);
594 const lldb::pid_t pid = launch_info.GetProcessID();
595
596 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID0)
597 error.SetErrorString("failed to get process ID");
598
599 if (error.Success())
600 {
601 // The process successfully launched, so we can defer ownership of
602 // "shell_info" to the MonitorShellCommand callback function that will
603 // get called when the process dies. We release the unique pointer as it
604 // doesn't need to delete the ShellInfo anymore.
605 ShellInfo *shell_info = shell_info_ap.release();
606 TimeValue *timeout_ptr = nullptr;
607 TimeValue timeout_time(TimeValue::Now());
608 if (timeout_sec > 0) {
609 timeout_time.OffsetWithSeconds(timeout_sec);
610 timeout_ptr = &timeout_time;
611 }
612 bool timed_out = false;
613 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out);
614 if (timed_out)
615 {
616 error.SetErrorString("timed out waiting for shell command to complete");
617
618 // Kill the process since it didn't complete within the timeout specified
619 Kill (pid, SIGKILL9);
620 // Wait for the monitor callback to get the message
621 timeout_time = TimeValue::Now();
622 timeout_time.OffsetWithSeconds(1);
623 timed_out = false;
624 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
625 }
626 else
627 {
628 if (status_ptr)
629 *status_ptr = shell_info->status;
630
631 if (signo_ptr)
632 *signo_ptr = shell_info->signo;
633
634 if (command_output_ptr)
635 {
636 command_output_ptr->clear();
637 FileSpec file_spec(output_file_path.c_str(), File::eOpenOptionRead);
638 uint64_t file_size = file_spec.GetByteSize();
639 if (file_size > 0)
640 {
641 if (file_size > command_output_ptr->max_size())
642 {
643 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
644 }
645 else
646 {
647 command_output_ptr->resize(file_size);
648 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
649 }
650 }
651 }
652 }
653 shell_info->can_delete.SetValue(true, eBroadcastAlways);
654 }
655
656 FileSpec output_file_spec(output_file_path.c_str(), false);
657 if (FileSystem::GetFileExists(output_file_spec))
658 FileSystem::Unlink(output_file_path.c_str());
659 // Handshake with the monitor thread, or just let it know in advance that
660 // it can delete "shell_info" in case we timed out and were not able to kill
661 // the process...
662 return error;
663}
664
665
666// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC
667// systems
668
669#if defined (__APPLE__) || defined (__linux__1) || defined (__FreeBSD__) || defined (__GLIBC__2) || defined(__NetBSD__)
670#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
671// this method needs to be visible to macosx/Host.cpp and
672// common/Host.cpp.
673
674short
675Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info)
676{
677 short flags = POSIX_SPAWN_SETSIGDEF0x04 | POSIX_SPAWN_SETSIGMASK0x08;
678
679#if defined (__APPLE__)
680 if (launch_info.GetFlags().Test (eLaunchFlagExec))
681 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
682
683 if (launch_info.GetFlags().Test (eLaunchFlagDebug))
684 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
685
686 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
687 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
688
689 if (launch_info.GetLaunchInSeparateProcessGroup())
690 flags |= POSIX_SPAWN_SETPGROUP0x02;
691
692#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
693#if defined (__APPLE__) && (defined (__x86_64__1) || defined (__i386__))
694 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
695 if (g_use_close_on_exec_flag == eLazyBoolCalculate)
696 {
697 g_use_close_on_exec_flag = eLazyBoolNo;
698
699 uint32_t major, minor, update;
700 if (HostInfo::GetOSVersion(major, minor, update))
701 {
702 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier
703 if (major > 10 || (major == 10 && minor > 7))
704 {
705 // Only enable for 10.8 and later OS versions
706 g_use_close_on_exec_flag = eLazyBoolYes;
707 }
708 }
709 }
710#else
711 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
712#endif
713 // Close all files exception those with file actions if this is supported.
714 if (g_use_close_on_exec_flag == eLazyBoolYes)
715 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
716#endif
717#endif // #if defined (__APPLE__)
718 return flags;
719}
720
721Error
722Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid)
723{
724 Error error;
725 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST(1u << 14) | LIBLLDB_LOG_PROCESS(1u << 1)));
726
727 posix_spawnattr_t attr;
728 error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
729
730 if (error.Fail() || log)
731 error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
732 if (error.Fail())
733 return error;
734
735 // Make a quick class that will cleanup the posix spawn attributes in case
736 // we return in the middle of this function.
737 lldb_utility::CleanUp <posix_spawnattr_t *, int> posix_spawnattr_cleanup(&attr, posix_spawnattr_destroy);
738
739 sigset_t no_signals;
740 sigset_t all_signals;
741 sigemptyset (&no_signals);
742 sigfillset (&all_signals);
743 ::posix_spawnattr_setsigmask(&attr, &no_signals);
744#if defined (__linux__1) || defined (__FreeBSD__)
745 ::posix_spawnattr_setsigdefault(&attr, &no_signals);
746#else
747 ::posix_spawnattr_setsigdefault(&attr, &all_signals);
748#endif
749
750 short flags = GetPosixspawnFlags(launch_info);
751
752 error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
753 if (error.Fail() || log)
754 error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
755 if (error.Fail())
756 return error;
757
758 // posix_spawnattr_setbinpref_np appears to be an Apple extension per:
759 // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
760#if defined (__APPLE__) && !defined (__arm__)
761
762 // Don't set the binpref if a shell was provided. After all, that's only going to affect what version of the shell
763 // is launched, not what fork of the binary is launched. We insert "arch --arch <ARCH> as part of the shell invocation
764 // to do that job on OSX.
765
766 if (launch_info.GetShell() == nullptr)
767 {
768 // We don't need to do this for ARM, and we really shouldn't now that we
769 // have multiple CPU subtypes and no posix_spawnattr call that allows us
770 // to set which CPU subtype to launch...
771 const ArchSpec &arch_spec = launch_info.GetArchitecture();
772 cpu_type_t cpu = arch_spec.GetMachOCPUType();
773 cpu_type_t sub = arch_spec.GetMachOCPUSubType();
774 if (cpu != 0 &&
775 cpu != static_cast<cpu_type_t>(UINT32_MAX(4294967295U)) &&
776 cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE(0xFFFFFFFEu)) &&
777 !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try to set the CPU type or we will fail
778 {
779 size_t ocount = 0;
780 error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
781 if (error.Fail() || log)
782 error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
783
784 if (error.Fail() || ocount != 1)
785 return error;
786 }
787 }
788
789#endif
790
791 const char *tmp_argv[2];
792 char * const *argv = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
793 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
794 if (argv == NULL__null)
795 {
796 // posix_spawn gets very unhappy if it doesn't have at least the program
797 // name in argv[0]. One of the side affects I have noticed is the environment
798 // variables don't make it into the child process if "argv == NULL"!!!
799 tmp_argv[0] = exe_path;
800 tmp_argv[1] = NULL__null;
801 argv = (char * const*)tmp_argv;
802 }
803
804#if !defined (__APPLE__)
805 // manage the working directory
806 char current_dir[PATH_MAX4096];
807 current_dir[0] = '\0';
808#endif
809
810 const char *working_dir = launch_info.GetWorkingDirectory();
811 if (working_dir)
812 {
813#if defined (__APPLE__)
814 // Set the working directory on this thread only
815 if (__pthread_chdir (working_dir) < 0) {
816 if (errno(*__errno_location ()) == ENOENT2) {
817 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
818 } else if (errno(*__errno_location ()) == ENOTDIR20) {
819 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir);
820 } else {
821 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
822 }
823 return error;
824 }
825#else
826 if (::getcwd(current_dir, sizeof(current_dir)) == NULL__null)
827 {
828 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
829 error.LogIfError(log, "unable to save the current directory");
830 return error;
831 }
832
833 if (::chdir(working_dir) == -1)
834 {
835 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
836 error.LogIfError(log, "unable to change working directory to %s", working_dir);
837 return error;
838 }
839#endif
840 }
841
842 ::pid_t result_pid = LLDB_INVALID_PROCESS_ID0;
843 const size_t num_file_actions = launch_info.GetNumFileActions ();
844 if (num_file_actions > 0)
845 {
846 posix_spawn_file_actions_t file_actions;
847 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
848 if (error.Fail() || log)
849 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
850 if (error.Fail())
851 return error;
852
853 // Make a quick class that will cleanup the posix spawn attributes in case
854 // we return in the middle of this function.
855 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy);
856
857 for (size_t i=0; i<num_file_actions; ++i)
858 {
859 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
860 if (launch_file_action)
861 {
862 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error))
863 return error;
864 }
865 }
866
867 error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX);
868
869 if (error.Fail() || log)
870 {
871 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid,
872 exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
873 reinterpret_cast<const void *>(envp));
874 if (log)
875 {
876 for (int ii=0; argv[ii]; ++ii)
877 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
878 }
879 }
880
881 }
882 else
883 {
884 error.SetError(::posix_spawnp(&result_pid, exe_path, NULL__null, &attr, argv, envp), eErrorTypePOSIX);
885
886 if (error.Fail() || log)
887 {
888 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
889 result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
890 reinterpret_cast<const void *>(envp));
891 if (log)
892 {
893 for (int ii=0; argv[ii]; ++ii)
894 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
895 }
896 }
897 }
898 pid = result_pid;
899
900 if (working_dir)
901 {
902#if defined (__APPLE__)
903 // No more thread specific current working directory
904 __pthread_fchdir (-1);
905#else
906 if (::chdir(current_dir) == -1 && error.Success())
907 {
908 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
909 error.LogIfError(log, "unable to change current directory back to %s",
910 current_dir);
911 }
912#endif
913 }
914
915 return error;
916}
917
918bool
919Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error)
920{
921 if (info == NULL__null)
922 return false;
923
924 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
925
926 switch (info->GetAction())
927 {
928 case FileAction::eFileActionNone:
929 error.Clear();
930 break;
931
932 case FileAction::eFileActionClose:
933 if (info->GetFD() == -1)
934 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)");
935 else
936 {
937 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX);
938 if (log && (error.Fail() || log))
939 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)",
940 static_cast<void *>(file_actions), info->GetFD());
941 }
942 break;
943
944 case FileAction::eFileActionDuplicate:
945 if (info->GetFD() == -1)
946 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)");
947 else if (info->GetActionArgument() == -1)
948 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
949 else
950 {
951 error.SetError(
952 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()),
953 eErrorTypePOSIX);
954 if (log && (error.Fail() || log))
955 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)",
956 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument());
957 }
958 break;
959
960 case FileAction::eFileActionOpen:
961 if (info->GetFD() == -1)
962 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)");
963 else
964 {
965 int oflag = info->GetActionArgument();
966
967 mode_t mode = 0;
968
969 if (oflag & O_CREAT0100)
970 mode = 0640;
971
972 error.SetError(
973 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode),
974 eErrorTypePOSIX);
975 if (error.Fail() || log)
976 error.PutToLog(log,
977 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)",
978 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode);
979 }
980 break;
981 }
982 return error.Success();
983}
984#endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
985#endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__)
986
987#if defined(__linux__1) || defined(__FreeBSD__) || defined(__GLIBC__2) || defined(__NetBSD__) || defined(_WIN32)
988// The functions below implement process launching via posix_spawn() for Linux,
989// FreeBSD and NetBSD.
990
991Error
992Host::LaunchProcess (ProcessLaunchInfo &launch_info)
993{
994 std::unique_ptr<ProcessLauncher> delegate_launcher;
995#if defined(_WIN32)
996 delegate_launcher.reset(new ProcessLauncherWindows());
997#elif defined(__ANDROID__) || defined(__ANDROID_NDK__)
998 delegate_launcher.reset(new ProcessLauncherAndroid());
999#else
1000 delegate_launcher.reset(new ProcessLauncherPosix());
1001#endif
1002 MonitoringProcessLauncher launcher(std::move(delegate_launcher));
1003
1004 Error error;
1005 HostProcess process = launcher.LaunchProcess(launch_info, error);
1006
1007 // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing
1008 // it into this structure.
1009 launch_info.SetProcessID(process.GetProcessId());
1010
1011 return error;
1012}
1013#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
1014
1015#ifndef _WIN32
1016void
1017Host::Kill(lldb::pid_t pid, int signo)
1018{
1019 ::kill(pid, signo);
1020}
1021
1022#endif
1023
1024#if !defined (__APPLE__)
1025bool
1026Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1027{
1028 return false;
1029}
1030
1031void
1032Host::SetCrashDescriptionWithFormat (const char *format, ...)
1033{
1034}
1035
1036void
1037Host::SetCrashDescription (const char *description)
1038{
1039}
1040
1041#endif
1042
1043#if !defined (__linux__1) && !defined (__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined (__NetBSD__)
1044
1045const lldb_private::UnixSignalsSP&
1046Host::GetUnixSignals ()
1047{
1048 static UnixSignalsSP s_unix_signals_sp (new UnixSignals ());
1049 return s_unix_signals_sp;
1050}
1051
1052#endif