James M Snell | 98e54b0 | 2017-01-03 21:16:48 | [diff] [blame] | 1 | // 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 Cheung | 3d66826 | 2018-11-28 16:46:45 | [diff] [blame] | 22 | #include "node_binding.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 23 | #include "node_buffer.h" |
| 24 | #include "node_constants.h" |
Joyee Cheung | 5850220 | 2018-11-03 14:45:40 | [diff] [blame] | 25 | #include "node_context_data.h" |
| 26 | #include "node_errors.h" |
| 27 | #include "node_internals.h" |
Joyee Cheung | d17d7bd | 2018-12-01 20:16:09 | [diff] [blame] | 28 | #include "node_metadata.h" |
Joyee Cheung | bd765d6 | 2018-11-03 06:26:32 | [diff] [blame] | 29 | #include "node_native_module.h" |
Joyee Cheung | 61a8963 | 2018-12-01 17:30:30 | [diff] [blame] | 30 | #include "node_options-inl.h" |
Joyee Cheung | bd765d6 | 2018-11-03 06:26:32 | [diff] [blame] | 31 | #include "node_perf.h" |
Matt Loring | 9e08695 | 2017-03-13 22:17:57 | [diff] [blame] | 32 | #include "node_platform.h" |
Joyee Cheung | 7824280 | 2018-12-31 15:18:08 | [diff] [blame] | 33 | #include "node_process.h" |
James M Snell | d387591 | 2016-02-04 01:16:10 | [diff] [blame] | 34 | #include "node_revert.h" |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 35 | #include "node_v8_platform-inl.h" |
Joyee Cheung | 5850220 | 2018-11-03 14:45:40 | [diff] [blame] | 36 | #include "node_version.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 37 | |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 38 | #if HAVE_OPENSSL |
| 39 | #include "node_crypto.h" |
| 40 | #endif |
| 41 | |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 42 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 43 | #include "node_i18n.h" |
| 44 | #endif |
| 45 | |
Ben Noordhuis | 399cb25 | 2017-05-27 11:31:00 | [diff] [blame] | 46 | #if HAVE_INSPECTOR |
| 47 | #include "inspector_io.h" |
| 48 | #endif |
| 49 | |
Ben Noordhuis | c4def50 | 2013-10-28 19:18:59 | [diff] [blame] | 50 | #if defined HAVE_DTRACE || defined HAVE_ETW |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 51 | #include "node_dtrace.h" |
| 52 | #endif |
| 53 | |
Daniel Bevenius | 7844766 | 2017-11-14 12:34:52 | [diff] [blame] | 54 | #include "async_wrap-inl.h" |
Ben Noordhuis | 756b622 | 2013-08-10 22:26:11 | [diff] [blame] | 55 | #include "env-inl.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 56 | #include "handle_wrap.h" |
Daniel Bevenius | b58a1cd | 2017-11-14 12:34:52 | [diff] [blame] | 57 | #include "req_wrap-inl.h" |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 58 | #include "string_bytes.h" |
Timothy J Fontaine | 1a09da6 | 2014-06-10 23:36:04 | [diff] [blame] | 59 | #include "util.h" |
Ben Noordhuis | ff4a9d3 | 2012-03-09 23:11:11 | [diff] [blame] | 60 | #include "uv.h" |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 61 | #if NODE_USE_V8_PLATFORM |
Ben Noordhuis | 4a801c2 | 2015-04-02 21:51:01 | [diff] [blame] | 62 | #include "libplatform/libplatform.h" |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 63 | #endif // NODE_USE_V8_PLATFORM |
Ben Noordhuis | 57231d5 | 2013-10-02 04:37:44 | [diff] [blame] | 64 | #include "v8-profiler.h" |
Ryan Dahl | 4635ed7 | 2010-03-11 20:40:19 | [diff] [blame] | 65 | |
Chunyang Dai | a881b53 | 2015-10-21 16:24:12 | [diff] [blame] | 66 | #ifdef NODE_ENABLE_VTUNE_PROFILING |
| 67 | #include "../deps/v8/src/third_party/vtune/v8-vtune.h" |
| 68 | #endif |
| 69 | |
Suresh Srinivas | bf7ed80 | 2018-03-23 19:16:48 | [diff] [blame] | 70 | #ifdef NODE_ENABLE_LARGE_CODE_PAGES |
| 71 | #include "large_pages/node_large_page.h" |
| 72 | #endif |
| 73 | |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 74 | #include <errno.h> |
Myles Borins | 9cc39ff | 2017-04-24 16:47:26 | [diff] [blame] | 75 | #include <fcntl.h> // _O_RDWR |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 76 | #include <limits.h> // PATH_MAX |
Bert Belder | 9cec08e | 2011-05-23 23:42:22 | [diff] [blame] | 77 | #include <signal.h> |
Ryan | 19478ed | 2009-03-03 00:56:15 | [diff] [blame] | 78 | #include <stdio.h> |
Ryan | 34a6f10 | 2009-05-28 12:47:16 | [diff] [blame] | 79 | #include <stdlib.h> |
Ryan Dahl | c90e44e | 2010-05-10 23:38:47 | [diff] [blame] | 80 | #include <string.h> |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 81 | #include <sys/types.h> |
Ben Noordhuis | c5c28c3 | 2015-10-10 13:01:49 | [diff] [blame] | 82 | |
| 83 | #include <string> |
Brian White | 2d35607 | 2015-10-13 21:18:15 | [diff] [blame] | 84 | #include <vector> |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 85 | |
Evan Lucas | 30b8bb0 | 2015-09-27 15:59:02 | [diff] [blame] | 86 | #if defined(NODE_HAVE_I18N_SUPPORT) |
| 87 | #include <unicode/uvernum.h> |
| 88 | #endif |
| 89 | |
Gireesh Punathil | 4f67973 | 2018-09-05 14:06:59 | [diff] [blame] | 90 | #ifdef NODE_REPORT |
| 91 | #include "node_report.h" |
| 92 | #endif |
| 93 | |
Karl Skomski | 6ed0603 | 2015-08-14 08:07:18 | [diff] [blame] | 94 | #if defined(LEAK_SANITIZER) |
| 95 | #include <sanitizer/lsan_interface.h> |
| 96 | #endif |
| 97 | |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 98 | #if defined(_MSC_VER) |
Peter Bright | 13d6a1f | 2011-08-06 04:23:25 | [diff] [blame] | 99 | #include <direct.h> |
Peter Bright | b9d7777 | 2011-08-11 01:45:56 | [diff] [blame] | 100 | #include <io.h> |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 101 | #define STDIN_FILENO 0 |
Ben Noordhuis | 02cab97 | 2013-07-31 21:16:08 | [diff] [blame] | 102 | #else |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 103 | #include <pthread.h> |
Ben Noordhuis | 6820054 | 2013-10-02 10:17:57 | [diff] [blame] | 104 | #include <sys/resource.h> // getrlimit, setrlimit |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 105 | #include <unistd.h> // STDIN_FILENO, STDERR_FILENO |
Bert Belder | a177d60 | 2010-11-25 00:02:55 | [diff] [blame] | 106 | #endif |
| 107 | |
Ryan | d6c9d31 | 2009-09-11 14:02:29 | [diff] [blame] | 108 | namespace node { |
| 109 | |
Anna Henningsen | e812be4 | 2018-08-23 14:41:05 | [diff] [blame] | 110 | using options_parser::kAllowedInEnvironment; |
| 111 | using options_parser::kDisallowedInEnvironment; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 112 | using v8::Array; |
| 113 | using v8::Boolean; |
| 114 | using v8::Context; |
Gireesh Punathil | 31ca5dc | 2018-09-01 06:49:02 | [diff] [blame] | 115 | using v8::DEFAULT; |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 116 | using v8::EscapableHandleScope; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 117 | using v8::Exception; |
| 118 | using v8::Function; |
| 119 | using v8::FunctionCallbackInfo; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 120 | using v8::HandleScope; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 121 | using v8::Isolate; |
Anna Henningsen | f3cd537 | 2017-12-01 23:04:56 | [diff] [blame] | 122 | using v8::Just; |
Ben Noordhuis | 511af4d | 2013-07-30 19:28:43 | [diff] [blame] | 123 | using v8::Local; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 124 | using v8::Locker; |
Anna Henningsen | f3cd537 | 2017-12-01 23:04:56 | [diff] [blame] | 125 | using v8::Maybe; |
Michaël Zasso | 023c317 | 2016-02-08 21:34:05 | [diff] [blame] | 126 | using v8::MaybeLocal; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 127 | using v8::Object; |
Gireesh Punathil | 31ca5dc | 2018-09-01 06:49:02 | [diff] [blame] | 128 | using v8::Script; |
Fedor Indutny | a07c691 | 2015-04-11 14:02:33 | [diff] [blame] | 129 | using v8::SealHandleScope; |
Ben Noordhuis | 511af4d | 2013-07-30 19:28:43 | [diff] [blame] | 130 | using v8::String; |
Anna Henningsen | 64616bb | 2017-08-08 18:02:55 | [diff] [blame] | 131 | using v8::Undefined; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 132 | using v8::V8; |
| 133 | using v8::Value; |
Ben Noordhuis | 110a9cd | 2013-07-03 02:23:44 | [diff] [blame] | 134 | |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 135 | namespace per_process { |
James M Snell | 35f6e59 | 2017-08-16 16:34:37 | [diff] [blame] | 136 | |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 137 | // node_revert.h |
| 138 | // Bit flag used to track security reverts. |
| 139 | unsigned 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 Henningsen | 72c60e8 | 2016-09-10 16:21:20 | [diff] [blame] | 144 | bool v8_initialized = false; |
| 145 | |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 146 | // node_internals.h |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 147 | // process-relative uptime base, initialized at start-up |
James M Snell | baadc7a | 2018-06-03 00:27:03 | [diff] [blame] | 148 | double prog_start_time; |
Joyee Cheung | ca9e24e | 2019-01-16 19:00:55 | [diff] [blame] | 149 | // Tells whether --prof is passed. |
| 150 | bool v8_is_profiling = false; |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 151 | |
| 152 | // node_v8_platform-inl.h |
| 153 | struct V8Platform v8_platform; |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 154 | } // namespace per_process |
Stefan Budeanu | 410296c | 2016-03-27 00:17:55 | [diff] [blame] | 155 | |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 156 | #ifdef __POSIX__ |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 157 | static const unsigned kMaxSignal = 32; |
Ben Noordhuis | 844f0a9 | 2016-03-25 16:59:07 | [diff] [blame] | 158 | #endif |
| 159 | |
Joyee Cheung | eb68619 | 2019-02-01 00:00:23 | [diff] [blame] | 160 | void WaitForInspectorDisconnect(Environment* env) { |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 161 | #if HAVE_INSPECTOR |
Eugene Ostroukhov | 39977db | 2018-05-21 23:59:04 | [diff] [blame] | 162 | if (env->inspector_agent()->IsActive()) { |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 163 | // Restore signal dispositions, the app is done and is no longer |
| 164 | // capable of handling signals. |
Stewart X Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 165 | #if defined(__POSIX__) && !defined(NODE_SHARED_MODE) |
Eugene Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 166 | 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 Henningsen | 0815b94 | 2016-05-08 01:28:47 | [diff] [blame] | 180 | void SignalExit(int signo) { |
Evan Lucas | 14dc17d | 2018-06-11 14:20:50 | [diff] [blame] | 181 | uv_tty_reset_mode(); |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 182 | #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 Hauge | c61b0e9 | 2014-03-31 07:52:03 | [diff] [blame] | 189 | raise(signo); |
Dean McNamee | f67e8f2 | 2011-03-15 22:39:16 | [diff] [blame] | 190 | } |
| 191 | |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 192 | static MaybeLocal<Value> ExecuteBootstrapper( |
Anna Henningsen | 0df031a | 2017-09-01 15:03:41 | [diff] [blame] | 193 | Environment* env, |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 194 | const char* id, |
| 195 | std::vector<Local<String>>* parameters, |
| 196 | std::vector<Local<Value>>* arguments) { |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 197 | 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 Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 211 | |
| 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 Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 219 | if (result.IsEmpty()) { |
Joyee Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 220 | env->async_hooks()->clear_async_id_stack(); |
| 221 | } |
| 222 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 223 | return scope.EscapeMaybe(result); |
Joyee Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 224 | } |
| 225 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 226 | MaybeLocal<Value> RunBootstrapping(Environment* env) { |
Anna Henningsen | f6a1d88 | 2019-01-02 21:14:23 | [diff] [blame] | 227 | CHECK(!env->has_run_bootstrapping_code()); |
Anna Henningsen | f6a1d88 | 2019-01-02 21:14:23 | [diff] [blame] | 228 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 229 | EscapableHandleScope scope(env->isolate()); |
Joyee Cheung | 7778c03 | 2018-11-14 14:38:12 | [diff] [blame] | 230 | Isolate* isolate = env->isolate(); |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 231 | Local<Context> context = env->context(); |
Anna Henningsen | 0df031a | 2017-09-01 15:03:41 | [diff] [blame] | 232 | |
Ryan Dahl | f8ce848 | 2010-09-17 07:01:07 | [diff] [blame] | 233 | // Add a reference to the global object |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 234 | Local<Object> global = context->Global(); |
Zoran Tomicic | d98ea70 | 2010-02-22 05:15:44 | [diff] [blame] | 235 | |
Ben Noordhuis | c4def50 | 2013-10-28 19:18:59 | [diff] [blame] | 236 | #if defined HAVE_DTRACE || defined HAVE_ETW |
Fedor Indutny | 75adde0 | 2014-02-21 13:02:42 | [diff] [blame] | 237 | InitDTrace(env, global); |
Ryan Dahl | e9257b8 | 2011-02-10 02:50:26 | [diff] [blame] | 238 | #endif |
Ryan Dahl | 068b733 | 2011-01-25 01:50:10 | [diff] [blame] | 239 | |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 240 | Local<Object> process = env->process_object(); |
Ryan Dahl | 9f5643f | 2010-01-31 07:22:34 | [diff] [blame] | 241 | |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 242 | // Setting global properties for the bootstrappers to use: |
| 243 | // - global |
Jeremiah Senkpiel | 21d66d6 | 2016-03-23 22:09:10 | [diff] [blame] | 244 | // Expose the global object as a property on itself |
| 245 | // (Allows you to set stuff on `global` from anywhere in JavaScript.) |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 246 | global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global) |
| 247 | .FromJust(); |
Jeremiah Senkpiel | 21d66d6 | 2016-03-23 22:09:10 | [diff] [blame] | 248 | |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 249 | // 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 Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 269 | // Create binding loaders |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 270 | std::vector<Local<String>> loaders_params = { |
| 271 | env->process_string(), |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 272 | FIXED_ONE_BYTE_STRING(isolate, "getLinkedBinding"), |
| 273 | FIXED_ONE_BYTE_STRING(isolate, "getInternalBinding"), |
Joyee Cheung | cd70cbc | 2019-01-12 17:01:27 | [diff] [blame] | 274 | // --experimental-modules |
| 275 | FIXED_ONE_BYTE_STRING(isolate, "experimentalModules"), |
| 276 | // --expose-internals |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 277 | FIXED_ONE_BYTE_STRING(isolate, "exposeInternals"), |
| 278 | env->primordials_string()}; |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 279 | std::vector<Local<Value>> loaders_args = { |
| 280 | process, |
Joyee Cheung | 3d66826 | 2018-11-28 16:46:45 | [diff] [blame] | 281 | env->NewFunctionTemplate(binding::GetLinkedBinding) |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 282 | ->GetFunction(context) |
| 283 | .ToLocalChecked(), |
Joyee Cheung | 3d66826 | 2018-11-28 16:46:45 | [diff] [blame] | 284 | env->NewFunctionTemplate(binding::GetInternalBinding) |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 285 | ->GetFunction(context) |
| 286 | .ToLocalChecked(), |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 287 | Boolean::New(isolate, env->options()->experimental_modules), |
| 288 | Boolean::New(isolate, env->options()->expose_internals), |
| 289 | env->primordials()}; |
Joyee Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 290 | |
Joyee Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 291 | // Bootstrap internal loaders |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 292 | MaybeLocal<Value> loader_exports = ExecuteBootstrapper( |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 293 | env, "internal/bootstrap/loaders", &loaders_params, &loaders_args); |
| 294 | if (loader_exports.IsEmpty()) { |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 295 | return MaybeLocal<Value>(); |
Joyee Cheung | 2a9eb31 | 2018-03-03 20:55:45 | [diff] [blame] | 296 | } |
| 297 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 298 | 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 Henningsen | 39eca84 | 2019-02-01 22:47:38 | [diff] [blame] | 309 | // process, loaderExports, isMainThread, ownsProcessState, primordials |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 310 | std::vector<Local<String>> node_params = { |
| 311 | env->process_string(), |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 312 | FIXED_ONE_BYTE_STRING(isolate, "loaderExports"), |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 313 | FIXED_ONE_BYTE_STRING(isolate, "isMainThread"), |
Anna Henningsen | 39eca84 | 2019-02-01 22:47:38 | [diff] [blame] | 314 | FIXED_ONE_BYTE_STRING(isolate, "ownsProcessState"), |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 315 | env->primordials_string()}; |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 316 | std::vector<Local<Value>> node_args = { |
| 317 | process, |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 318 | loader_exports_obj, |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 319 | Boolean::New(isolate, env->is_main_thread()), |
Anna Henningsen | 39eca84 | 2019-02-01 22:47:38 | [diff] [blame] | 320 | Boolean::New(isolate, env->owns_process_state()), |
Joyee Cheung | 39d9221 | 2019-01-30 14:21:07 | [diff] [blame] | 321 | env->primordials()}; |
Joyee Cheung | edcb950 | 2018-11-26 17:50:41 | [diff] [blame] | 322 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 323 | MaybeLocal<Value> result = ExecuteBootstrapper( |
| 324 | env, "internal/bootstrap/node", &node_params, &node_args); |
Anna Henningsen | f6a1d88 | 2019-01-02 21:14:23 | [diff] [blame] | 325 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 326 | env->set_has_run_bootstrapping_code(true); |
| 327 | |
| 328 | return scope.EscapeMaybe(result); |
Anna Henningsen | f6a1d88 | 2019-01-02 21:14:23 | [diff] [blame] | 329 | } |
| 330 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 331 | void 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 Henningsen | f6a1d88 | 2019-01-02 21:14:23 | [diff] [blame] | 336 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 337 | MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) { |
| 338 | EscapableHandleScope scope(env->isolate()); |
| 339 | CHECK_NE(main_script_id, nullptr); |
Joyee Cheung | 2c7f4f4 | 2019-01-13 15:44:09 | [diff] [blame] | 340 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 341 | 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, ¶meters, &arguments); |
| 357 | return scope.EscapeMaybe(result); |
| 358 | } |
| 359 | |
| 360 | MaybeLocal<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 Cheung | 2c7f4f4 | 2019-01-13 15:44:09 | [diff] [blame] | 366 | } |
| 367 | |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 368 | 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 | |
| 412 | void 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 | } |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 421 | } |
| 422 | |
Ryan Dahl | 2a7e7b1 | 2010-12-18 19:17:29 | [diff] [blame] | 423 | |
Fedor Indutny | 82d0ac7 | 2011-09-24 13:51:59 | [diff] [blame] | 424 | #ifdef __POSIX__ |
Anna Henningsen | 0815b94 | 2016-05-08 01:28:47 | [diff] [blame] | 425 | void RegisterSignalHandler(int signal, |
| 426 | void (*handler)(int signal), |
| 427 | bool reset_handler) { |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 428 | struct sigaction sa; |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 429 | memset(&sa, 0, sizeof(sa)); |
| 430 | sa.sa_handler = handler; |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 431 | #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 Hauge | c61b0e9 | 2014-03-31 07:52:03 | [diff] [blame] | 435 | sa.sa_flags = reset_handler ? SA_RESETHAND : 0; |
Fedor Indutny | b64983d | 2015-03-20 05:03:34 | [diff] [blame] | 436 | #endif |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 437 | sigfillset(&sa.sa_mask); |
Ben Noordhuis | 2d82cdf | 2014-10-22 01:29:32 | [diff] [blame] | 438 | CHECK_EQ(sigaction(signal, &sa, nullptr), 0); |
Bert Belder | 829735e | 2011-11-04 15:23:02 | [diff] [blame] | 439 | } |
| 440 | |
Fedor Indutny | 8e29ce9 | 2013-07-31 18:07:29 | [diff] [blame] | 441 | #endif // __POSIX__ |
Tom Hughes | f61b110 | 2010-10-12 21:01:58 | [diff] [blame] | 442 | |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 443 | inline void PlatformInit() { |
| 444 | #ifdef __POSIX__ |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 445 | #if HAVE_INSPECTOR |
Ben Noordhuis | 63ae1d2 | 2015-01-26 22:26:33 | [diff] [blame] | 446 | sigset_t sigmask; |
| 447 | sigemptyset(&sigmask); |
| 448 | sigaddset(&sigmask, SIGUSR1); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 449 | const int err = pthread_sigmask(SIG_SETMASK, &sigmask, nullptr); |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 450 | #endif // HAVE_INSPECTOR |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 451 | |
| 452 | // Make sure file descriptors 0-2 are valid before we start logging anything. |
Evan Lucas | 14dc17d | 2018-06-11 14:20:50 | [diff] [blame] | 453 | for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd += 1) { |
| 454 | struct stat ignored; |
| 455 | if (fstat(fd, &ignored) == 0) |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 456 | 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 Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 460 | ABORT(); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 461 | if (fd != open("/dev/null", O_RDWR)) |
Evan Lucas | 870229e | 2015-09-16 15:12:41 | [diff] [blame] | 462 | ABORT(); |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 463 | } |
| 464 | |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 465 | #if HAVE_INSPECTOR |
Ben Noordhuis | b5f25a9 | 2015-02-18 02:43:29 | [diff] [blame] | 466 | CHECK_EQ(err, 0); |
Daniel Bevenius | 65a6e05 | 2017-04-07 06:48:32 | [diff] [blame] | 467 | #endif // HAVE_INSPECTOR |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 468 | |
Stewart X Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 469 | #ifndef NODE_SHARED_MODE |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 470 | // 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 Ostroukhov | 6626919 | 2016-06-08 21:09:28 | [diff] [blame] | 477 | for (unsigned nr = 1; nr < kMaxSignal; nr += 1) { |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 478 | 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 Addison | 0f0f3d3 | 2016-12-30 12:44:46 | [diff] [blame] | 483 | #endif // !NODE_SHARED_MODE |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 484 | |
Ben Noordhuis | 63ae1d2 | 2015-01-26 22:26:33 | [diff] [blame] | 485 | RegisterSignalHandler(SIGINT, SignalExit, true); |
| 486 | RegisterSignalHandler(SIGTERM, SignalExit, true); |
Ben Noordhuis | dd47a8c | 2015-01-26 23:07:34 | [diff] [blame] | 487 | |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 488 | // 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 Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 508 | #endif // __POSIX__ |
Bartosz Sosnowski | bd496e0 | 2017-03-14 17:22:53 | [diff] [blame] | 509 | #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 Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 522 | } |
| 523 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 524 | int ProcessGlobalArgs(std::vector<std::string>* args, |
| 525 | std::vector<std::string>* exec_args, |
| 526 | std::vector<std::string>* errors, |
| 527 | bool is_env) { |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 528 | // Parse a few arguments which are specific to Node. |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 529 | std::vector<std::string> v8_args; |
Anna Henningsen | e812be4 | 2018-08-23 14:41:05 | [diff] [blame] | 530 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 531 | 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 Henningsen | e812be4 | 2018-08-23 14:41:05 | [diff] [blame] | 539 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 540 | if (!errors->empty()) return 9; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 541 | |
Anna Henningsen | 38ab1e9 | 2019-01-12 19:55:58 | [diff] [blame] | 542 | 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 Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 550 | |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 551 | auto env_opts = per_process::cli_options->per_isolate->per_env; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 552 | 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 Bevenius | 6a9e776 | 2018-09-06 08:39:38 | [diff] [blame] | 556 | env_opts->abort_on_uncaught_exception = true; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 557 | } |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 558 | |
| 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 Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 563 | if (std::find(v8_args.begin(), v8_args.end(), "--prof") != v8_args.end()) { |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 564 | per_process::v8_is_profiling = true; |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 565 | } |
| 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 Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 571 | if (per_process::v8_is_profiling) { |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 572 | uv_loop_configure(uv_default_loop(), UV_LOOP_BLOCK_SIGNAL, SIGPROF); |
| 573 | } |
| 574 | #endif |
| 575 | |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 576 | 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 Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 584 | |
| 585 | // Anything that's still in v8_argv is not a V8 or a node option. |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 586 | 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 Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 588 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 589 | if (v8_args_as_char_ptr.size() > 1) return 9; |
| 590 | |
| 591 | return 0; |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 592 | } |
| 593 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 594 | int Init(std::vector<std::string>* argv, |
| 595 | std::vector<std::string>* exec_argv, |
| 596 | std::vector<std::string>* errors) { |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 597 | // Initialize prog_start_time to get relative uptime. |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 598 | per_process::prog_start_time = static_cast<double>(uv_now(uv_default_loop())); |
Ben Noordhuis | 74a8215 | 2012-02-03 15:32:00 | [diff] [blame] | 599 | |
Yihong Wang | 8680bb9 | 2017-10-22 06:16:50 | [diff] [blame] | 600 | // Register built-in modules |
Joyee Cheung | 3d66826 | 2018-11-28 16:46:45 | [diff] [blame] | 601 | binding::RegisterBuiltinModules(); |
Yihong Wang | 8680bb9 | 2017-10-22 06:16:50 | [diff] [blame] | 602 | |
Bert Belder | 09be360 | 2012-06-13 23:28:51 | [diff] [blame] | 603 | // Make inherited handles noninheritable. |
| 604 | uv_disable_stdio_inheritance(); |
| 605 | |
Gireesh Punathil | 4f67973 | 2018-09-05 14:06:59 | [diff] [blame] | 606 | #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 Noordhuis | 490d5ab | 2014-03-31 12:22:49 | [diff] [blame] | 612 | #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 Indutny | b55c9d6 | 2014-03-26 20:30:49 | [diff] [blame] | 618 | |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 619 | std::shared_ptr<EnvironmentOptions> default_env_options = |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 620 | per_process::cli_options->per_isolate->per_env; |
James M Snell | a16b570 | 2017-03-11 20:18:53 | [diff] [blame] | 621 | { |
| 622 | std::string text; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 623 | default_env_options->pending_deprecation = |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 624 | credentials::SafeGetenv("NODE_PENDING_DEPRECATION", &text) && |
| 625 | text[0] == '1'; |
James M Snell | a16b570 | 2017-03-11 20:18:53 | [diff] [blame] | 626 | } |
| 627 | |
Marc Udoff | d3b1a2b | 2016-09-20 22:21:44 | [diff] [blame] | 628 | // Allow for environment set preserving symlinks. |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 629 | { |
| 630 | std::string text; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 631 | default_env_options->preserve_symlinks = |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 632 | credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && |
| 633 | text[0] == '1'; |
Marc Udoff | d3b1a2b | 2016-09-20 22:21:44 | [diff] [blame] | 634 | } |
| 635 | |
David Goldstein | 2365965 | 2018-04-10 07:40:56 | [diff] [blame] | 636 | { |
| 637 | std::string text; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 638 | default_env_options->preserve_symlinks_main = |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 639 | credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) && |
| 640 | text[0] == '1'; |
David Goldstein | 2365965 | 2018-04-10 07:40:56 | [diff] [blame] | 641 | } |
| 642 | |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 643 | if (default_env_options->redirect_warnings.empty()) { |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 644 | credentials::SafeGetenv("NODE_REDIRECT_WARNINGS", |
| 645 | &default_env_options->redirect_warnings); |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 646 | } |
James M Snell | 03e89b3 | 2016-12-04 18:38:35 | [diff] [blame] | 647 | |
Daniel Bevenius | e1d8899 | 2017-02-28 19:04:12 | [diff] [blame] | 648 | #if HAVE_OPENSSL |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 649 | std::string* openssl_config = &per_process::cli_options->openssl_config; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 650 | if (openssl_config->empty()) { |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 651 | credentials::SafeGetenv("OPENSSL_CONF", openssl_config); |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 652 | } |
Daniel Bevenius | e1d8899 | 2017-02-28 19:04:12 | [diff] [blame] | 653 | #endif |
Sam Roberts | 59afa27 | 2017-01-25 22:13:34 | [diff] [blame] | 654 | |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 655 | #if !defined(NODE_WITHOUT_NODE_OPTIONS) |
| 656 | std::string node_options; |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 657 | if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) { |
Anna Henningsen | 8ec3c35 | 2019-01-06 01:48:05 | [diff] [blame] | 658 | // [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 Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 662 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 663 | const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true); |
| 664 | if (exit_code != 0) return exit_code; |
Oleksandr Chekhovskyi | 8e14135 | 2015-08-07 13:03:04 | [diff] [blame] | 665 | } |
| 666 | #endif |
| 667 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 668 | const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, false); |
| 669 | if (exit_code != 0) return exit_code; |
Sam Roberts | f2282bb | 2017-02-20 14:18:43 | [diff] [blame] | 670 | |
James M Snell | 9d71619 | 2018-06-22 23:16:03 | [diff] [blame] | 671 | // Set the process.title immediately after processing argv if --title is set. |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 672 | if (!per_process::cli_options->title.empty()) |
| 673 | uv_set_process_title(per_process::cli_options->title.c_str()); |
James M Snell | 9d71619 | 2018-06-22 23:16:03 | [diff] [blame] | 674 | |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 675 | #if defined(NODE_HAVE_I18N_SUPPORT) |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 676 | // If the parameter isn't given, use the env variable. |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 677 | 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. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 680 | // Initialize ICU. |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 681 | // If icu_data_dir is empty here, it will load the 'minimal' data. |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 682 | if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) { |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 683 | errors->push_back("could not initialize ICU " |
| 684 | "(check NODE_ICU_DATA or --icu-data-dir parameters)\n"); |
| 685 | return 9; |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 686 | } |
Joyee Cheung | 263d137 | 2018-12-18 21:23:47 | [diff] [blame] | 687 | per_process::metadata.versions.InitializeIntlVersions(); |
Steven R. Loomis | ac2857b | 2014-09-05 05:03:24 | [diff] [blame] | 688 | #endif |
Tom Hughes | 78da9cb | 2010-10-18 22:50:56 | [diff] [blame] | 689 | |
Cheng Zhao | 22e1aea | 2015-01-12 21:31:25 | [diff] [blame] | 690 | // 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 Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 694 | return 0; |
Ben Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 695 | } |
Ben Noordhuis | 356992f | 2011-11-22 16:10:09 | [diff] [blame] | 696 | |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 697 | // TODO(addaleax): Deprecate and eventually remove this. |
| 698 | void 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 Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 704 | std::vector<std::string> errors; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 705 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 706 | // 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 Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 723 | |
| 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 Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 735 | |
Anatoli Papirovski | 8803b69 | 2018-01-18 21:52:51 | [diff] [blame] | 736 | void RunBeforeExit(Environment* env) { |
| 737 | env->RunBeforeExitCallbacks(); |
| 738 | |
| 739 | if (!uv_loop_alive(env->event_loop())) |
| 740 | EmitBeforeExit(env); |
| 741 | } |
| 742 | |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 743 | inline int Start(Isolate* isolate, IsolateData* isolate_data, |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 744 | const std::vector<std::string>& args, |
| 745 | const std::vector<std::string>& exec_args) { |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 746 | HandleScope handle_scope(isolate); |
Ben Noordhuis | 668ad44 | 2017-09-07 11:26:47 | [diff] [blame] | 747 | Local<Context> context = NewContext(isolate); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 748 | Context::Scope context_scope(context); |
Anna Henningsen | 39eca84 | 2019-02-01 22:47:38 | [diff] [blame] | 749 | Environment env( |
| 750 | isolate_data, |
| 751 | context, |
| 752 | static_cast<Environment::Flags>(Environment::kIsMainThread | |
| 753 | Environment::kOwnsProcessState | |
| 754 | Environment::kOwnsInspector)); |
Anna Henningsen | 95571ac | 2019-01-27 13:21:21 | [diff] [blame] | 755 | env.Start(per_process::v8_is_profiling); |
Joyee Cheung | 6967f91 | 2019-01-15 15:12:21 | [diff] [blame] | 756 | env.ProcessCliArgs(args, exec_args); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 757 | |
Joyee Cheung | e3e4048 | 2019-01-21 14:57:51 | [diff] [blame] | 758 | #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 Cheung | 61a8963 | 2018-12-01 17:30:30 | [diff] [blame] | 767 | if (env.options()->debug_options().inspector_enabled && |
Joyee Cheung | e3e4048 | 2019-01-21 14:57:51 | [diff] [blame] | 768 | !env.inspector_agent()->IsListening()) { |
Eugene Ostroukhov | 7599b0e | 2016-12-13 01:08:31 | [diff] [blame] | 769 | return 12; // Signal internal error. |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 770 | } |
Joyee Cheung | e3e4048 | 2019-01-21 14:57:51 | [diff] [blame] | 771 | #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 Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 776 | |
| 777 | { |
| 778 | Environment::AsyncCallbackScope callback_scope(&env); |
Andreas Madsen | 3a69ef5 | 2017-09-26 13:50:10 | [diff] [blame] | 779 | env.async_hooks()->push_async_ids(1, 0); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 780 | LoadEnvironment(&env); |
Andreas Madsen | 3a69ef5 | 2017-09-26 13:50:10 | [diff] [blame] | 781 | env.async_hooks()->pop_async_id(1); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 782 | } |
| 783 | |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 784 | { |
| 785 | SealHandleScope seal(isolate); |
| 786 | bool more; |
James M Snell | 96cb4fb | 2018-03-06 18:42:37 | [diff] [blame] | 787 | env.performance_state()->Mark( |
| 788 | node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 789 | do { |
Matt Loring | 9e08695 | 2017-03-13 22:17:57 | [diff] [blame] | 790 | uv_run(env.event_loop(), UV_RUN_DEFAULT); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 791 | |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 792 | per_process::v8_platform.DrainVMTasks(isolate); |
Anna Henningsen | f27b5e4 | 2017-09-15 13:03:48 | [diff] [blame] | 793 | |
| 794 | more = uv_loop_alive(env.event_loop()); |
| 795 | if (more) |
| 796 | continue; |
| 797 | |
Anatoli Papirovski | 8803b69 | 2018-01-18 21:52:51 | [diff] [blame] | 798 | RunBeforeExit(&env); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 799 | |
Matt Loring | 9e08695 | 2017-03-13 22:17:57 | [diff] [blame] | 800 | // 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 Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 803 | } while (more == true); |
James M Snell | 96cb4fb | 2018-03-06 18:42:37 | [diff] [blame] | 804 | env.performance_state()->Mark( |
| 805 | node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 806 | } |
| 807 | |
| 808 | env.set_trace_sync_io(false); |
| 809 | |
| 810 | const int exit_code = EmitExit(&env); |
Anna Henningsen | 5c6cf30 | 2017-09-09 20:28:02 | [diff] [blame] | 811 | |
Anna Henningsen | 61fd027 | 2017-09-09 20:29:08 | [diff] [blame] | 812 | WaitForInspectorDisconnect(&env); |
| 813 | |
Anna Henningsen | bcb324c | 2017-09-20 12:43:19 | [diff] [blame] | 814 | env.set_can_call_into_js(false); |
Anna Henningsen | 0df031a | 2017-09-01 15:03:41 | [diff] [blame] | 815 | env.stop_sub_worker_contexts(); |
Anna Henningsen | 43fd1d7 | 2018-05-30 09:18:43 | [diff] [blame] | 816 | uv_tty_reset_mode(); |
Anna Henningsen | 5c6cf30 | 2017-09-09 20:28:02 | [diff] [blame] | 817 | env.RunCleanup(); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 818 | RunAtExit(&env); |
| 819 | |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 820 | per_process::v8_platform.DrainVMTasks(isolate); |
| 821 | per_process::v8_platform.CancelVMTasks(isolate); |
Ben Noordhuis | ceb6023 | 2016-10-21 12:24:48 | [diff] [blame] | 822 | #if defined(LEAK_SANITIZER) |
| 823 | __lsan_do_leak_check(); |
| 824 | #endif |
| 825 | |
| 826 | return exit_code; |
| 827 | } |
| 828 | |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 829 | inline int Start(uv_loop_t* event_loop, |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 830 | const std::vector<std::string>& args, |
| 831 | const std::vector<std::string>& exec_args) { |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 832 | std::unique_ptr<ArrayBufferAllocator, decltype(&FreeArrayBufferAllocator)> |
| 833 | allocator(CreateArrayBufferAllocator(), &FreeArrayBufferAllocator); |
Andreas Haas | d5e7294 | 2018-06-03 15:35:25 | [diff] [blame] | 834 | Isolate* const isolate = NewIsolate(allocator.get(), event_loop); |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 835 | if (isolate == nullptr) |
| 836 | return 12; // Signal internal error. |
| 837 | |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 838 | 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 Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 848 | int exit_code; |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 849 | { |
| 850 | Locker locker(isolate); |
| 851 | Isolate::Scope isolate_scope(isolate); |
| 852 | HandleScope handle_scope(isolate); |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 853 | std::unique_ptr<IsolateData, decltype(&FreeIsolateData)> isolate_data( |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 854 | CreateIsolateData(isolate, |
| 855 | event_loop, |
| 856 | per_process::v8_platform.Platform(), |
| 857 | allocator.get()), |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 858 | &FreeIsolateData); |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 859 | // 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 Payer | 91d1312 | 2017-11-22 13:43:42 | [diff] [blame] | 862 | isolate->GetHeapProfiler()->StartTrackingHeapObjects(true); |
| 863 | } |
helloshuangzi | 963cb3a | 2018-05-11 18:06:05 | [diff] [blame] | 864 | exit_code = |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 865 | Start(isolate, isolate_data.get(), args, exec_args); |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 866 | } |
| 867 | |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 868 | isolate->Dispose(); |
Joyee Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 869 | per_process::v8_platform.Platform()->UnregisterIsolate(isolate); |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 870 | |
| 871 | return exit_code; |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 872 | } |
| 873 | |
Ben Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 874 | int Start(int argc, char** argv) { |
Evan Lucas | 14dc17d | 2018-06-11 14:20:50 | [diff] [blame] | 875 | atexit([] () { uv_tty_reset_mode(); }); |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 876 | PlatformInit(); |
Daniel Bevenius | cae4182 | 2018-02-23 14:42:20 | [diff] [blame] | 877 | performance::performance_node_start = PERFORMANCE_NOW(); |
Ben Noordhuis | 5756f92 | 2015-01-26 22:15:20 | [diff] [blame] | 878 | |
Ben Noordhuis | 5fdff38 | 2014-10-11 14:52:07 | [diff] [blame] | 879 | CHECK_GT(argc, 0); |
Micheil Smith | 19fd530 | 2012-03-05 17:53:15 | [diff] [blame] | 880 | |
Suresh Srinivas | bf7ed80 | 2018-03-23 19:16:48 | [diff] [blame] | 881 | #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 Noordhuis | 185c515 | 2013-09-02 14:42:01 | [diff] [blame] | 889 | // Hack around with the argv pointer. Used for process.title = "blah". |
Ben Noordhuis | 1a97998 | 2012-03-15 22:10:32 | [diff] [blame] | 890 | argv = uv_setup_args(argc, argv); |
| 891 | |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 892 | std::vector<std::string> args(argv, argv + argc); |
| 893 | std::vector<std::string> exec_args; |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 894 | std::vector<std::string> errors; |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 895 | // This needs to run *before* V8::Initialize(). |
Anna Henningsen | eb664c3 | 2019-01-06 21:55:09 | [diff] [blame] | 896 | { |
| 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 Noordhuis | 5866f1a | 2011-12-09 18:02:33 | [diff] [blame] | 902 | |
Ben Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 903 | #if HAVE_OPENSSL |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 904 | { |
| 905 | std::string extra_ca_certs; |
Joyee Cheung | 321e296 | 2018-12-15 19:13:12 | [diff] [blame] | 906 | if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs)) |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 907 | crypto::UseExtraCaCerts(extra_ca_certs); |
| 908 | } |
Stefan Budeanu | 7c48cb5 | 2016-01-22 23:10:09 | [diff] [blame] | 909 | #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 Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 914 | // V8 on Windows doesn't have a good source of entropy. Seed it from |
| 915 | // OpenSSL's pool. |
| 916 | V8::SetEntropySource(crypto::EntropySource); |
Ben Noordhuis | a8734af | 2017-01-28 12:27:02 | [diff] [blame] | 917 | #endif // HAVE_OPENSSL |
Ben Noordhuis | 7ac2391 | 2013-09-20 20:01:49 | [diff] [blame] | 918 | |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 919 | InitializeV8Platform(per_process::cli_options->v8_thread_pool_size); |
Ben Noordhuis | 75ea566 | 2013-09-23 12:27:26 | [diff] [blame] | 920 | V8::Initialize(); |
Daniel Bevenius | cae4182 | 2018-02-23 14:42:20 | [diff] [blame] | 921 | performance::performance_v8_start = PERFORMANCE_NOW(); |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 922 | per_process::v8_initialized = true; |
Ben Noordhuis | d77e818 | 2016-10-21 11:47:49 | [diff] [blame] | 923 | const int exit_code = |
Anna Henningsen | 29a71ba | 2018-08-10 00:45:28 | [diff] [blame] | 924 | Start(uv_default_loop(), args, exec_args); |
Joyee Cheung | 9db9e7e | 2019-01-01 05:56:53 | [diff] [blame] | 925 | per_process::v8_initialized = false; |
Ryan | 27b268b | 2009-06-17 13:05:44 | [diff] [blame] | 926 | V8::Dispose(); |
Igor Zinkovsky | a58b643 | 2011-07-07 20:54:30 | [diff] [blame] | 927 | |
Matt Loring | 9e08695 | 2017-03-13 22:17:57 | [diff] [blame] | 928 | // 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 Cheung | 99c3243 | 2019-01-16 18:34:43 | [diff] [blame] | 934 | per_process::v8_platform.Dispose(); |
Ben Noordhuis | 4a801c2 | 2015-04-02 21:51:01 | [diff] [blame] | 935 | |
Petka Antonov | 4ae64b2 | 2015-03-03 20:25:47 | [diff] [blame] | 936 | return exit_code; |
Ryan | 19478ed | 2009-03-03 00:56:15 | [diff] [blame] | 937 | } |
Ryan Dahl | 124fbed | 2010-09-19 20:13:57 | [diff] [blame] | 938 | |
Ryan Dahl | 124fbed | 2010-09-19 20:13:57 | [diff] [blame] | 939 | } // namespace node |
Eugene Ostroukhov | 3f48ab3 | 2017-04-25 21:55:55 | [diff] [blame] | 940 | |
| 941 | #if !HAVE_INSPECTOR |
Daniel Bevenius | ebbf393 | 2018-03-23 08:38:16 | [diff] [blame] | 942 | void Initialize() {} |
Eugene Ostroukhov | 3f48ab3 | 2017-04-25 21:55:55 | [diff] [blame] | 943 | |
Beni von Cheni | 0500237 | 2018-12-10 03:12:39 | [diff] [blame] | 944 | NODE_MODULE_CONTEXT_AWARE_INTERNAL(inspector, Initialize) |
Eugene Ostroukhov | 3f48ab3 | 2017-04-25 21:55:55 | [diff] [blame] | 945 | #endif // !HAVE_INSPECTOR |