GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_main_instance.cc Lines: 96 97 99.0 %
Date: 2022-05-21 04:15:56 Branches: 42 52 80.8 %

Line Branch Exec Source
1
#include "node_main_instance.h"
2
#include <memory>
3
#if HAVE_OPENSSL
4
#include "crypto/crypto_util.h"
5
#endif  // HAVE_OPENSSL
6
#include "debug_utils-inl.h"
7
#include "node_external_reference.h"
8
#include "node_internals.h"
9
#include "node_native_module_env.h"
10
#include "node_options-inl.h"
11
#include "node_snapshot_builder.h"
12
#include "node_snapshotable.h"
13
#include "node_v8_platform-inl.h"
14
#include "util-inl.h"
15
#if defined(LEAK_SANITIZER)
16
#include <sanitizer/lsan_interface.h>
17
#endif
18
19
#if HAVE_INSPECTOR
20
#include "inspector/worker_inspector.h"  // ParentInspectorHandle
21
#endif
22
23
namespace node {
24
25
using v8::Context;
26
using v8::HandleScope;
27
using v8::Isolate;
28
using v8::Local;
29
using v8::Locker;
30
31
6
NodeMainInstance::NodeMainInstance(Isolate* isolate,
32
                                   uv_loop_t* event_loop,
33
                                   MultiIsolatePlatform* platform,
34
                                   const std::vector<std::string>& args,
35
6
                                   const std::vector<std::string>& exec_args)
36
    : args_(args),
37
      exec_args_(exec_args),
38
      array_buffer_allocator_(nullptr),
39
      isolate_(isolate),
40
      platform_(platform),
41
      isolate_data_(nullptr),
42
6
      snapshot_data_(nullptr) {
43
  isolate_data_ =
44
6
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
45
46
6
  SetIsolateMiscHandlers(isolate_, {});
47
6
}
48
49
6
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
50
    Isolate* isolate,
51
    uv_loop_t* event_loop,
52
    MultiIsolatePlatform* platform,
53
    const std::vector<std::string>& args,
54
    const std::vector<std::string>& exec_args) {
55
  return std::unique_ptr<NodeMainInstance>(
56
6
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
57
}
58
59
5180
NodeMainInstance::NodeMainInstance(const SnapshotData* snapshot_data,
60
                                   uv_loop_t* event_loop,
61
                                   MultiIsolatePlatform* platform,
62
                                   const std::vector<std::string>& args,
63
5180
                                   const std::vector<std::string>& exec_args)
64
    : args_(args),
65
      exec_args_(exec_args),
66
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
67
      isolate_(nullptr),
68
      platform_(platform),
69
      isolate_data_(),
70
      isolate_params_(std::make_unique<Isolate::CreateParams>()),
71
5180
      snapshot_data_(snapshot_data) {
72
5180
  isolate_params_->array_buffer_allocator = array_buffer_allocator_.get();
73
5180
  if (snapshot_data != nullptr) {
74
5178
    SnapshotBuilder::InitializeIsolateParams(snapshot_data,
75
                                             isolate_params_.get());
76
  }
77
78
5180
  isolate_ = Isolate::Allocate();
79
5180
  CHECK_NOT_NULL(isolate_);
80
  // Register the isolate on the platform before the isolate gets initialized,
81
  // so that the isolate can access the platform during initialization.
82
5180
  platform->RegisterIsolate(isolate_, event_loop);
83
5180
  SetIsolateCreateParamsForNode(isolate_params_.get());
84
5180
  Isolate::Initialize(isolate_, *isolate_params_);
85
86
  // If the indexes are not nullptr, we are not deserializing
87
5180
  isolate_data_ = std::make_unique<IsolateData>(
88
5180
      isolate_,
89
      event_loop,
90
      platform,
91
5180
      array_buffer_allocator_.get(),
92
5180
      snapshot_data == nullptr ? nullptr
93
5180
                               : &(snapshot_data->isolate_data_indices));
94
5180
  IsolateSettings s;
95
5180
  SetIsolateMiscHandlers(isolate_, s);
96
5180
  if (snapshot_data == nullptr) {
97
    // If in deserialize mode, delay until after the deserialization is
98
    // complete.
99
2
    SetIsolateErrorHandlers(isolate_, s);
100
  }
101
5180
  isolate_data_->max_young_gen_size =
102
5180
      isolate_params_->constraints.max_young_generation_size_in_bytes();
103
5180
}
104
105
6
void NodeMainInstance::Dispose() {
106
  // This should only be called on a main instance that does not own its
107
  // isolate.
108
6
  CHECK_NULL(isolate_params_);
109
6
  platform_->DrainTasks(isolate_);
110
6
}
111
112


4704
NodeMainInstance::~NodeMainInstance() {
113
4680
  if (isolate_params_ == nullptr) {
114
6
    return;
115
  }
116
  // This should only be done on a main instance that owns its isolate.
117
4674
  platform_->UnregisterIsolate(isolate_);
118
4674
  isolate_->Dispose();
119
4680
}
120
121
5180
int NodeMainInstance::Run() {
122
9854
  Locker locker(isolate_);
123
9854
  Isolate::Scope isolate_scope(isolate_);
124
9854
  HandleScope handle_scope(isolate_);
125
126
5180
  int exit_code = 0;
127
  DeleteFnPtr<Environment, FreeEnvironment> env =
128
9854
      CreateMainEnvironment(&exit_code);
129
5180
  CHECK_NOT_NULL(env);
130
131
5180
  Context::Scope context_scope(env->context());
132
5180
  Run(&exit_code, env.get());
133
4674
  return exit_code;
134
}
135
136
5180
void NodeMainInstance::Run(int* exit_code, Environment* env) {
137
5180
  if (*exit_code == 0) {
138
5180
    LoadEnvironment(env, StartExecutionCallback{});
139
140
9564
    *exit_code = SpinEventLoop(env).FromMaybe(1);
141
  }
142
143
4674
  ResetStdio();
144
145
  // TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really
146
  // make sense here.
147
#if HAVE_INSPECTOR && defined(__POSIX__) && !defined(NODE_SHARED_MODE)
148
  struct sigaction act;
149
4674
  memset(&act, 0, sizeof(act));
150
149568
  for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
151

144894
    if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
152
14022
      continue;
153
130872
    act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
154
130872
    CHECK_EQ(0, sigaction(nr, &act, nullptr));
155
  }
156
#endif
157
158
#if defined(LEAK_SANITIZER)
159
  __lsan_do_leak_check();
160
#endif
161
4674
}
162
163
DeleteFnPtr<Environment, FreeEnvironment>
164
5180
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
165
5180
  *exit_code = 0;  // Reset the exit code to 0
