GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_process_methods.cc Lines: 258 273 94.5 %
Date: 2021-12-06 04:13:56 Branches: 65 100 65.0 %

Line Branch Exec Source
1
#include "base_object-inl.h"
2
#include "debug_utils-inl.h"
3
#include "env-inl.h"
4
#include "memory_tracker-inl.h"
5
#include "node.h"
6
#include "node_errors.h"
7
#include "node_external_reference.h"
8
#include "node_internals.h"
9
#include "node_process-inl.h"
10
#include "util-inl.h"
11
#include "uv.h"
12
#include "v8-fast-api-calls.h"
13
#include "v8.h"
14
15
#include <vector>
16
17
#if HAVE_INSPECTOR
18
#include "inspector_io.h"
19
#endif
20
21
#include <climits>  // PATH_MAX
22
#include <cstdio>
23
24
#if defined(_MSC_VER)
25
#include <direct.h>
26
#include <io.h>
27
#define umask _umask
28
typedef int mode_t;
29
#else
30
#include <pthread.h>
31
#include <sys/resource.h>  // getrlimit, setrlimit
32
#include <termios.h>  // tcgetattr, tcsetattr
33
#endif
34
35
namespace node {
36
37
using v8::Array;
38
using v8::ArrayBuffer;
39
using v8::CFunction;
40
using v8::Context;
41
using v8::Float64Array;
42
using v8::FunctionCallbackInfo;
43
using v8::HeapStatistics;
44
using v8::Integer;
45
using v8::Isolate;
46
using v8::Local;
47
using v8::NewStringType;
48
using v8::Number;
49
using v8::Object;
50
using v8::String;
51
using v8::Uint32;
52
using v8::Value;
53
54
namespace per_process {
55
Mutex umask_mutex;
56
}   // namespace per_process
57
58
// Microseconds in a second, as a float, used in CPUUsage() below
59
#define MICROS_PER_SEC 1e6
60
// used in Hrtime() and Uptime() below
61
#define NANOS_PER_SEC 1000000000
62
63
static void Abort(const FunctionCallbackInfo<Value>& args) {
64
  Abort();
65
}
66
67
// For internal testing only, not exposed to userland.
68
static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
69
  // This should crash hard all platforms.
70
  volatile void** d = static_cast<volatile void**>(nullptr);
71
  *d = nullptr;
72
}
73
74
452
static void Chdir(const FunctionCallbackInfo<Value>& args) {
75
452
  Environment* env = Environment::GetCurrent(args);
76
452
  CHECK(env->owns_process_state());
77
78
452
  CHECK_EQ(args.Length(), 1);
79
904
  CHECK(args[0]->IsString());
80
452
  Utf8Value path(env->isolate(), args[0]);
81
452
  int err = uv_chdir(*path);
82
452
  if (err) {
83
    // Also include the original working directory, since that will usually
84
    // be helpful information when debugging a `chdir()` failure.
85
    char buf[PATH_MAX_BYTES];
86
1
    size_t cwd_len = sizeof(buf);
87
1
    uv_cwd(buf, &cwd_len);
88
1
    return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
89
  }
90
}
91
92
556
inline Local<ArrayBuffer> get_fields_array_buffer(
93
    const FunctionCallbackInfo<Value>& args,
94
    size_t index,
95
    size_t array_length) {
96

1112
  CHECK(args[index]->IsFloat64Array());
97
1668
  Local<Float64Array> arr = args[index].As<Float64Array>();
98
556
  CHECK_EQ(arr->Length(), array_length);
99
556
  return arr->Buffer();
100
}
101
102
// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
103
// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
104
// which are uv_timeval_t structs (long tv_sec, long tv_usec).
105
// Returns those values as Float64 microseconds in the elements of the array
106
// passed to the function.
107
33
static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
108
33
  Environment* env = Environment::GetCurrent(args);
109
  uv_rusage_t rusage;
110
111
  // Call libuv to get the values we'll return.
112
33
  int err = uv_getrusage(&rusage);
