GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_process_methods.cc Lines: 255 274 93.1 %
Date: 2021-09-20 04:12:42 Branches: 61 92 66.3 %

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::BackingStore;
40
using v8::CFunction;
41
using v8::ConstructorBehavior;
42
using v8::Context;
43
using v8::Float64Array;
44
using v8::FunctionCallbackInfo;
45
using v8::FunctionTemplate;
46
using v8::Global;
47
using v8::HeapStatistics;
48
using v8::Integer;
49
using v8::Isolate;
50
using v8::Local;
51
using v8::NewStringType;
52
using v8::Number;
53
using v8::Object;
54
using v8::ObjectTemplate;
55
using v8::SideEffectType;
56
using v8::Signature;
57
using v8::String;
58
using v8::Uint32;
59
using v8::Value;
60
61
namespace per_process {
62
Mutex umask_mutex;
63
}   // namespace per_process
64
65
// Microseconds in a second, as a float, used in CPUUsage() below
66
#define MICROS_PER_SEC 1e6
67
// used in Hrtime() and Uptime() below
68
#define NANOS_PER_SEC 1000000000
69
70
static void Abort(const FunctionCallbackInfo<Value>& args) {
71
  Abort();
72
}
73
74
// For internal testing only, not exposed to userland.
75
static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
76
  // This should crash hard all platforms.
77
  volatile void** d = static_cast<volatile void**>(nullptr);
78
  *d = nullptr;
79
}
80
81
451
static void Chdir(const FunctionCallbackInfo<Value>& args) {
82
451
  Environment* env = Environment::GetCurrent(args);
83
451
  CHECK(env->owns_process_state());
84
85
451
  CHECK_EQ(args.Length(), 1);
86
902
  CHECK(args[0]->IsString());
87
451
  Utf8Value path(env->isolate(), args[0]);
88
451
  int err = uv_chdir(*path);
89
451
  if (err) {
90
    // Also include the original working directory, since that will usually
91
    // be helpful information when debugging a `chdir()` failure.
92
    char buf[PATH_MAX_BYTES];
93
1
    size_t cwd_len = sizeof(buf);
94
1
    uv_cwd(buf, &cwd_len);
95
1
    return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
96
  }
97
}
98
99
556
inline Local<ArrayBuffer> get_fields_array_buffer(
100
    const FunctionCallbackInfo<Value>& args,
101
    size_t index,
102
    size_t array_length) {
103

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



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


66
  CHECK(args.Length() == 1 && args[0]->IsString() &&
217
        "must be called with a single string");
218
44
  Utf8Value message(args.GetIsolate(), args[0]);
219
22
  FPrintF(stderr, "%s\n", message);
220
22
  fflush(stderr);
221
22
}
222
223
4087
static void Umask(const FunctionCallbackInfo<Value>& args) {
224
4087
  Environment* env = Environment::GetCurrent(args);
225
4087
  CHECK(env->has_run_bootstrapping_code());
226
4087
  CHECK_EQ(args.Length(), 1);
227

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