Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
platform_linux.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
7
8#include "bin/platform.h"
9
10#include <errno.h>
11#include <signal.h>
12#include <string.h>
13#include <sys/prctl.h>
14#include <sys/resource.h>
15#if defined(DART_HOST_OS_ANDROID)
16#include <sys/system_properties.h>
17#endif
18#include <sys/utsname.h>
19#include <unistd.h>
20
21#include "bin/console.h"
22#include "bin/file.h"
23
24namespace dart {
25namespace bin {
26
27const char* Platform::executable_name_ = nullptr;
28int Platform::script_index_ = 1;
29char** Platform::argv_ = nullptr;
30
31static const char* strcode(int si_signo, int si_code) {
32#define CASE(signo, code) \
33 if (si_signo == signo && si_code == code) return #code;
34
35 CASE(SIGILL, ILL_ILLOPC);
36 CASE(SIGILL, ILL_ILLOPN);
37 CASE(SIGILL, ILL_ILLADR);
38 CASE(SIGILL, ILL_ILLTRP);
39 CASE(SIGILL, ILL_PRVOPC);
40 CASE(SIGILL, ILL_PRVREG);
41 CASE(SIGILL, ILL_COPROC);
42 CASE(SIGILL, ILL_BADSTK);
43 CASE(SIGSEGV, SEGV_MAPERR);
44 CASE(SIGSEGV, SEGV_ACCERR);
45 CASE(SIGBUS, BUS_ADRALN);
46 CASE(SIGBUS, BUS_ADRERR);
47 CASE(SIGBUS, BUS_OBJERR);
48 CASE(SIGBUS, BUS_MCEERR_AR);
49 CASE(SIGBUS, BUS_MCEERR_AO);
50 CASE(SIGTRAP, TRAP_BRKPT);
51 CASE(SIGTRAP, TRAP_TRACE);
52#undef CASE
53 return "?";
54}
55
56static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
58 "\n===== CRASH =====\n"
59 "si_signo=%s(%d), si_code=%s(%d), si_addr=%p\n",
60 strsignal(siginfo->si_signo), siginfo->si_signo,
61 strcode(siginfo->si_signo, siginfo->si_code), siginfo->si_code,
62 siginfo->si_addr);
65 abort();
66}
67
69 // Turn off the signal handler for SIGPIPE as it causes the process
70 // to terminate on writing to a closed pipe. Without the signal
71 // handler error EPIPE is set instead.
72 struct sigaction act = {};
73 act.sa_handler = SIG_IGN;
74 if (sigaction(SIGPIPE, &act, nullptr) != 0) {
75 perror("Setting signal handler failed");
76 return false;
77 }
78
79 // tcsetattr raises SIGTTOU if we try to set console attributes when
80 // backgrounded, which suspends the process. Ignoring the signal prevents
81 // us from being suspended and lets us fail gracefully instead.
82 sigset_t signal_mask;
83 sigemptyset(&signal_mask);
84 sigaddset(&signal_mask, SIGTTOU);
85 if (sigprocmask(SIG_BLOCK, &signal_mask, nullptr) < 0) {
86 perror("Setting signal handler failed");
87 return false;
88 }
89
90 act.sa_flags = SA_SIGINFO;
91 act.sa_sigaction = &segv_handler;
92 if (sigemptyset(&act.sa_mask) != 0) {
93 perror("sigemptyset() failed.");
94 return false;
95 }
96 if (sigaddset(&act.sa_mask, SIGPROF) != 0) {
97 perror("sigaddset() failed");
98 return false;
99 }
100 if (sigaction(SIGSEGV, &act, nullptr) != 0) {
101 perror("sigaction() failed.");
102 return false;
103 }
104 if (sigaction(SIGBUS, &act, nullptr) != 0) {
105 perror("sigaction() failed.");
106 return false;
107 }
108 if (sigaction(SIGTRAP, &act, nullptr) != 0) {
109 perror("sigaction() failed.");
110 return false;
111 }
112 if (sigaction(SIGILL, &act, nullptr) != 0) {
113 perror("sigaction() failed.");
114 return false;
115 }
116 return true;
117}
118
120 return sysconf(_SC_NPROCESSORS_ONLN);
121}
122
124#if defined(DART_HOST_OS_ANDROID)
125 char os_version[PROP_VALUE_MAX + 1];
126 int os_version_length =
127 __system_property_get("ro.build.display.id", os_version);
128 if (os_version_length == 0) {
129 return nullptr;
130 }
131 os_version[Utils::Minimum(os_version_length, PROP_VALUE_MAX)] = '\0';
132 return DartUtils::ScopedCopyCString(os_version);
133#else
134 struct utsname info;
135 int ret = uname(&info);
136 if (ret != 0) {
137 return nullptr;
138 }
139 return DartUtils::ScopedCStringFormatted("%s %s %s", info.sysname,
140 info.release, info.version);
141#endif
142}
143
144const char* Platform::LibraryPrefix() {
145 return "lib";
146}
147
148const char* Platform::LibraryExtension() {
149 return "so";
150}
151
152const char* Platform::LocaleName() {
153 char* lang = getenv("LANG");
154 if (lang == nullptr) {
155 return "en_US";
156 }
157 return lang;
158}
159
160bool Platform::LocalHostname(char* buffer, intptr_t buffer_length) {
161 return gethostname(buffer, buffer_length) == 0;
162}
163
164char** Platform::Environment(intptr_t* count) {
165 // Using environ directly is only safe as long as we do not
166 // provide access to modifying environment variables.
167 intptr_t i = 0;
168 char** tmp = environ;
169 while (*(tmp++) != nullptr) {
170 i++;
171 }
172 *count = i;
173 char** result;
174 result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
175 for (intptr_t current = 0; current < i; current++) {
176 result[current] = environ[current];
177 }
178 return result;
179}
180
181const char* Platform::GetExecutableName() {
182 return executable_name_;
183}
184
186 return File::ReadLink("/proc/self/exe");
187}
188
189intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
190 return File::ReadLinkInto("/proc/self/exe", result, result_size);
191}
192
193void Platform::SetProcessName(const char* name) {
194 prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name), 0, 0, 0); // NOLINT
195}
196
197void Platform::Exit(int exit_code) {
200 exit(exit_code);
201}
202
203void Platform::_Exit(int exit_code) {
206 _exit(exit_code);
207}
208
210 rlimit limit = {static_cast<rlim_t>(value), static_cast<rlim_t>(value)};
211 setrlimit(RLIMIT_CORE, &limit);
212}
213
214} // namespace bin
215} // namespace dart
216
217#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
int count
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static T Minimum(T x, T y)
Definition utils.h:21
static void RestoreConfig()
static char * ScopedCStringFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition dartutils.cc:819
static char * ScopedCopyCString(const char *str)
Definition dartutils.h:232
static const char * ReadLink(const char *pathname)
static intptr_t ReadLinkInto(const char *pathname, char *result, size_t result_size)
static bool LocalHostname(char *buffer, intptr_t buffer_length)
static const char * GetExecutableName()
static const char * LibraryPrefix()
static DART_NORETURN void _Exit(int exit_code)
static void SetProcessName(const char *name)
static const char * LocaleName()
static DART_NORETURN void Exit(int exit_code)
static bool Initialize()
static char ** Environment(intptr_t *count)
static const char * OperatingSystemVersion()
static intptr_t ResolveExecutablePathInto(char *result, size_t result_size)
static int NumberOfProcessors()
static const char * LibraryExtension()
static const char * ResolveExecutablePath()
static void SetCoreDumpResourceLimit(int value)
static const uint8_t buffer[]
uint8_t value
GAsyncResult * result
#define CASE(Arity, Mask, Name, Args, Result)
exit(kErrorExitCode)
DART_EXPORT void Dart_PrepareToAbort()
const char *const name
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
DART_EXPORT void Dart_DumpNativeStackTrace(void *context)