113
33
  if (err)
114
    return env->ThrowUVException(err, "uv_getrusage");
115
116
  // Get the double array pointer from the Float64Array argument.
117
33
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 2);
118
33
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
119
120
  // Set the Float64Array elements to be user / system values in microseconds.
121
33
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
122
33
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
123
}
124
125
6147
static void Cwd(const FunctionCallbackInfo<Value>& args) {
126
6147
  Environment* env = Environment::GetCurrent(args);
127
6147
  CHECK(env->has_run_bootstrapping_code());
128
  char buf[PATH_MAX_BYTES];
129
6147
  size_t cwd_len = sizeof(buf);
130
6147
  int err = uv_cwd(buf, &cwd_len);
131
6147
  if (err)
132
13
    return env->ThrowUVException(err, "uv_cwd");
133
134
6134
  Local<String> cwd = String::NewFromUtf8(env->isolate(),
135
                                          buf,
136
                                          NewStringType::kNormal,
137
12268
                                          cwd_len).ToLocalChecked();
138
12268
  args.GetReturnValue().Set(cwd);
139
}
140
141
64
static void Kill(const FunctionCallbackInfo<Value>& args) {
142
64
  Environment* env = Environment::GetCurrent(args);
143
64
  Local<Context> context = env->context();
144
145
64
  if (args.Length() < 2) {
146
    THROW_ERR_MISSING_ARGS(env, "Bad argument.");
147
  }
148
149
  int pid;
150
128
  if (!args[0]->Int32Value(context).To(&pid)) return;
151
  int sig;
152
128
  if (!args[1]->Int32Value(context).To(&sig)) return;
153
154
64
  uv_pid_t own_pid = uv_os_getpid();
155
190
  if (sig > 0 &&
156



92
      (pid == 0 || pid == -1 || pid == own_pid || pid == -own_pid) &&
157
28
      !HasSignalJSHandler(sig)) {
158
    // This is most likely going to terminate this process.
159
    // It's not an exact method but it might be close enough.
160
19
    RunAtExit(env);
161
  }
162
163
64
  int err = uv_kill(pid, sig);
164
128
  args.GetReturnValue().Set(err);
165
}
166
167
4
static void Rss(const FunctionCallbackInfo<Value>& args) {
168
4
  Environment* env = Environment::GetCurrent(args);
169
170
  size_t rss;
171
4
  int err = uv_resident_set_memory(&rss);
172
4
  if (err)
173
    return env->ThrowUVException(err, "uv_resident_set_memory");
174
175
8
  args.GetReturnValue().Set(static_cast<double>(rss));
176
}
177
178
522
static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
179
522
  Environment* env = Environment::GetCurrent(args);
180
181
522
  Isolate* isolate = env->isolate();
182
  // V8 memory usage
183
522
  HeapStatistics v8_heap_stats;
184
522
  isolate->GetHeapStatistics(&v8_heap_stats);
185
186
  NodeArrayBufferAllocator* array_buffer_allocator =
187
522
      env->isolate_data()->node_allocator();
188
189
  // Get the double array pointer from the Float64Array argument.
190
522
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 5);
191
522
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
192
193
  size_t rss;
194
522
  int err = uv_resident_set_memory(&rss);
195
522
  if (err)
196
    return env->ThrowUVException(err, "uv_resident_set_memory");
197
198
522
  fields[0] = static_cast<double>(rss);
199
522
  fields[1] = static_cast<double>(v8_heap_stats.total_heap_size());
200
522
  fields[2] = static_cast<double>(v8_heap_stats.used_heap_size());
201
522
  fields[3] = static_cast<double>(v8_heap_stats.external_memory());
202
522
  fields[4] =
203
      array_buffer_allocator == nullptr
204
1044
          ? 0
205
522
          : static_cast<double>(array_buffer_allocator->total_mem_usage());
