Bug Summary

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