Bug Summary

File:tools/lldb/source/Host/common/Host.cpp
Location:line 273, column 9
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#include "lldb/lldb-python.h"
11
12// C includes
13#include <errno(*__errno_location ()).h>
14#include <limits.h>
15#include <stdlib.h>
16#include <sys/types.h>
17#ifndef _WIN32
18#include <unistd.h>
19#include <dlfcn.h>
20#include <grp.h>
21#include <netdb.h>
22#include <pwd.h>
23#include <sys/stat.h>
24#endif
25
26#if defined (__APPLE__)
27#include <mach/mach_port.h>
28#include <mach/mach_init.h>
29#include <mach-o/dyld.h>
30#endif
31
32#if defined (__linux__1) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) || defined(__NetBSD__)
33#ifndef __ANDROID__
34#include <spawn.h>
35#endif
36#include <sys/wait.h>
37#include <sys/syscall.h>
38#endif
39
40#if defined (__FreeBSD__)
41#include <pthread_np.h>
42#endif
43
44// C++ includes
45#include <limits>
46
47#include "lldb/Host/Host.h"
48#include "lldb/Host/HostInfo.h"
49#include "lldb/Core/ArchSpec.h"
50#include "lldb/Core/Debugger.h"
51#include "lldb/Core/Error.h"
52#include "lldb/Core/Log.h"
53#include "lldb/Core/Module.h"
54#include "lldb/Host/FileSpec.h"
55#include "lldb/Host/HostProcess.h"
56#include "lldb/Host/MonitoringProcessLauncher.h"
57#include "lldb/Host/ProcessLauncher.h"
58#include "lldb/Host/ThreadLauncher.h"
59#include "lldb/lldb-private-forward.h"
60#include "lldb/Target/FileAction.h"
61#include "lldb/Target/ProcessLaunchInfo.h"
62#include "lldb/Target/TargetList.h"
63#include "lldb/Utility/CleanUp.h"
64
65#if defined(_WIN32)
66#include "lldb/Host/windows/ProcessLauncherWindows.h"
67#else
68#include "lldb/Host/posix/ProcessLauncherPosix.h"
69#endif
70
71#if defined (__APPLE__)
72#ifndef _POSIX_SPAWN_DISABLE_ASLR
73#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
74#endif
75
76extern "C"
77{
78 int __pthread_chdir(const char *path);
79 int __pthread_fchdir (int fildes);
80}
81
82#endif
83
84using namespace lldb;
85using namespace lldb_private;
86
87#if !defined (__APPLE__) && !defined (_WIN32)
88struct MonitorInfo
89{
90 lldb::pid_t pid; // The process ID to monitor
91 Host::MonitorChildProcessCallback callback; // The callback function to call when "pid" exits or signals
92 void *callback_baton; // The callback baton for the callback function
93 bool monitor_signals; // If true, call the callback when "pid" gets signaled.
94};
95
96static thread_result_t
97MonitorChildProcessThreadFunction (void *arg);
98
99HostThread
100Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals)
101{
102 MonitorInfo * info_ptr = new MonitorInfo();
103
104 info_ptr->pid = pid;
105 info_ptr->callback = callback;
106 info_ptr->callback_baton = callback_baton;
107 info_ptr->monitor_signals = monitor_signals;
108
109 char thread_name[256];
110 ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64"l" "u" ")>", pid);
111 return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL__null);
112}
113
114#ifndef __ANDROID__
115//------------------------------------------------------------------
116// Scoped class that will disable thread canceling when it is
117// constructed, and exception safely restore the previous value it
118// when it goes out of scope.
119//------------------------------------------------------------------
120class ScopedPThreadCancelDisabler
121{
122public:
123 ScopedPThreadCancelDisabler()
124 {
125 // Disable the ability for this thread to be cancelled
126 int err = ::pthread_setcancelstate (PTHREAD_CANCEL_DISABLEPTHREAD_CANCEL_DISABLE, &m_old_state);
127 if (err != 0)
128 m_old_state = -1;
129
130 }
131
132 ~ScopedPThreadCancelDisabler()
133 {
134 // Restore the ability for this thread to be cancelled to what it
135 // previously was.
136 if (m_old_state != -1)
137 ::pthread_setcancelstate (m_old_state, 0);
138 }
139private:
140 int m_old_state; // Save the old cancelability state.
141};
142#endif
143
144static thread_result_t
145MonitorChildProcessThreadFunction (void *arg)
146{
147 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1)));
148 const char *function = __FUNCTION__;
149 if (log)
1
Assuming 'log' is null
2
Taking false branch
150 log->Printf ("%s (arg = %p) thread starting...", function, arg);
151
152 MonitorInfo *info = (MonitorInfo *)arg;
153
154 const Host::MonitorChildProcessCallback callback = info->callback;
155 void * const callback_baton = info->callback_baton;
156 const bool monitor_signals = info->monitor_signals;
157
158 assert (info->pid <= UINT32_MAX)((info->pid <= (4294967295U)) ? static_cast<void>
(0) : __assert_fail ("info->pid <= (4294967295U)", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn220848/tools/lldb/source/Host/common/Host.cpp"
, 158, __PRETTY_FUNCTION__))
;
159 const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;
3
Assuming 'monitor_signals' is 0
4
'?' condition is false
160
161 delete info;
5
Memory is released
162
163 int status = -1;
164#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
165 #define __WALL0x40000000 0
166#endif
167 const int options = __WALL0x40000000;
168
169 while (1)
6
Loop condition is true. Entering loop body
12
Loop condition is true. Entering loop body
170 {
171 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS(1u << 1));
172 if (log)
7
Assuming 'log' is null
8
Taking false branch
13
Assuming 'log' is null
14
Taking false branch
173 log->Printf("%s ::wait_pid (pid = %" PRIi32"i" ", &status, options = %i)...", function, pid, options);
174
175 // Wait for all child processes
176#ifndef __ANDROID__
177 ::pthread_testcancel ();
178#endif
179 // Get signals from all children with same process group of pid
180 const ::pid_t wait_pid = ::waitpid (pid, &status, options);
181#ifndef __ANDROID__
182 ::pthread_testcancel ();
183#endif
184
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 false branch
192 log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno(*__errno_location ())));
193 break;
18
Execution continues on line 271
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#ifndef __ANDROID__
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 wait_pid,
238 options,
239 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)
19
Assuming 'log' is non-null
20
Taking true branch
273 log->Printf ("%s (arg = %p) thread exiting...", __FUNCTION__, arg);
21
Use of memory after it is freed
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(__linux__1)
320 return lldb::tid_t(syscall(SYS_gettid186));
321#else
322 return lldb::tid_t(pthread_self());
323#endif
324}
325
326lldb::thread_t
327Host::GetCurrentThread ()
328{
329 return lldb::thread_t(pthread_self());
330}
331
332const char *
333Host::GetSignalAsCString (int signo)
334{
335 switch (signo)
336 {
337 case SIGHUP1: return "SIGHUP"; // 1 hangup
338 case SIGINT2: return "SIGINT"; // 2 interrupt
339 case SIGQUIT3: return "SIGQUIT"; // 3 quit
340 case SIGILL4: return "SIGILL"; // 4 illegal instruction (not reset when caught)
341 case SIGTRAP5: return "SIGTRAP"; // 5 trace trap (not reset when caught)
342 case SIGABRT6: return "SIGABRT"; // 6 abort()
343#if defined(SIGPOLL29)
344#if !defined(SIGIO29) || (SIGPOLL29 != SIGIO29)
345// Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
346// fail with 'multiple define cases with same value'
347 case SIGPOLL29: return "SIGPOLL"; // 7 pollable event ([XSR] generated, not supported)
348#endif
349#endif
350#if defined(SIGEMT)
351 case SIGEMT: return "SIGEMT"; // 7 EMT instruction
352#endif
353 case SIGFPE8: return "SIGFPE"; // 8 floating point exception
354 case SIGKILL9: return "SIGKILL"; // 9 kill (cannot be caught or ignored)
355 case SIGBUS7: return "SIGBUS"; // 10 bus error
356 case SIGSEGV11: return "SIGSEGV"; // 11 segmentation violation
357 case SIGSYS31: return "SIGSYS"; // 12 bad argument to system call
358 case SIGPIPE13: return "SIGPIPE"; // 13 write on a pipe with no one to read it
359 case SIGALRM14: return "SIGALRM"; // 14 alarm clock
360 case SIGTERM15: return "SIGTERM"; // 15 software termination signal from kill
361 case SIGURG23: return "SIGURG"; // 16 urgent condition on IO channel
362 case SIGSTOP19: return "SIGSTOP"; // 17 sendable stop signal not from tty
363 case SIGTSTP20: return "SIGTSTP"; // 18 stop signal from tty
364 case SIGCONT18: return "SIGCONT"; // 19 continue a stopped process
365 case SIGCHLD17: return "SIGCHLD"; // 20 to parent on child stop or exit
366 case SIGTTIN21: return "SIGTTIN"; // 21 to readers pgrp upon background tty read
367 case SIGTTOU22: return "SIGTTOU"; // 22 like TTIN for output if (tp->t_local&LTOSTOP)
368#if defined(SIGIO29)
369 case SIGIO29: return "SIGIO"; // 23 input/output possible signal
370#endif
371 case SIGXCPU24: return "SIGXCPU"; // 24 exceeded CPU time limit
372 case SIGXFSZ25: return "SIGXFSZ"; // 25 exceeded file size limit
373 case SIGVTALRM26: return "SIGVTALRM"; // 26 virtual time alarm
374 case SIGPROF27: return "SIGPROF"; // 27 profiling time alarm
375#if defined(SIGWINCH28)
376 case SIGWINCH28: return "SIGWINCH"; // 28 window size changes
377#endif
378#if defined(SIGINFO)
379 case SIGINFO: return "SIGINFO"; // 29 information request
380#endif
381 case SIGUSR110: return "SIGUSR1"; // 30 user defined signal 1
382 case SIGUSR212: return "SIGUSR2"; // 31 user defined signal 2
383 default:
384 break;
385 }
386 return NULL__null;
387}
388
389#endif
390
391void
392Host::WillTerminate ()
393{
394}
395
396#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__1) // see macosx/Host.mm
397
398void
399Host::Backtrace (Stream &strm, uint32_t max_frames)
400{
401 // TODO: Is there a way to backtrace the current process on other systems?
402}
403
404size_t
405Host::GetEnvironment (StringList &env)
406{
407 // TODO: Is there a way to the host environment for this process on other systems?
408 return 0;
409}
410
411#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) && !defined (__linux__)
412
413#ifndef _WIN32
414
415lldb::thread_key_t
416Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback)
417{
418 pthread_key_t key;
419 ::pthread_key_create (&key, callback);
420 return key;
421}
422
423void*
424Host::ThreadLocalStorageGet(lldb::thread_key_t key)
425{
426 return ::pthread_getspecific (key);
427}
428
429void
430Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value)
431{
432 ::pthread_setspecific (key, value);
433}
434
435#endif
436
437#if !defined (__APPLE__) // see Host.mm
438
439bool
440Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
441{
442 bundle.Clear();
443 return false;
444}
445
446bool
447Host::ResolveExecutableInBundle (FileSpec &file)
448{
449 return false;
450}
451#endif
452
453#ifndef _WIN32
454
455FileSpec
456Host::GetModuleFileSpecForHostAddress (const void *host_addr)
457{
458 FileSpec module_filespec;
459#ifndef __ANDROID__
460 Dl_info info;
461 if (::dladdr (host_addr, &info))
462 {
463 if (info.dli_fname)
464 module_filespec.SetFile(info.dli_fname, true);
465 }
466#else
467 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.6~svn220848/tools/lldb/source/Host/common/Host.cpp"
, 467, __PRETTY_FUNCTION__))
;
468#endif
469 return module_filespec;
470}
471
472#endif
473
474#if !defined(__linux__1)
475bool
476Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
477{
478 return false;
479}
480#endif
481
482lldb::TargetSP
483Host::GetDummyTarget (lldb_private::Debugger &debugger)
484{
485 static TargetSP g_dummy_target_sp;
486
487 // FIXME: Maybe the dummy target should be per-Debugger
488 if (!g_dummy_target_sp || !g_dummy_target_sp->IsValid())
489 {
490 ArchSpec arch(Target::GetDefaultArchitecture());
491 if (!arch.IsValid())
492 arch = HostInfo::GetArchitecture();
493 Error err = debugger.GetTargetList().CreateTarget(debugger,
494 NULL__null,
495 arch.GetTriple().getTriple().c_str(),
496 false,
497 NULL__null,
498 g_dummy_target_sp);
499 }
500
501 return g_dummy_target_sp;
502}
503
504struct ShellInfo
505{
506 ShellInfo () :
507 process_reaped (false),
508 can_delete (false),
509 pid (LLDB_INVALID_PROCESS_ID0),
510 signo(-1),
511 status(-1)
512 {
513 }
514
515 lldb_private::Predicate<bool> process_reaped;
516 lldb_private::Predicate<bool> can_delete;
517 lldb::pid_t pid;
518 int signo;
519 int status;
520};
521
522static bool
523MonitorShellCommand (void *callback_baton,
524 lldb::pid_t pid,
525 bool exited, // True if the process did exit
526 int signo, // Zero for no signal
527 int status) // Exit value of process if signal is zero
528{
529 ShellInfo *shell_info = (ShellInfo *)callback_baton;
530 shell_info->pid = pid;
531 shell_info->signo = signo;
532 shell_info->status = status;
533 // Let the thread running Host::RunShellCommand() know that the process
534 // exited and that ShellInfo has been filled in by broadcasting to it
535 shell_info->process_reaped.SetValue(1, eBroadcastAlways);
536 // Now wait for a handshake back from that thread running Host::RunShellCommand
537 // so we know that we can delete shell_info_ptr
538 shell_info->can_delete.WaitForValueEqualTo(true);
539 // Sleep a bit to allow the shell_info->can_delete.SetValue() to complete...
540 usleep(1000);
541 // Now delete the shell info that was passed into this function
542 delete shell_info;
543 return true;
544}
545
546Error
547Host::RunShellCommand (const char *command,
548 const char *working_dir,
549 int *status_ptr,
550 int *signo_ptr,
551 std::string *command_output_ptr,
552 uint32_t timeout_sec,
553 bool run_in_default_shell)
554{
555 Error error;
556 ProcessLaunchInfo launch_info;
557 if (run_in_default_shell)
558 {
559 // Run the command in a shell
560 launch_info.SetShell(HostInfo::GetDefaultShell());
561 launch_info.GetArguments().AppendArgument(command);
562 const bool localhost = true;
563 const bool will_debug = false;
564 const bool first_arg_is_full_shell_command = true;
565 launch_info.ConvertArgumentsForLaunchingInShell (error,
566 localhost,
567 will_debug,
568 first_arg_is_full_shell_command,
569 0);
570 }
571 else
572 {
573 // No shell, just run it
574 Args args (command);
575 const bool first_arg_is_executable = true;
576 launch_info.SetArguments(args, first_arg_is_executable);
577 }
578
579 if (working_dir)
580 launch_info.SetWorkingDirectory(working_dir);
581 char output_file_path_buffer[PATH_MAX4096];
582 const char *output_file_path = NULL__null;
583
584 if (command_output_ptr)
585 {
586 // Create a temporary file to get the stdout/stderr and redirect the
587 // output of the command into this file. We will later read this file
588 // if all goes well and fill the data into "command_output_ptr"
589 FileSpec tmpdir_file_spec;
590 if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
591 {
592 tmpdir_file_spec.AppendPathComponent("lldb-shell-output.XXXXXX");
593 strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer));
594 }
595 else
596 {
597 strncpy(output_file_path_buffer, "/tmp/lldb-shell-output.XXXXXX", sizeof(output_file_path_buffer));
598 }
599
600 output_file_path = ::mktemp(output_file_path_buffer);
601 }
602
603 launch_info.AppendSuppressFileAction (STDIN_FILENO0, true, false);
604 if (output_file_path)
605 {
606 launch_info.AppendOpenFileAction(STDOUT_FILENO1, output_file_path, false, true);
607 launch_info.AppendDuplicateFileAction(STDOUT_FILENO1, STDERR_FILENO2);
608 }
609 else
610 {
611 launch_info.AppendSuppressFileAction (STDOUT_FILENO1, false, true);
612 launch_info.AppendSuppressFileAction (STDERR_FILENO2, false, true);
613 }
614
615 // The process monitor callback will delete the 'shell_info_ptr' below...
616 std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
617
618 const bool monitor_signals = false;
619 launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
620
621 error = LaunchProcess (launch_info);
622 const lldb::pid_t pid = launch_info.GetProcessID();
623
624 if (error.Success() && pid == LLDB_INVALID_PROCESS_ID0)
625 error.SetErrorString("failed to get process ID");
626
627 if (error.Success())
628 {
629 // The process successfully launched, so we can defer ownership of
630 // "shell_info" to the MonitorShellCommand callback function that will
631 // get called when the process dies. We release the unique pointer as it
632 // doesn't need to delete the ShellInfo anymore.
633 ShellInfo *shell_info = shell_info_ap.release();
634 TimeValue *timeout_ptr = nullptr;
635 TimeValue timeout_time(TimeValue::Now());
636 if (timeout_sec > 0) {
637 timeout_time.OffsetWithSeconds(timeout_sec);
638 timeout_ptr = &timeout_time;
639 }
640 bool timed_out = false;
641 shell_info->process_reaped.WaitForValueEqualTo(true, timeout_ptr, &timed_out);
642 if (timed_out)
643 {
644 error.SetErrorString("timed out waiting for shell command to complete");
645
646 // Kill the process since it didn't complete within the timeout specified
647 Kill (pid, SIGKILL9);
648 // Wait for the monitor callback to get the message
649 timeout_time = TimeValue::Now();
650 timeout_time.OffsetWithSeconds(1);
651 timed_out = false;
652 shell_info->process_reaped.WaitForValueEqualTo(true, &timeout_time, &timed_out);
653 }
654 else
655 {
656 if (status_ptr)
657 *status_ptr = shell_info->status;
658
659 if (signo_ptr)
660 *signo_ptr = shell_info->signo;
661
662 if (command_output_ptr)
663 {
664 command_output_ptr->clear();
665 FileSpec file_spec(output_file_path, File::eOpenOptionRead);
666 uint64_t file_size = file_spec.GetByteSize();
667 if (file_size > 0)
668 {
669 if (file_size > command_output_ptr->max_size())
670 {
671 error.SetErrorStringWithFormat("shell command output is too large to fit into a std::string");
672 }
673 else
674 {
675 command_output_ptr->resize(file_size);
676 file_spec.ReadFileContents(0, &((*command_output_ptr)[0]), command_output_ptr->size(), &error);
677 }
678 }
679 }
680 }
681 shell_info->can_delete.SetValue(true, eBroadcastAlways);
682 }
683
684 if (output_file_path)
685 ::unlink (output_file_path);
686 // Handshake with the monitor thread, or just let it know in advance that
687 // it can delete "shell_info" in case we timed out and were not able to kill
688 // the process...
689 return error;
690}
691
692
693// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC
694// systems
695
696#if defined (__APPLE__) || defined (__linux__1) || defined (__FreeBSD__) || defined (__GLIBC__2) || defined(__NetBSD__)
697
698// this method needs to be visible to macosx/Host.cpp and
699// common/Host.cpp.
700
701short
702Host::GetPosixspawnFlags(const ProcessLaunchInfo &launch_info)
703{
704#ifndef __ANDROID__
705 short flags = POSIX_SPAWN_SETSIGDEF0x04 | POSIX_SPAWN_SETSIGMASK0x08;
706
707#if defined (__APPLE__)
708 if (launch_info.GetFlags().Test (eLaunchFlagExec))
709 flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
710
711 if (launch_info.GetFlags().Test (eLaunchFlagDebug))
712 flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
713
714 if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
715 flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
716
717 if (launch_info.GetLaunchInSeparateProcessGroup())
718 flags |= POSIX_SPAWN_SETPGROUP0x02;
719
720#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
721#if defined (__APPLE__) && (defined (__x86_64__1) || defined (__i386__))
722 static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
723 if (g_use_close_on_exec_flag == eLazyBoolCalculate)
724 {
725 g_use_close_on_exec_flag = eLazyBoolNo;
726
727 uint32_t major, minor, update;
728 if (HostInfo::GetOSVersion(major, minor, update))
729 {
730 // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or earlier
731 if (major > 10 || (major == 10 && minor > 7))
732 {
733 // Only enable for 10.8 and later OS versions
734 g_use_close_on_exec_flag = eLazyBoolYes;
735 }
736 }
737 }
738#else
739 static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
740#endif
741 // Close all files exception those with file actions if this is supported.
742 if (g_use_close_on_exec_flag == eLazyBoolYes)
743 flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
744#endif
745#endif // #if defined (__APPLE__)
746 return flags;
747#else
748 assert(false *&& "Host::GetPosixspawnFlags() not supported on Android")((false *&& "Host::GetPosixspawnFlags() not supported on Android"
) ? static_cast<void> (0) : __assert_fail ("false *&& \"Host::GetPosixspawnFlags() not supported on Android\""
, "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn220848/tools/lldb/source/Host/common/Host.cpp"
, 748, __PRETTY_FUNCTION__))
;
749 return 0;
750#endif
751}
752
753Error
754Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid)
755{
756 Error error;
757#ifndef __ANDROID__
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 = (char * const*)launch_info.GetArguments().GetConstArgumentVector();
826 char * const *envp = (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 = (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 const char *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) < 0) {
849 if (errno(*__errno_location ()) == ENOENT2) {
850 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
851 } else if (errno(*__errno_location ()) == ENOTDIR20) {
852 error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir);
853 } else {
854 error.SetErrorStringWithFormat("An unknown error occurred when changing directory for process execution.");
855 }
856 return error;
857 }
858#else
859 if (::getcwd(current_dir, sizeof(current_dir)) == NULL__null)
860 {
861 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
862 error.LogIfError(log, "unable to save the current directory");
863 return error;
864 }
865
866 if (::chdir(working_dir) == -1)
867 {
868 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
869 error.LogIfError(log, "unable to change working directory to %s", working_dir);
870 return error;
871 }
872#endif
873 }
874
875 ::pid_t result_pid = LLDB_INVALID_PROCESS_ID0;
876 const size_t num_file_actions = launch_info.GetNumFileActions ();
877 if (num_file_actions > 0)
878 {
879 posix_spawn_file_actions_t file_actions;
880 error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
881 if (error.Fail() || log)
882 error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
883 if (error.Fail())
884 return error;
885
886 // Make a quick class that will cleanup the posix spawn attributes in case
887 // we return in the middle of this function.
888 lldb_utility::CleanUp <posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup (&file_actions, posix_spawn_file_actions_destroy);
889
890 for (size_t i=0; i<num_file_actions; ++i)
891 {
892 const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i);
893 if (launch_file_action)
894 {
895 if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error))
896 return error;
897 }
898 }
899
900 error.SetError(::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX);
901
902 if (error.Fail() || log)
903 {
904 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", result_pid,
905 exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
906 reinterpret_cast<const void *>(envp));
907 if (log)
908 {
909 for (int ii=0; argv[ii]; ++ii)
910 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
911 }
912 }
913
914 }
915 else
916 {
917 error.SetError(::posix_spawnp(&result_pid, exe_path, NULL__null, &attr, argv, envp), eErrorTypePOSIX);
918
919 if (error.Fail() || log)
920 {
921 error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
922 result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
923 reinterpret_cast<const void *>(envp));
924 if (log)
925 {
926 for (int ii=0; argv[ii]; ++ii)
927 log->Printf("argv[%i] = '%s'", ii, argv[ii]);
928 }
929 }
930 }
931 pid = result_pid;
932
933 if (working_dir)
934 {
935#if defined (__APPLE__)
936 // No more thread specific current working directory
937 __pthread_fchdir (-1);
938#else
939 if (::chdir(current_dir) == -1 && error.Success())
940 {
941 error.SetError(errno(*__errno_location ()), eErrorTypePOSIX);
942 error.LogIfError(log, "unable to change current directory back to %s",
943 current_dir);
944 }
945#endif
946 }
947#else
948 error.SetErrorString("Host::LaunchProcessPosixSpawn() not supported on Android");
949#endif
950
951 return error;
952}
953
954bool
955Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error)
956{
957#ifndef __ANDROID__
958 if (info == NULL__null)
959 return false;
960
961 posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
962
963 switch (info->GetAction())
964 {
965 case FileAction::eFileActionNone:
966 error.Clear();
967 break;
968
969 case FileAction::eFileActionClose:
970 if (info->GetFD() == -1)
971 error.SetErrorString("invalid fd for posix_spawn_file_actions_addclose(...)");
972 else
973 {
974 error.SetError(::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX);
975 if (log && (error.Fail() || log))
976 error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)",
977 static_cast<void *>(file_actions), info->GetFD());
978 }
979 break;
980
981 case FileAction::eFileActionDuplicate:
982 if (info->GetFD() == -1)
983 error.SetErrorString("invalid fd for posix_spawn_file_actions_adddup2(...)");
984 else if (info->GetActionArgument() == -1)
985 error.SetErrorString("invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
986 else
987 {
988 error.SetError(
989 ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()),
990 eErrorTypePOSIX);
991 if (log && (error.Fail() || log))
992 error.PutToLog(log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)",
993 static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument());
994 }
995 break;
996
997 case FileAction::eFileActionOpen:
998 if (info->GetFD() == -1)
999 error.SetErrorString("invalid fd in posix_spawn_file_actions_addopen(...)");
1000 else
1001 {
1002 int oflag = info->GetActionArgument();
1003
1004 mode_t mode = 0;
1005
1006 if (oflag & O_CREAT0100)
1007 mode = 0640;
1008
1009 error.SetError(
1010 ::posix_spawn_file_actions_addopen(file_actions, info->GetFD(), info->GetPath(), oflag, mode),
1011 eErrorTypePOSIX);
1012 if (error.Fail() || log)
1013 error.PutToLog(log,
1014 "posix_spawn_file_actions_addopen (action=%p, fd=%i, path='%s', oflag=%i, mode=%i)",
1015 static_cast<void *>(file_actions), info->GetFD(), info->GetPath(), oflag, mode);
1016 }
1017 break;
1018 }
1019 return error.Success();
1020#else
1021 error.SetErrorString("Host::AddPosixSpawnFileAction() not supported on Android");
1022 return false;
1023#endif
1024}
1025
1026#endif // LaunchProcedssPosixSpawn: Apple, Linux, FreeBSD and other GLIBC systems
1027
1028#if defined(__linux__1) || defined(__FreeBSD__) || defined(__GLIBC__2) || defined(__NetBSD__) || defined(_WIN32)
1029// The functions below implement process launching via posix_spawn() for Linux,
1030// FreeBSD and NetBSD.
1031
1032Error
1033Host::LaunchProcess (ProcessLaunchInfo &launch_info)
1034{
1035 std::unique_ptr<ProcessLauncher> delegate_launcher;
1036#if defined(_WIN32)
1037 delegate_launcher.reset(new ProcessLauncherWindows());
1038#else
1039 delegate_launcher.reset(new ProcessLauncherPosix());
1040#endif
1041 MonitoringProcessLauncher launcher(std::move(delegate_launcher));
1042
1043 Error error;
1044 HostProcess process = launcher.LaunchProcess(launch_info, error);
1045
1046 // TODO(zturner): It would be better if the entire HostProcess were returned instead of writing
1047 // it into this structure.
1048 launch_info.SetProcessID(process.GetProcessId());
1049
1050 return error;
1051}
1052
1053#endif // defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
1054
1055#ifndef _WIN32
1056
1057void
1058Host::Kill(lldb::pid_t pid, int signo)
1059{
1060 ::kill(pid, signo);
1061}
1062
1063#endif
1064
1065#if !defined (__APPLE__)
1066bool
1067Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no)
1068{
1069 return false;
1070}
1071
1072void
1073Host::SetCrashDescriptionWithFormat (const char *format, ...)
1074{
1075}
1076
1077void
1078Host::SetCrashDescription (const char *description)
1079{
1080}
1081
1082lldb::pid_t
1083Host::LaunchApplication (const FileSpec &app_file_spec)
1084{
1085 return LLDB_INVALID_PROCESS_ID0;
1086}
1087
1088#endif
1089
1090#if !defined (__linux__1) && !defined (__FreeBSD__) && !defined (__NetBSD__)
1091
1092const lldb_private::UnixSignalsSP&
1093Host::GetUnixSignals ()
1094{
1095 static UnixSignalsSP s_unix_signals_sp (new UnixSignals ());
1096 return s_unix_signals_sp;
1097}
1098
1099#endif