206
}
207
208
22
void RawDebug(const FunctionCallbackInfo<Value>& args) {
209


66
  CHECK(args.Length() == 1 && args[0]->IsString() &&
210
        "must be called with a single string");
211
44
  Utf8Value message(args.GetIsolate(), args[0]);
212
22
  FPrintF(stderr, "%s\n", message);
213
22
  fflush(stderr);
214
22
}
215
216
4122
static void Umask(const FunctionCallbackInfo<Value>& args) {
217
4122
  Environment* env = Environment::GetCurrent(args);
218
4122
  CHECK(env->has_run_bootstrapping_code());
219
4122
  CHECK_EQ(args.Length(), 1);
220

12359
  CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
221
4122
  Mutex::ScopedLock scoped_lock(per_process::umask_mutex);
222
223
  uint32_t old;
224
8244
  if (args[0]->IsUndefined()) {
225
7
    old = umask(0);
226
7
    umask(static_cast<mode_t>(old));
227
  } else {
228
8230
    int oct = args[0].As<Uint32>()->Value();
229
4115
    old = umask(static_cast<mode_t>(oct));
230
  }
231
232
8244
  args.GetReturnValue().Set(old);
233
4122
}
234
235
4
static void Uptime(const FunctionCallbackInfo<Value>& args) {
236
4
  Environment* env = Environment::GetCurrent(args);
237
238
4
  uv_update_time(env->event_loop());
239
  double uptime =
240
4
      static_cast<double>(uv_hrtime() - per_process::node_start_time);
241
4
  Local<Number> result = Number::New(env->isolate(), uptime / NANOS_PER_SEC);
242
4
  args.GetReturnValue().Set(result);
243
4
}
244
245
2
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
246
2
  Environment* env = Environment::GetCurrent(args);
247
248
2
  std::vector<Local<Value>> request_v;
249
14
  for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
250
12
    AsyncWrap* w = req_wrap->GetAsyncWrap();
251
12
    if (w->persistent().IsEmpty())
252
      continue;
253
12
    request_v.emplace_back(w->GetOwner());
254
  }
255
256
4
  args.GetReturnValue().Set(
257
      Array::New(env->isolate(), request_v.data(), request_v.size()));
258
2
}
259
260
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
261
// implemented here for consistency with GetActiveRequests().
262
5
void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
263
5
  Environment* env = Environment::GetCurrent(args);
264
265
5
  std::vector<Local<Value>> handle_v;
266
25
  for (auto w : *env->handle_wrap_queue()) {
267
20
    if (!HandleWrap::HasRef(w))
268
1
      continue;
269
19
    handle_v.emplace_back(w->GetOwner());
270
  }
271
10
  args.GetReturnValue().Set(
272
      Array::New(env->isolate(), handle_v.data(), handle_v.size()));
273
5
}
274
275
1
static void ResourceUsage(const FunctionCallbackInfo<Value>& args) {
276
1
  Environment* env = Environment::GetCurrent(args);
277
278
  uv_rusage_t rusage;
279
1
  int err = uv_getrusage(&rusage);
280
1
  if (err)
281
    return env->ThrowUVException(err, "uv_getrusage");
282
283
1
  Local<ArrayBuffer> ab = get_fields_array_buffer(args, 0, 16);
284
1
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
285
286
1
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
287
1
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
288
1
  fields[2] = static_cast<double>(rusage.ru_maxrss);
289
1
  fields[3] = static_cast<double>(rusage.ru_ixrss);
290
1
  fields[4] = static_cast<double>(rusage.ru_idrss);
291
1
  fields[5] = static_cast<double>(rusage.ru_isrss);
292
1
  fields[6] = static_cast<double>(rusage.ru_minflt);
293
1
  fields[7] = static_cast<double>(rusage.ru_majflt);
294
1
  fields[8] = static_cast<double>(rusage.ru_nswap);
295
1
  fields[9] = static_cast<double>(rusage.ru_inblock);
296
1
  fields[10] = static_cast<double>(rusage.ru_oublock);
297
1
  fields[11] = static_cast<double>(rusage.ru_msgsnd);
298
1
  fields[12] = static_cast<double>(rusage.ru_msgrcv);
299
1
  fields[13] = static_cast<double>(rusage.ru_nsignals);
300
1
  fields[14] = static_cast<double>(rusage.ru_nvcsw);
301
1
  fields[15] = static_cast<double>(rusage.ru_nivcsw);
302
}
303
304
#ifdef __POSIX__
305
4
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
306
4
  Environment* env = Environment::GetCurrent(args);
