Flutter Engine
The Flutter Engine
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
Definition: FontMgrTest.cpp:50
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static T Minimum(T x, T y)
Definition: utils.h:36
static void RestoreConfig()
static char * ScopedCStringFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
Definition: dartutils.cc:813
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)
uint8_t value
GAsyncResult * result
#define CASE(Arity, Mask, Name, Args, Result)
exit(kErrorExitCode)
Definition: dart_vm.cc:33
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)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126