166
167
10360
  HandleScope handle_scope(isolate_);
168
169
  // TODO(addaleax): This should load a real per-Isolate option, currently
170
  // this is still effectively per-process.
171
5180
  if (isolate_data_->options()->track_heap_objects) {
172
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
173
  }
174
175
  Local<Context> context;
176
5180
  DeleteFnPtr<Environment, FreeEnvironment> env;
177
178
5180
  if (snapshot_data_ != nullptr) {
179
10356
    env.reset(new Environment(isolate_data_.get(),
180
                              isolate_,
181
5178
                              args_,
182
5178
                              exec_args_,
183
5178
                              &(snapshot_data_->env_info),
184
                              EnvironmentFlags::kDefaultFlags,
185
5178
                              {}));
186
5178
    context = Context::FromSnapshot(isolate_,
187
                                    SnapshotData::kNodeMainContextIndex,
188
5178
                                    {DeserializeNodeInternalFields, env.get()})
189
5178
                  .ToLocalChecked();
190
191
5178
    CHECK(!context.IsEmpty());
192
5178
    Context::Scope context_scope(context);
193
194
10356
    CHECK(InitializeContextRuntime(context).IsJust());
195
5178
    SetIsolateErrorHandlers(isolate_, {});
196
5178
    env->InitializeMainContext(context, &(snapshot_data_->env_info));
197
#if HAVE_INSPECTOR
198
5178
    env->InitializeInspector({});
199
#endif
200
5178
    env->DoneBootstrapping();
201
202
#if HAVE_OPENSSL
203
5178
    crypto::InitCryptoOnce(isolate_);
204
#endif  // HAVE_OPENSSL
205
  } else {
206
2
    context = NewContext(isolate_);
207
2
    CHECK(!context.IsEmpty());
208
2
    Context::Scope context_scope(context);
209
4
    env.reset(new Environment(isolate_data_.get(),
210
                              context,
211
2
                              args_,
212
2
                              exec_args_,
213
                              nullptr,
214
                              EnvironmentFlags::kDefaultFlags,
215
2
                              {}));
216
#if HAVE_INSPECTOR
217
2
    env->InitializeInspector({});
218
#endif
219
4
    if (env->RunBootstrapping().IsEmpty()) {
220
      return nullptr;
221
    }
222
  }
223
224
5180
  return env;
225
}
226
227
}  // namespace node