307
308
4
  if (args.Length() < 1) {
309
    return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
310
  }
311
312
4
  CHECK(args[0]->IsNumber());
313
8
  pid_t pid = args[0].As<Integer>()->Value();
314
4
  int r = kill(pid, SIGUSR1);
315
316
4
  if (r != 0) {
317
1
    return env->ThrowErrnoException(errno, "kill");
318
  }
319
}
320
#endif  // __POSIX__
321
322
#ifdef _WIN32
323
static int GetDebugSignalHandlerMappingName(DWORD pid,
324
                                            wchar_t* buf,
325
                                            size_t buf_len) {
326
  return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
327
}
328
329
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
330
  Environment* env = Environment::GetCurrent(args);
331
  Isolate* isolate = args.GetIsolate();
332
333
  if (args.Length() < 1) {
334
    return THROW_ERR_MISSING_ARGS(env, "Invalid number of arguments.");
335
  }
336
337
  HANDLE process = nullptr;
338
  HANDLE thread = nullptr;
339
  HANDLE mapping = nullptr;
340
  wchar_t mapping_name[32];
341
  LPTHREAD_START_ROUTINE* handler = nullptr;
342
  DWORD pid = 0;
343
344
  auto cleanup = OnScopeLeave([&]() {
345
    if (process != nullptr) CloseHandle(process);
346
    if (thread != nullptr) CloseHandle(thread);
347
    if (handler != nullptr) UnmapViewOfFile(handler);
348
    if (mapping != nullptr) CloseHandle(mapping);
349
  });
350
351
  CHECK(args[0]->IsNumber());
352
  pid = static_cast<DWORD>(args[0].As<Integer>()->Value());
353
354
  process =
355
      OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
356
                      PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
357
                  FALSE,
358
                  pid);
359
  if (process == nullptr) {
360
    isolate->ThrowException(
361
        WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
362
    return;
363
  }
364
365
  if (GetDebugSignalHandlerMappingName(
366
          pid, mapping_name, arraysize(mapping_name)) < 0) {
367
    env->ThrowErrnoException(errno, "sprintf");
368
    return;
369
  }
370
371
  mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
372
  if (mapping == nullptr) {
373
    isolate->ThrowException(
374
        WinapiErrnoException(isolate, GetLastError(), "OpenFileMappingW"));
375
    return;
376
  }
377
378
  handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
379
      MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, sizeof *handler));
380
  if (handler == nullptr || *handler == nullptr) {
381
    isolate->ThrowException(
382
        WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
383
    return;
384
  }
385
386
  thread =
387
      CreateRemoteThread(process, nullptr, 0, *handler, nullptr, 0, nullptr);
388
  if (thread == nullptr) {
389
    isolate->ThrowException(
390
        WinapiErrnoException(isolate, GetLastError(), "CreateRemoteThread"));
391
    return;
392
  }
393
394
  // Wait for the thread to terminate
395
  if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
396
    isolate->ThrowException(
397
        WinapiErrnoException(isolate, GetLastError(), "WaitForSingleObject"));
398
    return;
399
  }
400
}
401
#endif  // _WIN32
402
403
5
static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
404
#if HAVE_INSPECTOR
405
5
  Environment* env = Environment::GetCurrent(args);
406
5
  if (env->inspector_agent()->IsListening()) {
407
4
    env->inspector_agent()->Stop();
408
  }
409
#endif
410
5
}
411
412
421
static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
413
421
  Environment* env = Environment::GetCurrent(args);
414
421
  RunAtExit(env);
415
421
  int code = args[0]->Int32Value(env->context()).FromMaybe(0);
