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