GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/env.cc Lines: 53 68 77.9 %
Date: 2016-09-05 Branches: 8 12 66.7 %

Line Branch Exec Source
1
#include "env.h"
2
#include "env-inl.h"
3
#include "async-wrap.h"
4
#include "v8.h"
5
#include "v8-profiler.h"
6
7
#if defined(_MSC_VER)
8
#define getpid GetCurrentProcessId
9
#else
10
#include <unistd.h>
11
#endif
12
13
#include <stdio.h>
14
15
namespace node {
16
17
using v8::Context;
18
using v8::FunctionTemplate;
19
using v8::HandleScope;
20
using v8::Local;
21
using v8::Message;
22
using v8::StackFrame;
23
using v8::StackTrace;
24
25
1626
void Environment::Start(int argc,
26
                        const char* const* argv,
27
                        int exec_argc,
28
                        const char* const* exec_argv,
29
                        bool start_profiler_idle_notifier) {
30
3252
  HandleScope handle_scope(isolate());
31
4878
  Context::Scope context_scope(context());
32
33
1626
  isolate()->SetAutorunMicrotasks(false);
34
35
3252
  uv_check_init(event_loop(), immediate_check_handle());
36
1626
  uv_unref(reinterpret_cast<uv_handle_t*>(immediate_check_handle()));
37
38
3252
  uv_idle_init(event_loop(), immediate_idle_handle());
39
40
  // Inform V8's CPU profiler when we're idle.  The profiler is sampling-based
41
  // but not all samples are created equal; mark the wall clock time spent in
42
  // epoll_wait() and friends so profiling tools can filter it out.  The samples
43
  // still end up in v8.log but with state=IDLE rather than state=EXTERNAL.
44
  // TODO(bnoordhuis) Depends on a libuv implementation detail that we should
45
  // probably fortify in the API contract, namely that the last started prepare
46
  // or check watcher runs first.  It's not 100% foolproof; if an add-on starts
47
  // a prepare or check watcher after us, any samples attributed to its callback
48
  // will be recorded with state=IDLE.
49
3252
  uv_prepare_init(event_loop(), &idle_prepare_handle_);
50
3252
  uv_check_init(event_loop(), &idle_check_handle_);
51
1626
  uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
52
1626
  uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
53
54
5724
  auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) {
55
5724
    handle->data = env;
56
57
5724
    uv_close(handle, [](uv_handle_t* handle) {
58
5724
      static_cast<Environment*>(handle->data)->FinishHandleCleanup(handle);
59
17172
    });
60
11448
  };
61
62
1626
  RegisterHandleCleanup(
63
1626
      reinterpret_cast<uv_handle_t*>(immediate_check_handle()),
64
      close_and_finish,
65
1626
      nullptr);
66
1626
  RegisterHandleCleanup(
67
1626
      reinterpret_cast<uv_handle_t*>(immediate_idle_handle()),
68
      close_and_finish,
69
1626
      nullptr);
70
1626
  RegisterHandleCleanup(
71
      reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_),
72
      close_and_finish,
73
1626
      nullptr);
74
1626
  RegisterHandleCleanup(
75
      reinterpret_cast<uv_handle_t*>(&idle_check_handle_),
76
      close_and_finish,
77
1626
      nullptr);
78
79
1626
  if (start_profiler_idle_notifier) {
80
    StartProfilerIdleNotifier();
81
  }
82
83
3252
  auto process_template = FunctionTemplate::New(isolate());
84
1626
  process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate(), "process"));
85
86
  auto process_object =
87
6504
      process_template->GetFunction()->NewInstance(context()).ToLocalChecked();
88
1626
  set_process_object(process_object);
89
90
1626
  SetupProcessObject(this, argc, argv, exec_argc, exec_argv);
91
1626
  LoadAsyncWrapperInfo(this);
92
1626
}
93
94
void Environment::StartProfilerIdleNotifier() {
95
  uv_prepare_start(&idle_prepare_handle_, [](uv_prepare_t* handle) {
96
    Environment* env = ContainerOf(&Environment::idle_prepare_handle_, handle);
97
    env->isolate()->GetCpuProfiler()->SetIdle(true);
98
  });
99
100
  uv_check_start(&idle_check_handle_, [](uv_check_t* handle) {
101
    Environment* env = ContainerOf(&Environment::idle_check_handle_, handle);
102
    env->isolate()->GetCpuProfiler()->SetIdle(false);
103
  });
104
}
105
106
void Environment::StopProfilerIdleNotifier() {
107
  uv_prepare_stop(&idle_prepare_handle_);
108
  uv_check_stop(&idle_check_handle_);
109
}
110
111
147820
void Environment::PrintSyncTrace() const {
112
147820
  if (!trace_sync_io_)
113
147812
    return;
114
115
16
  HandleScope handle_scope(isolate());
116
  Local<v8::StackTrace> stack =
117
8
      StackTrace::CurrentStackTrace(isolate(), 10, StackTrace::kDetailed);
118
119
16
  fprintf(stderr, "(node:%d) WARNING: Detected use of sync API\n", getpid());
120
121
65
  for (int i = 0; i < stack->GetFrameCount() - 1; i++) {
122
57
    Local<StackFrame> stack_frame = stack->GetFrame(i);
123
171
    node::Utf8Value fn_name_s(isolate(), stack_frame->GetFunctionName());
124
171
    node::Utf8Value script_name(isolate(), stack_frame->GetScriptName());
125
57
    const int line_number = stack_frame->GetLineNumber();
126
57
    const int column = stack_frame->GetColumn();
127
128
57
    if (stack_frame->IsEval()) {
129
      if (stack_frame->GetScriptId() == Message::kNoScriptIdInfo) {
130
        fprintf(stderr, "    at [eval]:%i:%i\n", line_number, column);
131
      } else {
132
        fprintf(stderr,
133
                "    at [eval] (%s:%i:%i)\n",
134
                *script_name,
135
                line_number,
136
                column);
137
      }
138
      break;
139
    }
140
141
57
    if (fn_name_s.length() == 0) {
142
8
      fprintf(stderr, "    at %s:%i:%i\n", *script_name, line_number, column);
143
    } else {
144
49
      fprintf(stderr,
145
              "    at %s (%s:%i:%i)\n",
146
              *fn_name_s,
147
              *script_name,
148
              line_number,
149
49
              column);
150
    }
151
  }
152
8
  fflush(stderr);
153
}
154
155
}  // namespace node