416
421
  env->Exit(code);
417
71
}
418
419
namespace process {
420
421
constexpr FastStringKey BindingData::type_name;
422
423
5494
BindingData::BindingData(Environment* env, v8::Local<v8::Object> object)
424
5494
    : SnapshotableObject(env, object, type_int) {
425
5494
  Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), kBufferSize);
426
5494
  array_buffer_.Reset(env->isolate(), ab);
427
  object
428
5494
      ->Set(env->context(),
429
            FIXED_ONE_BYTE_STRING(env->isolate(), "hrtimeBuffer"),
430
16482
            ab)
431
      .ToChecked();
432
5494
  backing_store_ = ab->GetBackingStore();
433
5494
}
434
435
v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
436
v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
437
438
617
void BindingData::AddMethods() {
439
617
  env()->SetFastMethod(object(), "hrtime", SlowNumber, &fast_number_);
440
617
  env()->SetFastMethod(object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
441
617
}
442
443
4883
void BindingData::RegisterExternalReferences(
444
    ExternalReferenceRegistry* registry) {
445
4883
  registry->Register(SlowNumber);
446
4883
  registry->Register(SlowBigInt);
447
4883
  registry->Register(FastNumber);
448
4883
  registry->Register(FastBigInt);
449
4883
  registry->Register(fast_number_.GetTypeInfo());
450
4883
  registry->Register(fast_bigint_.GetTypeInfo());
451
4883
}
452
453
BindingData* BindingData::FromV8Value(Local<Value> value) {
454
  Local<Object> v8_object = value.As<Object>();
455
  return static_cast<BindingData*>(
456
      v8_object->GetAlignedPointerFromInternalField(BaseObject::kSlot));
457
}
458
459
22
void BindingData::MemoryInfo(MemoryTracker* tracker) const {
460
22
  tracker->TrackField("array_buffer", array_buffer_);
461
22
}
462
463
// This is the legacy version of hrtime before BigInt was introduced in
464
// JavaScript.
465
// The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
466
// so this function instead fills in an Uint32Array with 3 entries,
467
// to avoid any integer overflow possibility.
468
// The first two entries contain the second part of the value
469
// broken into the upper/lower 32 bits to be converted back in JS,
470
// because there is no Uint64Array in JS.
471
// The third entry contains the remaining nanosecond part of the value.
472
193266
void BindingData::NumberImpl(BindingData* receiver) {
473
  // Make sure we don't accidentally access buffers wiped for snapshot.
474
193266
  CHECK(!receiver->array_buffer_.IsEmpty());
475
193266
  uint64_t t = uv_hrtime();
476
193266
  uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
477
193266
  fields[0] = (t / NANOS_PER_SEC) >> 32;
478
193266
  fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
479
193266
  fields[2] = t % NANOS_PER_SEC;
480
193266
}
481
482
238023
void BindingData::BigIntImpl(BindingData* receiver) {
483
  // Make sure we don't accidentally access buffers wiped for snapshot.
484
238023
  CHECK(!receiver->array_buffer_.IsEmpty());
485
238023
  uint64_t t = uv_hrtime();
486
238023
  uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
487
238023
  fields[0] = t;
488
238023
}
489
490
238023
void BindingData::SlowBigInt(const FunctionCallbackInfo<Value>& args) {
491
238023
  BigIntImpl(FromJSObject<BindingData>(args.Holder()));
492
238023
}
493
494
193266
void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
495
193266
  NumberImpl(FromJSObject<BindingData>(args.Holder()));
496
193266
}
497
498
6
void BindingData::PrepareForSerialization(Local<Context> context,
499
                                          v8::SnapshotCreator* creator) {
500
  // It's not worth keeping.
501
  // Release it, we will recreate it when the instance is dehydrated.
502
6
  array_buffer_.Reset();
503
6
}
504
505
6
InternalFieldInfo* BindingData::Serialize(int index) {
506
  DCHECK_EQ(index, BaseObject::kSlot);
507
6
  InternalFieldInfo* info = InternalFieldInfo::New(type());
508
6
  return info;
509
}
510
511
4877
void BindingData::Deserialize(Local<Context> context,
512
                              Local<Object> holder,
513
                              int index,
514
                              InternalFieldInfo* info) {
515
  DCHECK_EQ(index, BaseObject::kSlot);
516
9754
  v8::HandleScope scope(context->GetIsolate());
517
4877
  Environment* env = Environment::GetCurrent(context);
518
  // Recreate the buffer in the constructor.
519
4877
  BindingData* binding = env->AddBindingData<BindingData>(context, holder);
520
4877
  CHECK_NOT_NULL(binding);
521
4877
}
522
523
617
static void Initialize(Local<Object> target,
524
                       Local<Value> unused,
525
                       Local<Context> context,
526
                       void* priv) {
527
617
  Environment* env = Environment::GetCurrent(context);
528
  BindingData* const binding_data =
529
617
      env->AddBindingData<BindingData>(context, target);
530
617
  if (binding_data == nullptr) return;
531
617
  binding_data->AddMethods();
532
533
  // define various internal methods
534
617
  if (env->owns_process_state()) {
535
52
    env->SetMethod(target, "_debugProcess", DebugProcess);
536
52
    env->SetMethod(target, "_debugEnd", DebugEnd);
537
52
    env->SetMethod(target, "abort", Abort);
538
52
    env->SetMethod(target, "causeSegfault", CauseSegfault);
539
52
    env->SetMethod(target, "chdir", Chdir);
540
  }
541
542
617
  env->SetMethod(target, "umask", Umask);
543
617
  env->SetMethod(target, "_rawDebug", RawDebug);
544
617
  env->SetMethod(target, "memoryUsage", MemoryUsage);
545
617
  env->SetMethod(target, "rss", Rss);
546
617
  env->SetMethod(target, "cpuUsage", CPUUsage);
547
617
  env->SetMethod(target, "resourceUsage", ResourceUsage);
548
549
617
  env->SetMethod(target, "_getActiveRequests", GetActiveRequests);
550
617
  env->SetMethod(target, "_getActiveHandles", GetActiveHandles);
551
617
  env->SetMethod(target, "_kill", Kill);
552
553
617
  env->SetMethodNoSideEffect(target, "cwd", Cwd);
554
617
  env->SetMethod(target, "dlopen", binding::DLOpen);
555
617
  env->SetMethod(target, "reallyExit", ReallyExit);
556
617
  env->SetMethodNoSideEffect(target, "uptime", Uptime);
557
617
  env->SetMethod(target, "patchProcessObject", PatchProcessObject);
558
}
559
560
4883
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
561
4883
  BindingData::RegisterExternalReferences(registry);
562
563
4883
  registry->Register(DebugProcess);
564
4883
  registry->Register(DebugEnd);
565
4883
  registry->Register(Abort);
566
4883
  registry->Register(CauseSegfault);
567
4883
  registry->Register(Chdir);
568
569
4883
  registry->Register(Umask);
570
4883
  registry->Register(RawDebug);
571
4883
  registry->Register(MemoryUsage);
572
4883
  registry->Register(Rss);
573
4883
  registry->Register(CPUUsage);
574
4883
  registry->Register(ResourceUsage);
575
576
4883
  registry->Register(GetActiveRequests);
577
4883
  registry->Register(GetActiveHandles);
578
4883
  registry->Register(Kill);
579
580
4883
  registry->Register(Cwd);
581
4883
  registry->Register(binding::DLOpen);
582
4883
  registry->Register(ReallyExit);
583
4883
  registry->Register(Uptime);
584
4883
  registry->Register(PatchProcessObject);
585
4883
}
586
587
}  // namespace process
588
}  // namespace node
589
590
4944
NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods, node::process::Initialize)
591
4883
NODE_MODULE_EXTERNAL_REFERENCE(process_methods,
592
                               node::process::RegisterExternalReferences)