1 //===-- HostProcessPosix.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/Host/Host.h"
11 #include "lldb/Host/posix/HostProcessPosix.h"
12 #include "lldb/Host/FileSystem.h"
13
14 #include "llvm/ADT/STLExtras.h"
15
16 #include <limits.h>
17
18 using namespace lldb_private;
19
20 namespace
21 {
22 const int kInvalidPosixProcess = 0;
23 }
24
HostProcessPosix()25 HostProcessPosix::HostProcessPosix()
26 : HostNativeProcessBase(kInvalidPosixProcess)
27 {
28 }
29
HostProcessPosix(lldb::process_t process)30 HostProcessPosix::HostProcessPosix(lldb::process_t process)
31 : HostNativeProcessBase(process)
32 {
33 }
34
~HostProcessPosix()35 HostProcessPosix::~HostProcessPosix()
36 {
37 }
38
Signal(int signo) const39 Error HostProcessPosix::Signal(int signo) const
40 {
41 if (m_process == kInvalidPosixProcess)
42 {
43 Error error;
44 error.SetErrorString("HostProcessPosix refers to an invalid process");
45 return error;
46 }
47
48 return HostProcessPosix::Signal(m_process, signo);
49 }
50
Signal(lldb::process_t process,int signo)51 Error HostProcessPosix::Signal(lldb::process_t process, int signo)
52 {
53 Error error;
54
55 if (-1 == ::kill(process, signo))
56 error.SetErrorToErrno();
57
58 return error;
59 }
60
Terminate()61 Error HostProcessPosix::Terminate()
62 {
63 return Signal(SIGKILL);
64 }
65
GetMainModule(FileSpec & file_spec) const66 Error HostProcessPosix::GetMainModule(FileSpec &file_spec) const
67 {
68 Error error;
69
70 // Use special code here because proc/[pid]/exe is a symbolic link.
71 char link_path[PATH_MAX];
72 if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", m_process) != 1)
73 {
74 error.SetErrorString("Unable to build /proc/<pid>/exe string");
75 return error;
76 }
77
78 error = FileSystem::Readlink(FileSpec{link_path, false}, file_spec);
79 if (!error.Success())
80 return error;
81
82 // If the binary has been deleted, the link name has " (deleted)" appended.
83 // Remove if there.
84 if (file_spec.GetFilename().GetStringRef().endswith(" (deleted)"))
85 {
86 const char *filename = file_spec.GetFilename().GetCString();
87 static const size_t deleted_len = strlen(" (deleted)");
88 const size_t len = file_spec.GetFilename().GetLength();
89 file_spec.GetFilename().SetCStringWithLength(filename, len - deleted_len);
90 }
91 return error;
92 }
93
GetProcessId() const94 lldb::pid_t HostProcessPosix::GetProcessId() const
95 {
96 return m_process;
97 }
98
IsRunning() const99 bool HostProcessPosix::IsRunning() const
100 {
101 if (m_process == kInvalidPosixProcess)
102 return false;
103
104 // Send this process the null signal. If it succeeds the process is running.
105 Error error = Signal(0);
106 return error.Success();
107 }
108
109 HostThread
StartMonitoring(HostProcess::MonitorCallback callback,void * callback_baton,bool monitor_signals)110 HostProcessPosix::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
111 {
112 return Host::StartMonitoringChildProcess(callback, callback_baton, m_process, monitor_signals);
113 }
114