blob: dfd691facdb569c6bb03c72a43bd3fa363060034 [file] [log] [blame]
James M Snell98e54b02017-01-03 21:16:481// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
Joyee Cheung3d668262018-11-28 16:46:4522#include "node_binding.h"
Ben Noordhuis02cab972013-07-31 21:16:0823#include "node_buffer.h"
24#include "node_constants.h"
Joyee Cheung58502202018-11-03 14:45:4025#include "node_context_data.h"
26#include "node_errors.h"
27#include "node_internals.h"
Joyee Cheungd17d7bd2018-12-01 20:16:0928#include "node_metadata.h"
Joyee Cheungbd765d62018-11-03 06:26:3229#include "node_native_module.h"
Joyee Cheung61a89632018-12-01 17:30:3030#include "node_options-inl.h"
Joyee Cheungbd765d62018-11-03 06:26:3231#include "node_perf.h"
Matt Loring9e086952017-03-13 22:17:5732#include "node_platform.h"
Joyee Cheung78242802018-12-31 15:18:0833#include "node_process.h"
James M Snelld3875912016-02-04 01:16:1034#include "node_revert.h"
Joyee Cheung99c32432019-01-16 18:34:4335#include "node_v8_platform-inl.h"
Joyee Cheung58502202018-11-03 14:45:4036#include "node_version.h"
Ben Noordhuis02cab972013-07-31 21:16:0837
Ben Noordhuis02cab972013-07-31 21:16:0838#if HAVE_OPENSSL
39#include "node_crypto.h"
40#endif
41
Steven R. Loomisac2857b2014-09-05 05:03:2442#if defined(NODE_HAVE_I18N_SUPPORT)
43#include "node_i18n.h"
44#endif
45
Ben Noordhuis399cb252017-05-27 11:31:0046#if HAVE_INSPECTOR
47#include "inspector_io.h"
48#endif
49
Ben Noordhuisc4def502013-10-28 19:18:5950#if defined HAVE_DTRACE || defined HAVE_ETW
Ben Noordhuis02cab972013-07-31 21:16:0851#include "node_dtrace.h"
52#endif
53
Daniel Bevenius78447662017-11-14 12:34:5254#include "async_wrap-inl.h"
Ben Noordhuis756b6222013-08-10 22:26:1155#include "env-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0856#include "handle_wrap.h"
Daniel Beveniusb58a1cd2017-11-14 12:34:5257#include "req_wrap-inl.h"
Ben Noordhuis02cab972013-07-31 21:16:0858#include "string_bytes.h"
Timothy J Fontaine1a09da62014-06-10 23:36:0459#include "util.h"
Ben Noordhuisff4a9d32012-03-09 23:11:1160#include "uv.h"
Stefan Budeanu410296c2016-03-27 00:17:5561#if NODE_USE_V8_PLATFORM
Ben Noordhuis4a801c22015-04-02 21:51:0162#include "libplatform/libplatform.h"
Stefan Budeanu410296c2016-03-27 00:17:5563#endif // NODE_USE_V8_PLATFORM
Ben Noordhuis57231d52013-10-02 04:37:4464#include "v8-profiler.h"
Ryan Dahl4635ed72010-03-11 20:40:1965
Chunyang Daia881b532015-10-21 16:24:1266#ifdef NODE_ENABLE_VTUNE_PROFILING
67#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
68#endif
69
Suresh Srinivasbf7ed802018-03-23 19:16:4870#ifdef NODE_ENABLE_LARGE_CODE_PAGES
71#include "large_pages/node_large_page.h"
72#endif
73
Ben Noordhuis02cab972013-07-31 21:16:0874#include <errno.h>
Myles Borins9cc39ff2017-04-24 16:47:2675#include <fcntl.h> // _O_RDWR
Ben Noordhuis02cab972013-07-31 21:16:0876#include <limits.h> // PATH_MAX
Bert Belder9cec08e2011-05-23 23:42:2277#include <signal.h>
Ryan19478ed2009-03-03 00:56:1578#include <stdio.h>
Ryan34a6f102009-05-28 12:47:1679#include <stdlib.h>
Ryan Dahlc90e44e2010-05-10 23:38:4780#include <string.h>
Ben Noordhuis02cab972013-07-31 21:16:0881#include <sys/types.h>
Ben Noordhuisc5c28c32015-10-10 13:01:4982
83#include <string>
Brian White2d356072015-10-13 21:18:1584#include <vector>
Ben Noordhuis02cab972013-07-31 21:16:0885
Evan Lucas30b8bb02015-09-27 15:59:0286#if defined(NODE_HAVE_I18N_SUPPORT)
87#include <unicode/uvernum.h>
88#endif
89
Gireesh Punathil4f679732018-09-05 14:06:5990#ifdef NODE_REPORT
91#include "node_report.h"
92#endif
93
Karl Skomski6ed06032015-08-14 08:07:1894#if defined(LEAK_SANITIZER)
95#include <sanitizer/lsan_interface.h>
96#endif
97
Ben Noordhuis02cab972013-07-31 21:16:0898#if defined(_MSC_VER)
Peter Bright13d6a1f2011-08-06 04:23:2599#include <direct.h>
Peter Brightb9d77772011-08-11 01:45:56100#include <io.h>
Joyee Cheung6967f912019-01-15 15:12:21101#define STDIN_FILENO 0
Ben Noordhuis02cab972013-07-31 21:16:08102#else
Ben Noordhuis844f0a92016-03-25 16:59:07103#include <pthread.h>
Ben Noordhuis68200542013-10-02 10:17:57104#include <sys/resource.h> // getrlimit, setrlimit
Joyee Cheung321e2962018-12-15 19:13:12105#include <unistd.h> // STDIN_FILENO, STDERR_FILENO
Bert Beldera177d602010-11-25 00:02:55106#endif
107
Ryand6c9d312009-09-11 14:02:29108namespace node {
109
Anna Henningsene812be42018-08-23 14:41:05110using options_parser::kAllowedInEnvironment;
111using options_parser::kDisallowedInEnvironment;
Ben Noordhuis110a9cd2013-07-03 02:23:44112using v8::Array;
113using v8::Boolean;
114using v8::Context;
Gireesh Punathil31ca5dc2018-09-01 06:49:02115using v8::DEFAULT;
Joyee Cheung6967f912019-01-15 15:12:21116using v8::EscapableHandleScope;
Ben Noordhuis110a9cd2013-07-03 02:23:44117using v8::Exception;
118using v8::Function;
119using v8::FunctionCallbackInfo;
Ben Noordhuis110a9cd2013-07-03 02:23:44120using v8::HandleScope;
Ben Noordhuis110a9cd2013-07-03 02:23:44121using v8::Isolate;
Anna Henningsenf3cd5372017-12-01 23:04:56122using v8::Just;
Ben Noordhuis511af4d2013-07-30 19:28:43123using v8::Local;
Ben Noordhuis110a9cd2013-07-03 02:23:44124using v8::Locker;
Anna Henningsenf3cd5372017-12-01 23:04:56125using v8::Maybe;
Michaël Zasso023c3172016-02-08 21:34:05126using v8::MaybeLocal;
Ben Noordhuis110a9cd2013-07-03 02:23:44127using v8::Object;
Gireesh Punathil31ca5dc2018-09-01 06:49:02128using v8::Script;
Fedor Indutnya07c6912015-04-11 14:02:33129using v8::SealHandleScope;
Ben Noordhuis511af4d2013-07-30 19:28:43130using v8::String;
Anna Henningsen64616bb2017-08-08 18:02:55131using v8::Undefined;
Ben Noordhuis110a9cd2013-07-03 02:23:44132using v8::V8;
133using v8::Value;
Ben Noordhuis110a9cd2013-07-03 02:23:44134
Joyee Cheung9db9e7e2019-01-01 05:56:53135namespace per_process {
James M Snell35f6e592017-08-16 16:34:37136
Joyee Cheung9db9e7e2019-01-01 05:56:53137// node_revert.h
138// Bit flag used to track security reverts.
139unsigned int reverted_cve = 0;
140
141// util.h
142// Tells whether the per-process V8::Initialize() is called and
143// if it is safe to call v8::Isolate::GetCurrent().
Anna Henningsen72c60e82016-09-10 16:21:20144bool v8_initialized = false;
145
Joyee Cheung9db9e7e2019-01-01 05:56:53146// node_internals.h
Ben Noordhuis74a82152012-02-03 15:32:00147// process-relative uptime base, initialized at start-up
James M Snellbaadc7a2018-06-03 00:27:03148double prog_start_time;
Joyee Cheungca9e24e2019-01-16 19:00:55149// Tells whether --prof is passed.
150bool v8_is_profiling = false;
Joyee Cheung99c32432019-01-16 18:34:43151
152// node_v8_platform-inl.h
153struct V8Platform v8_platform;
Joyee Cheung9db9e7e2019-01-01 05:56:53154} // namespace per_process
Stefan Budeanu410296c2016-03-27 00:17:55155
Ben Noordhuis844f0a92016-03-25 16:59:07156#ifdef __POSIX__
Eugene Ostroukhov66269192016-06-08 21:09:28157static const unsigned kMaxSignal = 32;
Ben Noordhuis844f0a92016-03-25 16:59:07158#endif
159
Joyee Cheungeb686192019-02-01 00:00:23160void WaitForInspectorDisconnect(Environment* env) {
Eugene Ostroukhov66269192016-06-08 21:09:28161#if HAVE_INSPECTOR
Eugene Ostroukhov39977db2018-05-21 23:59:04162 if (env->inspector_agent()->IsActive()) {
Eugene Ostroukhov66269192016-06-08 21:09:28163 // Restore signal dispositions, the app is done and is no longer
164 // capable of handling signals.
Stewart X Addison0f0f3d32016-12-30 12:44:46165#if defined(__POSIX__) && !defined(NODE_SHARED_MODE)
Eugene Ostroukhov66269192016-06-08 21:09:28166 struct sigaction act;
167 memset(&act, 0, sizeof(act));
168 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
169 if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
170 continue;
171 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
172 CHECK_EQ(0, sigaction(nr, &act, nullptr));
173 }
174#endif
175 env->inspector_agent()->WaitForDisconnect();
176 }
177#endif
178}
179
Anna Henningsen0815b942016-05-08 01:28:47180void SignalExit(int signo) {
Evan Lucas14dc17d2018-06-11 14:20:50181 uv_tty_reset_mode();
Fedor Indutnyb64983d2015-03-20 05:03:34182#ifdef __FreeBSD__
183 // FreeBSD has a nasty bug, see RegisterSignalHandler for details
184 struct sigaction sa;
185 memset(&sa, 0, sizeof(sa));
186 sa.sa_handler = SIG_DFL;
187 CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
188#endif
Geir Haugec61b0e92014-03-31 07:52:03189 raise(signo);
Dean McNameef67e8f22011-03-15 22:39:16190}
191
Joyee Cheungedcb9502018-11-26 17:50:41192static MaybeLocal<Value> ExecuteBootstrapper(
Anna Henningsen0df031a2017-09-01 15:03:41193 Environment* env,
Joyee Cheungedcb9502018-11-26 17:50:41194 const char* id,
195 std::vector<Local<String>>* parameters,
196 std::vector<Local<Value>>* arguments) {
Joyee Cheung6967f912019-01-15 15:12:21197 EscapableHandleScope scope(env->isolate());
198 MaybeLocal<Function> maybe_fn =
199 per_process::native_module_loader.LookupAndCompile(
200 env->context(), id, parameters, env);
201
202 if (maybe_fn.IsEmpty()) {
203 return MaybeLocal<Value>();
204 }
205
206 Local<Function> fn = maybe_fn.ToLocalChecked();
207 MaybeLocal<Value> result = fn->Call(env->context(),
208 Undefined(env->isolate()),
209 arguments->size(),
210 arguments->data());
Joyee Cheung2a9eb312018-03-03 20:55:45211
212 // If there was an error during bootstrap then it was either handled by the
213 // FatalException handler or it's unrecoverable (e.g. max call stack
214 // exceeded). Either way, clear the stack so that the AsyncCallbackScope
215 // destructor doesn't fail on the id check.
216 // There are only two ways to have a stack size > 1: 1) the user manually
217 // called MakeCallback or 2) user awaited during bootstrap, which triggered
218 // _tickCallback().
Joyee Cheung6967f912019-01-15 15:12:21219 if (result.IsEmpty()) {
Joyee Cheung2a9eb312018-03-03 20:55:45220 env->async_hooks()->clear_async_id_stack();
221 }
222
Joyee Cheung6967f912019-01-15 15:12:21223 return scope.EscapeMaybe(result);
Joyee Cheung2a9eb312018-03-03 20:55:45224}
225
Joyee Cheung6967f912019-01-15 15:12:21226MaybeLocal<Value> RunBootstrapping(Environment* env) {
Anna Henningsenf6a1d882019-01-02 21:14:23227 CHECK(!env->has_run_bootstrapping_code());
Anna Henningsenf6a1d882019-01-02 21:14:23228
Joyee Cheung6967f912019-01-15 15:12:21229 EscapableHandleScope scope(env->isolate());
Joyee Cheung7778c032018-11-14 14:38:12230 Isolate* isolate = env->isolate();
Joyee Cheungedcb9502018-11-26 17:50:41231 Local<Context> context = env->context();
Anna Henningsen0df031a2017-09-01 15:03:41232
Ryan Dahlf8ce8482010-09-17 07:01:07233 // Add a reference to the global object
Joyee Cheungedcb9502018-11-26 17:50:41234 Local<Object> global = context->Global();
Zoran Tomicicd98ea702010-02-22 05:15:44235
Ben Noordhuisc4def502013-10-28 19:18:59236#if defined HAVE_DTRACE || defined HAVE_ETW
Fedor Indutny75adde02014-02-21 13:02:42237 InitDTrace(env, global);
Ryan Dahle9257b82011-02-10 02:50:26238#endif
Ryan Dahl068b7332011-01-25 01:50:10239
Joyee Cheungedcb9502018-11-26 17:50:41240 Local<Object> process = env->process_object();
Ryan Dahl9f5643f2010-01-31 07:22:34241
Joyee Cheungedcb9502018-11-26 17:50:41242 // Setting global properties for the bootstrappers to use:
243 // - global
Jeremiah Senkpiel21d66d62016-03-23 22:09:10244 // Expose the global object as a property on itself
245 // (Allows you to set stuff on `global` from anywhere in JavaScript.)
Joyee Cheungedcb9502018-11-26 17:50:41246 global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global)
247 .FromJust();
Jeremiah Senkpiel21d66d62016-03-23 22:09:10248
Joyee Cheung39d92212019-01-30 14:21:07249 // Store primordials
250 env->set_primordials(Object::New(isolate));
251 std::vector<Local<String>> primordials_params = {
252 FIXED_ONE_BYTE_STRING(isolate, "breakAtBootstrap"),
253 env->primordials_string()
254 };
255 std::vector<Local<Value>> primordials_args = {
256 Boolean::New(isolate,
257 env->options()->debug_options().break_node_first_line),
258 env->primordials()
259 };
260 MaybeLocal<Value> primordials_ret =
261 ExecuteBootstrapper(env,
262 "internal/bootstrap/primordials",
263 &primordials_params,
264 &primordials_args);
265 if (primordials_ret.IsEmpty()) {
266 return MaybeLocal<Value>();
267 }
268
Joyee Cheung2a9eb312018-03-03 20:55:45269 // Create binding loaders
Joyee Cheungedcb9502018-11-26 17:50:41270 std::vector<Local<String>> loaders_params = {
271 env->process_string(),
Joyee Cheungedcb9502018-11-26 17:50:41272 FIXED_ONE_BYTE_STRING(isolate, "getLinkedBinding"),
273 FIXED_ONE_BYTE_STRING(isolate, "getInternalBinding"),
Joyee Cheungcd70cbc2019-01-12 17:01:27274 // --experimental-modules
275 FIXED_ONE_BYTE_STRING(isolate, "experimentalModules"),
276 // --expose-internals
Joyee Cheung39d92212019-01-30 14:21:07277 FIXED_ONE_BYTE_STRING(isolate, "exposeInternals"),
278 env->primordials_string()};
Joyee Cheungedcb9502018-11-26 17:50:41279 std::vector<Local<Value>> loaders_args = {
280 process,
Joyee Cheung3d668262018-11-28 16:46:45281 env->NewFunctionTemplate(binding::GetLinkedBinding)
Joyee Cheungedcb9502018-11-26 17:50:41282 ->GetFunction(context)
283 .ToLocalChecked(),
Joyee Cheung3d668262018-11-28 16:46:45284 env->NewFunctionTemplate(binding::GetInternalBinding)
Joyee Cheungedcb9502018-11-26 17:50:41285 ->GetFunction(context)
286 .ToLocalChecked(),
Joyee Cheung39d92212019-01-30 14:21:07287 Boolean::New(isolate, env->options()->experimental_modules),
288 Boolean::New(isolate, env->options()->expose_internals),
289 env->primordials()};
Joyee Cheung2a9eb312018-03-03 20:55:45290
Joyee Cheung2a9eb312018-03-03 20:55:45291 // Bootstrap internal loaders
Joyee Cheung6967f912019-01-15 15:12:21292 MaybeLocal<Value> loader_exports = ExecuteBootstrapper(
Joyee Cheungedcb9502018-11-26 17:50:41293 env, "internal/bootstrap/loaders", &loaders_params, &loaders_args);
294 if (loader_exports.IsEmpty()) {
Joyee Cheung6967f912019-01-15 15:12:21295 return MaybeLocal<Value>();
Joyee Cheung2a9eb312018-03-03 20:55:45296 }
297
Joyee Cheung6967f912019-01-15 15:12:21298 Local<Object> loader_exports_obj =
299 loader_exports.ToLocalChecked().As<Object>();
300 Local<Value> internal_binding_loader =
301 loader_exports_obj->Get(context, env->internal_binding_string())
302 .ToLocalChecked();
303 env->set_internal_binding_loader(internal_binding_loader.As<Function>());
304
305 Local<Value> require =
306 loader_exports_obj->Get(context, env->require_string()).ToLocalChecked();
307 env->set_native_module_require(require.As<Function>());
308
Anna Henningsen39eca842019-02-01 22:47:38309 // process, loaderExports, isMainThread, ownsProcessState, primordials
Joyee Cheungedcb9502018-11-26 17:50:41310 std::vector<Local<String>> node_params = {
311 env->process_string(),
Joyee Cheungedcb9502018-11-26 17:50:41312 FIXED_ONE_BYTE_STRING(isolate, "loaderExports"),
Joyee Cheung39d92212019-01-30 14:21:07313 FIXED_ONE_BYTE_STRING(isolate, "isMainThread"),
Anna Henningsen39eca842019-02-01 22:47:38314 FIXED_ONE_BYTE_STRING(isolate, "ownsProcessState"),
Joyee Cheung39d92212019-01-30 14:21:07315 env->primordials_string()};
Joyee Cheungedcb9502018-11-26 17:50:41316 std::vector<Local<Value>> node_args = {
317 process,
Joyee Cheung6967f912019-01-15 15:12:21318 loader_exports_obj,
Joyee Cheung39d92212019-01-30 14:21:07319 Boolean::New(isolate, env->is_main_thread()),
Anna Henningsen39eca842019-02-01 22:47:38320 Boolean::New(isolate, env->owns_process_state()),
Joyee Cheung39d92212019-01-30 14:21:07321 env->primordials()};
Joyee Cheungedcb9502018-11-26 17:50:41322
Joyee Cheung6967f912019-01-15 15:12:21323 MaybeLocal<Value> result = ExecuteBootstrapper(
324 env, "internal/bootstrap/node", &node_params, &node_args);
Anna Henningsenf6a1d882019-01-02 21:14:23325
Joyee Cheung6967f912019-01-15 15:12:21326 env->set_has_run_bootstrapping_code(true);
327
328 return scope.EscapeMaybe(result);
Anna Henningsenf6a1d882019-01-02 21:14:23329}
330
Joyee Cheung6967f912019-01-15 15:12:21331void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
332 Environment* env = Environment::GetCurrent(args);
333 env->performance_state()->Mark(
334 performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
335}
Anna Henningsenf6a1d882019-01-02 21:14:23336
Joyee Cheung6967f912019-01-15 15:12:21337MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
338 EscapableHandleScope scope(env->isolate());
339 CHECK_NE(main_script_id, nullptr);
Joyee Cheung2c7f4f42019-01-13 15:44:09340
Joyee Cheung6967f912019-01-15 15:12:21341 std::vector<Local<String>> parameters = {
342 env->process_string(),
343 env->require_string(),
344 env->internal_binding_string(),
345 FIXED_ONE_BYTE_STRING(env->isolate(), "markBootstrapComplete")};
346
347 std::vector<Local<Value>> arguments = {
348 env->process_object(),
349 env->native_module_require(),
350 env->internal_binding_loader(),
351 env->NewFunctionTemplate(MarkBootstrapComplete)
352 ->GetFunction(env->context())
353 .ToLocalChecked()};
354
355 MaybeLocal<Value> result =
356 ExecuteBootstrapper(env, main_script_id, &parameters, &arguments);
357 return scope.EscapeMaybe(result);
358}
359
360MaybeLocal<Value> StartMainThreadExecution(Environment* env) {
361 // To allow people to extend Node in different ways, this hook allows
362 // one to drop a file lib/_third_party_main.js into the build
363 // directory which will be executed instead of Node's normal loading.
364 if (per_process::native_module_loader.Exists("_third_party_main")) {
365 return StartExecution(env, "internal/main/run_third_party_main");
Joyee Cheung2c7f4f42019-01-13 15:44:09366 }
367
Joyee Cheung6967f912019-01-15 15:12:21368 if (env->execution_mode() == Environment::ExecutionMode::kInspect ||
369 env->execution_mode() == Environment::ExecutionMode::kDebug) {
370 return StartExecution(env, "internal/main/inspect");
371 }
372
373 if (per_process::cli_options->print_help) {
374 env->set_execution_mode(Environment::ExecutionMode::kPrintHelp);
375 return StartExecution(env, "internal/main/print_help");
376 }
377
378 if (per_process::cli_options->print_bash_completion) {
379 env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion);
380 return StartExecution(env, "internal/main/print_bash_completion");
381 }
382
383 if (env->options()->prof_process) {
384 env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion);
385 return StartExecution(env, "internal/main/prof_process");
386 }
387
388 // -e/--eval without -i/--interactive
389 if (env->options()->has_eval_string && !env->options()->force_repl) {
390 env->set_execution_mode(Environment::ExecutionMode::kEvalString);
391 return StartExecution(env, "internal/main/eval_string");
392 }
393
394 if (env->options()->syntax_check_only) {
395 env->set_execution_mode(Environment::ExecutionMode::kCheckSyntax);
396 return StartExecution(env, "internal/main/check_syntax");
397 }
398
399 if (env->execution_mode() == Environment::ExecutionMode::kRunMainModule) {
400 return StartExecution(env, "internal/main/run_main_module");
401 }
402
403 if (env->options()->force_repl || uv_guess_handle(STDIN_FILENO) == UV_TTY) {
404 env->set_execution_mode(Environment::ExecutionMode::kRepl);
405 return StartExecution(env, "internal/main/repl");
406 }
407
408 env->set_execution_mode(Environment::ExecutionMode::kEvalStdin);
409 return StartExecution(env, "internal/main/eval_stdin");
410}
411
412void LoadEnvironment(Environment* env) {
413 CHECK(env->is_main_thread());
414 // TODO(joyeecheung): Not all of the execution modes in
415 // StartMainThreadExecution() make sense for embedders. Pick the
416 // useful ones out, and allow embedders to customize the entry
417 // point more directly without using _third_party_main.js
418 if (!RunBootstrapping(env).IsEmpty()) {
419 USE(StartMainThreadExecution(env));
420 }
Ryan27b268b2009-06-17 13:05:44421}
422
Ryan Dahl2a7e7b12010-12-18 19:17:29423
Fedor Indutny82d0ac72011-09-24 13:51:59424#ifdef __POSIX__
Anna Henningsen0815b942016-05-08 01:28:47425void RegisterSignalHandler(int signal,
426 void (*handler)(int signal),
427 bool reset_handler) {
Tom Hughesf61b1102010-10-12 21:01:58428 struct sigaction sa;
Tom Hughesf61b1102010-10-12 21:01:58429 memset(&sa, 0, sizeof(sa));
430 sa.sa_handler = handler;
Fedor Indutnyb64983d2015-03-20 05:03:34431#ifndef __FreeBSD__
432 // FreeBSD has a nasty bug with SA_RESETHAND reseting the SA_SIGINFO, that is
433 // in turn set for a libthr wrapper. This leads to a crash.
434 // Work around the issue by manually setting SIG_DFL in the signal handler
Geir Haugec61b0e92014-03-31 07:52:03435 sa.sa_flags = reset_handler ? SA_RESETHAND : 0;
Fedor Indutnyb64983d2015-03-20 05:03:34436#endif
Tom Hughesf61b1102010-10-12 21:01:58437 sigfillset(&sa.sa_mask);
Ben Noordhuis2d82cdf2014-10-22 01:29:32438 CHECK_EQ(sigaction(signal, &sa, nullptr), 0);
Bert Belder829735e2011-11-04 15:23:02439}
440
Fedor Indutny8e29ce92013-07-31 18:07:29441#endif // __POSIX__
Tom Hughesf61b1102010-10-12 21:01:58442
Ben Noordhuis5756f922015-01-26 22:15:20443inline void PlatformInit() {
444#ifdef __POSIX__
Daniel Bevenius65a6e052017-04-07 06:48:32445#if HAVE_INSPECTOR
Ben Noordhuis63ae1d22015-01-26 22:26:33446 sigset_t sigmask;
447 sigemptyset(&sigmask);
448 sigaddset(&sigmask, SIGUSR1);
Ben Noordhuisb5f25a92015-02-18 02:43:29449 const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr);
Daniel Bevenius65a6e052017-04-07 06:48:32450#endif // HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:29451
452 // Make sure file descriptors 0-2 are valid before we start logging anything.
Evan Lucas14dc17d2018-06-11 14:20:50453 for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) {
454 struct stat ignored;
455 if (fstat(fd, &ignored) == 0)
Ben Noordhuisb5f25a92015-02-18 02:43:29456 continue;
457 // Anything but EBADF means something is seriously wrong. We don't
458 // have to special-case EINTR, fstat() is not interruptible.
459 if (errno != EBADF)
Evan Lucas870229e2015-09-16 15:12:41460 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:29461 if (fd != open("/dev/null", O_RDWR))
Evan Lucas870229e2015-09-16 15:12:41462 ABORT();
Ben Noordhuisb5f25a92015-02-18 02:43:29463 }
464
Daniel Bevenius65a6e052017-04-07 06:48:32465#if HAVE_INSPECTOR
Ben Noordhuisb5f25a92015-02-18 02:43:29466 CHECK_EQ(err, 0);
Daniel Bevenius65a6e052017-04-07 06:48:32467#endif // HAVE_INSPECTOR
Ben Noordhuisdd47a8c2015-01-26 23:07:34468
Stewart X Addison0f0f3d32016-12-30 12:44:46469#ifndef NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:34470 // Restore signal dispositions, the parent process may have changed them.
471 struct sigaction act;
472 memset(&act, 0, sizeof(act));
473
474 // The hard-coded upper limit is because NSIG is not very reliable; on Linux,
475 // it evaluates to 32, 34 or 64, depending on whether RT signals are enabled.
476 // Counting up to SIGRTMIN doesn't work for the same reason.
Eugene Ostroukhov66269192016-06-08 21:09:28477 for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
Ben Noordhuisdd47a8c2015-01-26 23:07:34478 if (nr == SIGKILL || nr == SIGSTOP)
479 continue;
480 act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
481 CHECK_EQ(0, sigaction(nr, &act, nullptr));
482 }
Stewart X Addison0f0f3d32016-12-30 12:44:46483#endif // !NODE_SHARED_MODE
Ben Noordhuisdd47a8c2015-01-26 23:07:34484
Ben Noordhuis63ae1d22015-01-26 22:26:33485 RegisterSignalHandler(SIGINT, SignalExit, true);
486 RegisterSignalHandler(SIGTERM, SignalExit, true);
Ben Noordhuisdd47a8c2015-01-26 23:07:34487
Ben Noordhuis5756f922015-01-26 22:15:20488 // Raise the open file descriptor limit.
489 struct rlimit lim;
490 if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) {
491 // Do a binary search for the limit.
492 rlim_t min = lim.rlim_cur;
493 rlim_t max = 1 << 20;
494 // But if there's a defined upper bound, don't search, just set it.
495 if (lim.rlim_max != RLIM_INFINITY) {
496 min = lim.rlim_max;
497 max = lim.rlim_max;
498 }
499 do {
500 lim.rlim_cur = min + (max - min) / 2;
501 if (setrlimit(RLIMIT_NOFILE, &lim)) {
502 max = lim.rlim_cur;
503 } else {
504 min = lim.rlim_cur;
505 }
506 } while (min + 1 < max);
507 }
Ben Noordhuis5756f922015-01-26 22:15:20508#endif // __POSIX__
Bartosz Sosnowskibd496e02017-03-14 17:22:53509#ifdef _WIN32
510 for (int fd = 0; fd <= 2; ++fd) {
511 auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
512 if (handle == INVALID_HANDLE_VALUE ||
513 GetFileType(handle) == FILE_TYPE_UNKNOWN) {
514 // Ignore _close result. If it fails or not depends on used Windows
515 // version. We will just check _open result.
516 _close(fd);
517 if (fd != _open("nul", _O_RDWR))
518 ABORT();
519 }
520 }
521#endif // _WIN32
Ben Noordhuis5756f922015-01-26 22:15:20522}
523
Anna Henningseneb664c32019-01-06 21:55:09524int ProcessGlobalArgs(std::vector<std::string>* args,
525 std::vector<std::string>* exec_args,
526 std::vector<std::string>* errors,
527 bool is_env) {
Sam Robertsf2282bb2017-02-20 14:18:43528 // Parse a few arguments which are specific to Node.
Anna Henningsen29a71ba2018-08-10 00:45:28529 std::vector<std::string> v8_args;
Anna Henningsene812be42018-08-23 14:41:05530
Anna Henningseneb664c32019-01-06 21:55:09531 Mutex::ScopedLock lock(per_process::cli_options_mutex);
532 options_parser::PerProcessOptionsParser::instance.Parse(
533 args,
534 exec_args,
535 &v8_args,
536 per_process::cli_options.get(),
537 is_env ? kAllowedInEnvironment : kDisallowedInEnvironment,
538 errors);
Anna Henningsene812be42018-08-23 14:41:05539
Anna Henningseneb664c32019-01-06 21:55:09540 if (!errors->empty()) return 9;
Anna Henningsen29a71ba2018-08-10 00:45:28541
Anna Henningsen38ab1e92019-01-12 19:55:58542 std::string revert_error;
543 for (const std::string& cve : per_process::cli_options->security_reverts) {
544 Revert(cve.c_str(), &revert_error);
545 if (!revert_error.empty()) {
546 errors->emplace_back(std::move(revert_error));
547 return 12;
548 }
549 }
Anna Henningsen29a71ba2018-08-10 00:45:28550
Joyee Cheung9db9e7e2019-01-01 05:56:53551 auto env_opts = per_process::cli_options->per_isolate->per_env;
Anna Henningsen29a71ba2018-08-10 00:45:28552 if (std::find(v8_args.begin(), v8_args.end(),
553 "--abort-on-uncaught-exception") != v8_args.end() ||
554 std::find(v8_args.begin(), v8_args.end(),
555 "--abort_on_uncaught_exception") != v8_args.end()) {
Daniel Bevenius6a9e7762018-09-06 08:39:38556 env_opts->abort_on_uncaught_exception = true;
Anna Henningsen29a71ba2018-08-10 00:45:28557 }
Sam Robertsf2282bb2017-02-20 14:18:43558
559 // TODO(bnoordhuis) Intercept --prof arguments and start the CPU profiler
560 // manually? That would give us a little more control over its runtime
561 // behavior but it could also interfere with the user's intentions in ways
562 // we fail to anticipate. Dillema.
Anna Henningsen29a71ba2018-08-10 00:45:28563 if (std::find(v8_args.begin(), v8_args.end(), "--prof") != v8_args.end()) {
Joyee Cheung9db9e7e2019-01-01 05:56:53564 per_process::v8_is_profiling = true;
Sam Robertsf2282bb2017-02-20 14:18:43565 }
566
567#ifdef __POSIX__
568 // Block SIGPROF signals when sleeping in epoll_wait/kevent/etc. Avoids the
569 // performance penalty of frequent EINTR wakeups when the profiler is running.
570 // Only do this for v8.log profiling, as it breaks v8::CpuProfiler users.
Joyee Cheung9db9e7e2019-01-01 05:56:53571 if (per_process::v8_is_profiling) {
Sam Robertsf2282bb2017-02-20 14:18:43572 uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF);
573 }
574#endif
575
Anna Henningsen29a71ba2018-08-10 00:45:28576 std::vector<char*> v8_args_as_char_ptr(v8_args.size());
577 if (v8_args.size() > 0) {
578 for (size_t i = 0; i < v8_args.size(); ++i)
579 v8_args_as_char_ptr[i] = &v8_args[i][0];
580 int argc = v8_args.size();
581 V8::SetFlagsFromCommandLine(&argc, &v8_args_as_char_ptr[0], true);
582 v8_args_as_char_ptr.resize(argc);
583 }
Sam Robertsf2282bb2017-02-20 14:18:43584
585 // Anything that's still in v8_argv is not a V8 or a node option.
Anna Henningseneb664c32019-01-06 21:55:09586 for (size_t i = 1; i < v8_args_as_char_ptr.size(); i++)
587 errors->push_back("bad option: " + std::string(v8_args_as_char_ptr[i]));
Sam Robertsf2282bb2017-02-20 14:18:43588
Anna Henningseneb664c32019-01-06 21:55:09589 if (v8_args_as_char_ptr.size() > 1) return 9;
590
591 return 0;
Sam Robertsf2282bb2017-02-20 14:18:43592}
593
Anna Henningseneb664c32019-01-06 21:55:09594int Init(std::vector<std::string>* argv,
595 std::vector<std::string>* exec_argv,
596 std::vector<std::string>* errors) {
Ben Noordhuis74a82152012-02-03 15:32:00597 // Initialize prog_start_time to get relative uptime.
Joyee Cheung9db9e7e2019-01-01 05:56:53598 per_process::prog_start_time = static_cast<double>(uv_now(uv_default_loop()));
Ben Noordhuis74a82152012-02-03 15:32:00599
Yihong Wang8680bb92017-10-22 06:16:50600 // Register built-in modules
Joyee Cheung3d668262018-11-28 16:46:45601 binding::RegisterBuiltinModules();
Yihong Wang8680bb92017-10-22 06:16:50602
Bert Belder09be3602012-06-13 23:28:51603 // Make inherited handles noninheritable.
604 uv_disable_stdio_inheritance();
605
Gireesh Punathil4f679732018-09-05 14:06:59606#ifdef NODE_REPORT
607 // Cache the original command line to be
608 // used in diagnostic reports.
609 per_process::cli_options->cmdline = *argv;
610#endif // NODE_REPORT
611
Ben Noordhuis490d5ab2014-03-31 12:22:49612#if defined(NODE_V8_OPTIONS)
613 // Should come before the call to V8::SetFlagsFromCommandLine()
614 // so the user can disable a flag --foo at run-time by passing
615 // --no_foo from the command line.
616 V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1);
617#endif
Fedor Indutnyb55c9d62014-03-26 20:30:49618
Anna Henningsen29a71ba2018-08-10 00:45:28619 std::shared_ptr<EnvironmentOptions> default_env_options =
Joyee Cheung9db9e7e2019-01-01 05:56:53620 per_process::cli_options->per_isolate->per_env;
James M Snella16b5702017-03-11 20:18:53621 {
622 std::string text;
Anna Henningsen29a71ba2018-08-10 00:45:28623 default_env_options->pending_deprecation =
Joyee Cheung321e2962018-12-15 19:13:12624 credentials::SafeGetenv("NODE_PENDING_DEPRECATION", &text) &&
625 text[0] == '1';
James M Snella16b5702017-03-11 20:18:53626 }
627
Marc Udoffd3b1a2b2016-09-20 22:21:44628 // Allow for environment set preserving symlinks.
Ben Noordhuisa8734af2017-01-28 12:27:02629 {
630 std::string text;
Anna Henningsen29a71ba2018-08-10 00:45:28631 default_env_options->preserve_symlinks =
Joyee Cheung321e2962018-12-15 19:13:12632 credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) &&
633 text[0] == '1';
Marc Udoffd3b1a2b2016-09-20 22:21:44634 }
635
David Goldstein23659652018-04-10 07:40:56636 {
637 std::string text;
Anna Henningsen29a71ba2018-08-10 00:45:28638 default_env_options->preserve_symlinks_main =
Joyee Cheung321e2962018-12-15 19:13:12639 credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) &&
640 text[0] == '1';
David Goldstein23659652018-04-10 07:40:56641 }
642
Anna Henningsen29a71ba2018-08-10 00:45:28643 if (default_env_options->redirect_warnings.empty()) {
Joyee Cheung321e2962018-12-15 19:13:12644 credentials::SafeGetenv("NODE_REDIRECT_WARNINGS",
645 &default_env_options->redirect_warnings);
Anna Henningsen29a71ba2018-08-10 00:45:28646 }
James M Snell03e89b32016-12-04 18:38:35647
Daniel Beveniuse1d88992017-02-28 19:04:12648#if HAVE_OPENSSL
Joyee Cheung9db9e7e2019-01-01 05:56:53649 std::string* openssl_config = &per_process::cli_options->openssl_config;
Anna Henningsen29a71ba2018-08-10 00:45:28650 if (openssl_config->empty()) {
Joyee Cheung321e2962018-12-15 19:13:12651 credentials::SafeGetenv("OPENSSL_CONF", openssl_config);
Anna Henningsen29a71ba2018-08-10 00:45:28652 }
Daniel Beveniuse1d88992017-02-28 19:04:12653#endif
Sam Roberts59afa272017-01-25 22:13:34654
Sam Robertsf2282bb2017-02-20 14:18:43655#if !defined(NODE_WITHOUT_NODE_OPTIONS)
656 std::string node_options;
Joyee Cheung321e2962018-12-15 19:13:12657 if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
Anna Henningsen8ec3c352019-01-06 01:48:05658 // [0] is expected to be the program name, fill it in from the real argv
659 // and use 'x' as a placeholder while parsing.
660 std::vector<std::string> env_argv = SplitString("x " + node_options, ' ');
661 env_argv[0] = argv->at(0);
Anna Henningsen29a71ba2018-08-10 00:45:28662
Anna Henningseneb664c32019-01-06 21:55:09663 const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true);
664 if (exit_code != 0) return exit_code;
Oleksandr Chekhovskyi8e141352015-08-07 13:03:04665 }
666#endif
667
Anna Henningseneb664c32019-01-06 21:55:09668 const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, false);
669 if (exit_code != 0) return exit_code;
Sam Robertsf2282bb2017-02-20 14:18:43670
James M Snell9d716192018-06-22 23:16:03671 // Set the process.title immediately after processing argv if --title is set.
Joyee Cheung9db9e7e2019-01-01 05:56:53672 if (!per_process::cli_options->title.empty())
673 uv_set_process_title(per_process::cli_options->title.c_str());
James M Snell9d716192018-06-22 23:16:03674
Steven R. Loomisac2857b2014-09-05 05:03:24675#if defined(NODE_HAVE_I18N_SUPPORT)
Ben Noordhuisa8734af2017-01-28 12:27:02676 // If the parameter isn't given, use the env variable.
Joyee Cheung9db9e7e2019-01-01 05:56:53677 if (per_process::cli_options->icu_data_dir.empty())
678 credentials::SafeGetenv("NODE_ICU_DATA",
679 &per_process::cli_options->icu_data_dir);
Steven R. Loomisac2857b2014-09-05 05:03:24680 // Initialize ICU.
Ben Noordhuisa8734af2017-01-28 12:27:02681 // If icu_data_dir is empty here, it will load the 'minimal' data.
Joyee Cheung9db9e7e2019-01-01 05:56:53682 if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {
Anna Henningseneb664c32019-01-06 21:55:09683 errors->push_back("could not initialize ICU "
684 "(check NODE_ICU_DATA or --icu-data-dir parameters)\n");
685 return 9;
Steven R. Loomisac2857b2014-09-05 05:03:24686 }
Joyee Cheung263d1372018-12-18 21:23:47687 per_process::metadata.versions.InitializeIntlVersions();
Steven R. Loomisac2857b2014-09-05 05:03:24688#endif
Tom Hughes78da9cb2010-10-18 22:50:56689
Cheng Zhao22e1aea2015-01-12 21:31:25690 // We should set node_is_initialized here instead of in node::Start,
691 // otherwise embedders using node::Init to initialize everything will not be
692 // able to set it and native modules will not load for them.
693 node_is_initialized = true;
Anna Henningseneb664c32019-01-06 21:55:09694 return 0;
Ben Noordhuis5866f1a2011-12-09 18:02:33695}
Ben Noordhuis356992f2011-11-22 16:10:09696
Anna Henningsen29a71ba2018-08-10 00:45:28697// TODO(addaleax): Deprecate and eventually remove this.
698void Init(int* argc,
699 const char** argv,
700 int* exec_argc,
701 const char*** exec_argv) {
702 std::vector<std::string> argv_(argv, argv + *argc); // NOLINT
703 std::vector<std::string> exec_argv_;
Anna Henningseneb664c32019-01-06 21:55:09704 std::vector<std::string> errors;
Anna Henningsen29a71ba2018-08-10 00:45:28705
Anna Henningseneb664c32019-01-06 21:55:09706 // This (approximately) duplicates some logic that has been moved to
707 // node::Start(), with the difference that here we explicitly call `exit()`.
708 int exit_code = Init(&argv_, &exec_argv_, &errors);
709
710 for (const std::string& error : errors)
711 fprintf(stderr, "%s: %s\n", argv_.at(0).c_str(), error.c_str());
712 if (exit_code != 0) exit(exit_code);
713
714 if (per_process::cli_options->print_version) {
715 printf("%s\n", NODE_VERSION);
716 exit(0);
717 }
718
719 if (per_process::cli_options->print_v8_help) {
720 V8::SetFlagsFromString("--help", 6); // Doesn't return.
721 UNREACHABLE();
722 }
Anna Henningsen29a71ba2018-08-10 00:45:28723
724 *argc = argv_.size();
725 *exec_argc = exec_argv_.size();
726 // These leak memory, because, in the original code of this function, no
727 // extra allocations were visible. This should be okay because this function
728 // is only supposed to be called once per process, though.
729 *exec_argv = Malloc<const char*>(*exec_argc);
730 for (int i = 0; i < *exec_argc; ++i)
731 (*exec_argv)[i] = strdup(exec_argv_[i].c_str());
732 for (int i = 0; i < *argc; ++i)
733 argv[i] = strdup(argv_[i].c_str());
734}
Ben Noordhuis5866f1a2011-12-09 18:02:33735
Anatoli Papirovski8803b692018-01-18 21:52:51736void RunBeforeExit(Environment* env) {
737 env->RunBeforeExitCallbacks();
738
739 if (!uv_loop_alive(env->event_loop()))
740 EmitBeforeExit(env);
741}
742
Ben Noordhuisceb60232016-10-21 12:24:48743inline int Start(Isolate* isolate, IsolateData* isolate_data,
Anna Henningsen29a71ba2018-08-10 00:45:28744 const std::vector<std::string>& args,
745 const std::vector<std::string>& exec_args) {
Ben Noordhuisceb60232016-10-21 12:24:48746 HandleScope handle_scope(isolate);
Ben Noordhuis668ad442017-09-07 11:26:47747 Local<Context> context = NewContext(isolate);
Ben Noordhuisceb60232016-10-21 12:24:48748 Context::Scope context_scope(context);
Anna Henningsen39eca842019-02-01 22:47:38749 Environment env(
750 isolate_data,
751 context,
752 static_cast<Environment::Flags>(Environment::kIsMainThread |
753 Environment::kOwnsProcessState |
754 Environment::kOwnsInspector));
Anna Henningsen95571ac2019-01-27 13:21:21755 env.Start(per_process::v8_is_profiling);
Joyee Cheung6967f912019-01-15 15:12:21756 env.ProcessCliArgs(args, exec_args);
Ben Noordhuisceb60232016-10-21 12:24:48757
Joyee Cheunge3e40482019-01-21 14:57:51758#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
759 CHECK(!env.inspector_agent()->IsListening());
760 // Inspector agent can't fail to start, but if it was configured to listen
761 // right away on the websocket port and fails to bind/etc, this will return
762 // false.
763 env.inspector_agent()->Start(args.size() > 1 ? args[1].c_str() : "",
764 env.options()->debug_options(),
765 env.inspector_host_port(),
766 true);
Joyee Cheung61a89632018-12-01 17:30:30767 if (env.options()->debug_options().inspector_enabled &&
Joyee Cheunge3e40482019-01-21 14:57:51768 !env.inspector_agent()->IsListening()) {
Eugene Ostroukhov7599b0e2016-12-13 01:08:31769 return 12; // Signal internal error.
Anna Henningsen29a71ba2018-08-10 00:45:28770 }
Joyee Cheunge3e40482019-01-21 14:57:51771#else
772 // inspector_enabled can't be true if !HAVE_INSPECTOR or !NODE_USE_V8_PLATFORM
773 // - the option parser should not allow that.
774 CHECK(!env.options()->debug_options().inspector_enabled);
775#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
Ben Noordhuisceb60232016-10-21 12:24:48776
777 {
778 Environment::AsyncCallbackScope callback_scope(&env);
Andreas Madsen3a69ef52017-09-26 13:50:10779 env.async_hooks()->push_async_ids(1, 0);
Ben Noordhuisceb60232016-10-21 12:24:48780 LoadEnvironment(&env);
Andreas Madsen3a69ef52017-09-26 13:50:10781 env.async_hooks()->pop_async_id(1);
Ben Noordhuisceb60232016-10-21 12:24:48782 }
783
Ben Noordhuisceb60232016-10-21 12:24:48784 {
785 SealHandleScope seal(isolate);
786 bool more;
James M Snell96cb4fb2018-03-06 18:42:37787 env.performance_state()->Mark(
788 node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
Ben Noordhuisceb60232016-10-21 12:24:48789 do {
Matt Loring9e086952017-03-13 22:17:57790 uv_run(env.event_loop(), UV_RUN_DEFAULT);
Ben Noordhuisceb60232016-10-21 12:24:48791
Joyee Cheung99c32432019-01-16 18:34:43792 per_process::v8_platform.DrainVMTasks(isolate);
Anna Henningsenf27b5e42017-09-15 13:03:48793
794 more = uv_loop_alive(env.event_loop());
795 if (more)
796 continue;
797
Anatoli Papirovski8803b692018-01-18 21:52:51798 RunBeforeExit(&env);
Ben Noordhuisceb60232016-10-21 12:24:48799
Matt Loring9e086952017-03-13 22:17:57800 // Emit `beforeExit` if the loop became alive either after emitting
801 // event, or after running some callbacks.
802 more = uv_loop_alive(env.event_loop());
Ben Noordhuisceb60232016-10-21 12:24:48803 } while (more == true);
James M Snell96cb4fb2018-03-06 18:42:37804 env.performance_state()->Mark(
805 node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
Ben Noordhuisceb60232016-10-21 12:24:48806 }
807
808 env.set_trace_sync_io(false);
809
810 const int exit_code = EmitExit(&env);
Anna Henningsen5c6cf302017-09-09 20:28:02811
Anna Henningsen61fd0272017-09-09 20:29:08812 WaitForInspectorDisconnect(&env);
813
Anna Henningsenbcb324c2017-09-20 12:43:19814 env.set_can_call_into_js(false);
Anna Henningsen0df031a2017-09-01 15:03:41815 env.stop_sub_worker_contexts();
Anna Henningsen43fd1d72018-05-30 09:18:43816 uv_tty_reset_mode();
Anna Henningsen5c6cf302017-09-09 20:28:02817 env.RunCleanup();
Ben Noordhuisceb60232016-10-21 12:24:48818 RunAtExit(&env);
819
Joyee Cheung99c32432019-01-16 18:34:43820 per_process::v8_platform.DrainVMTasks(isolate);
821 per_process::v8_platform.CancelVMTasks(isolate);
Ben Noordhuisceb60232016-10-21 12:24:48822#if defined(LEAK_SANITIZER)
823 __lsan_do_leak_check();
824#endif
825
826 return exit_code;
827}
828
helloshuangzi963cb3a2018-05-11 18:06:05829inline int Start(uv_loop_t* event_loop,
Anna Henningsen29a71ba2018-08-10 00:45:28830 const std::vector<std::string>& args,
831 const std::vector<std::string>& exec_args) {
helloshuangzi963cb3a2018-05-11 18:06:05832 std::unique_ptr<ArrayBufferAllocator, decltype(&FreeArrayBufferAllocator)>
833 allocator(CreateArrayBufferAllocator(), &FreeArrayBufferAllocator);
Andreas Haasd5e72942018-06-03 15:35:25834 Isolate* const isolate = NewIsolate(allocator.get(), event_loop);
helloshuangzi963cb3a2018-05-11 18:06:05835 if (isolate == nullptr)
836 return 12; // Signal internal error.
837
Anna Henningseneb664c32019-01-06 21:55:09838 if (per_process::cli_options->print_version) {
839 printf("%s\n", NODE_VERSION);
840 return 0;
841 }
842
843 if (per_process::cli_options->print_v8_help) {
844 V8::SetFlagsFromString("--help", 6); // Doesn't return.
845 UNREACHABLE();
846 }
847
Ben Noordhuisd77e8182016-10-21 11:47:49848 int exit_code;
Petka Antonov4ae64b22015-03-03 20:25:47849 {
850 Locker locker(isolate);
851 Isolate::Scope isolate_scope(isolate);
852 HandleScope handle_scope(isolate);
helloshuangzi963cb3a2018-05-11 18:06:05853 std::unique_ptr<IsolateData, decltype(&FreeIsolateData)> isolate_data(
Joyee Cheung99c32432019-01-16 18:34:43854 CreateIsolateData(isolate,
855 event_loop,
856 per_process::v8_platform.Platform(),
857 allocator.get()),
helloshuangzi963cb3a2018-05-11 18:06:05858 &FreeIsolateData);
Anna Henningsen29a71ba2018-08-10 00:45:28859 // TODO(addaleax): This should load a real per-Isolate option, currently
860 // this is still effectively per-process.
861 if (isolate_data->options()->track_heap_objects) {
Hannes Payer91d13122017-11-22 13:43:42862 isolate->GetHeapProfiler()->StartTrackingHeapObjects(true);
863 }
helloshuangzi963cb3a2018-05-11 18:06:05864 exit_code =
Anna Henningsen29a71ba2018-08-10 00:45:28865 Start(isolate, isolate_data.get(), args, exec_args);
Petka Antonov4ae64b22015-03-03 20:25:47866 }
867
Petka Antonov4ae64b22015-03-03 20:25:47868 isolate->Dispose();
Joyee Cheung99c32432019-01-16 18:34:43869 per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
Ben Noordhuisd77e8182016-10-21 11:47:49870
871 return exit_code;
Petka Antonov4ae64b22015-03-03 20:25:47872}
873
Ben Noordhuis185c5152013-09-02 14:42:01874int Start(int argc, char** argv) {
Evan Lucas14dc17d2018-06-11 14:20:50875 atexit([] () { uv_tty_reset_mode(); });
Ben Noordhuis5756f922015-01-26 22:15:20876 PlatformInit();
Daniel Beveniuscae41822018-02-23 14:42:20877 performance::performance_node_start = PERFORMANCE_NOW();
Ben Noordhuis5756f922015-01-26 22:15:20878
Ben Noordhuis5fdff382014-10-11 14:52:07879 CHECK_GT(argc, 0);
Micheil Smith19fd5302012-03-05 17:53:15880
Suresh Srinivasbf7ed802018-03-23 19:16:48881#ifdef NODE_ENABLE_LARGE_CODE_PAGES
882 if (node::IsLargePagesEnabled()) {
883 if (node::MapStaticCodeToLargePages() != 0) {
884 fprintf(stderr, "Reverting to default page size\n");
885 }
886 }
887#endif
888
Ben Noordhuis185c5152013-09-02 14:42:01889 // Hack around with the argv pointer. Used for process.title = "blah".
Ben Noordhuis1a979982012-03-15 22:10:32890 argv = uv_setup_args(argc, argv);
891
Anna Henningsen29a71ba2018-08-10 00:45:28892 std::vector<std::string> args(argv, argv + argc);
893 std::vector<std::string> exec_args;
Anna Henningseneb664c32019-01-06 21:55:09894 std::vector<std::string> errors;
Anna Henningsen29a71ba2018-08-10 00:45:28895 // This needs to run *before* V8::Initialize().
Anna Henningseneb664c32019-01-06 21:55:09896 {
897 const int exit_code = Init(&args, &exec_args, &errors);
898 for (const std::string& error : errors)
899 fprintf(stderr, "%s: %s\n", args.at(0).c_str(), error.c_str());
900 if (exit_code != 0) return exit_code;
901 }
Ben Noordhuis5866f1a2011-12-09 18:02:33902
Ben Noordhuis7ac23912013-09-20 20:01:49903#if HAVE_OPENSSL
Ben Noordhuisa8734af2017-01-28 12:27:02904 {
905 std::string extra_ca_certs;
Joyee Cheung321e2962018-12-15 19:13:12906 if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
Ben Noordhuisa8734af2017-01-28 12:27:02907 crypto::UseExtraCaCerts(extra_ca_certs);
908 }
Stefan Budeanu7c48cb52016-01-22 23:10:09909#ifdef NODE_FIPS_MODE
910 // In the case of FIPS builds we should make sure
911 // the random source is properly initialized first.
912 OPENSSL_init();
913#endif // NODE_FIPS_MODE
Ben Noordhuis7ac23912013-09-20 20:01:49914 // V8 on Windows doesn't have a good source of entropy. Seed it from
915 // OpenSSL's pool.
916 V8::SetEntropySource(crypto::EntropySource);
Ben Noordhuisa8734af2017-01-28 12:27:02917#endif // HAVE_OPENSSL
Ben Noordhuis7ac23912013-09-20 20:01:49918
Joyee Cheung9db9e7e2019-01-01 05:56:53919 InitializeV8Platform(per_process::cli_options->v8_thread_pool_size);
Ben Noordhuis75ea5662013-09-23 12:27:26920 V8::Initialize();
Daniel Beveniuscae41822018-02-23 14:42:20921 performance::performance_v8_start = PERFORMANCE_NOW();
Joyee Cheung9db9e7e2019-01-01 05:56:53922 per_process::v8_initialized = true;
Ben Noordhuisd77e8182016-10-21 11:47:49923 const int exit_code =
Anna Henningsen29a71ba2018-08-10 00:45:28924 Start(uv_default_loop(), args, exec_args);
Joyee Cheung9db9e7e2019-01-01 05:56:53925 per_process::v8_initialized = false;
Ryan27b268b2009-06-17 13:05:44926 V8::Dispose();
Igor Zinkovskya58b6432011-07-07 20:54:30927
Matt Loring9e086952017-03-13 22:17:57928 // uv_run cannot be called from the time before the beforeExit callback
929 // runs until the program exits unless the event loop has any referenced
930 // handles after beforeExit terminates. This prevents unrefed timers
931 // that happen to terminate during shutdown from being run unsafely.
932 // Since uv_run cannot be called, uv_async handles held by the platform
933 // will never be fully cleaned up.
Joyee Cheung99c32432019-01-16 18:34:43934 per_process::v8_platform.Dispose();
Ben Noordhuis4a801c22015-04-02 21:51:01935
Petka Antonov4ae64b22015-03-03 20:25:47936 return exit_code;
Ryan19478ed2009-03-03 00:56:15937}
Ryan Dahl124fbed2010-09-19 20:13:57938
Ryan Dahl124fbed2010-09-19 20:13:57939} // namespace node
Eugene Ostroukhov3f48ab32017-04-25 21:55:55940
941#if !HAVE_INSPECTOR
Daniel Beveniusebbf3932018-03-23 08:38:16942void Initialize() {}
Eugene Ostroukhov3f48ab32017-04-25 21:55:55943
Beni von Cheni05002372018-12-10 03:12:39944NODE_MODULE_CONTEXT_AWARE_INTERNAL(inspector, Initialize)
Eugene Ostroukhov3f48ab32017-04-25 21:55:55945#endif // !HAVE_INSPECTOR