GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/env.cc Lines: 53 72 73.6 %
Date: 2016-07-12 Branches: 8 12 66.7 %

Line 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
using v8::Value;
25
26
1554
void Environment::Start(int argc,
27
                        const char* const* argv,
28
                        int exec_argc,
29
                        const char* const* exec_argv,
30
                        bool start_profiler_idle_notifier) {
31
3108
  HandleScope handle_scope(isolate());
32
4662
  Context::Scope context_scope(context());
33
34
1554
  isolate()->SetAutorunMicrotasks(false);
35
36
3108
  uv_check_init(event_loop(), immediate_check_handle());
37
1554
  uv_unref(reinterpret_cast<uv_handle_t*>(immediate_check_handle()));
38
39
3108
  uv_idle_init(event_loop(), immediate_idle_handle());
40
41
  // Inform V8's CPU profiler when we're idle.  The profiler is sampling-based
42
  // but not all samples are created equal; mark the wall clock time spent in
43
  // epoll_wait() and friends so profiling tools can filter it out.  The samples
44
  // still end up in v8.log but with state=IDLE rather than state=EXTERNAL.
45
  // TODO(bnoordhuis) Depends on a libuv implementation detail that we should
46
  // probably fortify in the API contract, namely that the last started prepare
47
  // or check watcher runs first.  It's not 100% foolproof; if an add-on starts
48
  // a prepare or check watcher after us, any samples attributed to its callback
49
  // will be recorded with state=IDLE.
50
3108
  uv_prepare_init(event_loop(), &idle_prepare_handle_);
51
3108
  uv_check_init(event_loop(), &idle_check_handle_);
52
1554
  uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
53
1554
  uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
54
55
5440
  auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) {
56
5440
    handle->data = env;
57
58
5440
    uv_close(handle, [](uv_handle_t* handle) {
59
5440
      static_cast<Environment*>(handle->data)->FinishHandleCleanup(handle);
60
16320
    });
61
10880
  };
62
63
1554
  RegisterHandleCleanup(
64
1554
      reinterpret_cast<uv_handle_t*>(immediate_check_handle()),
65
      close_and_finish,
66
1554
      nullptr);
67
1554
  RegisterHandleCleanup(
68
1554
      reinterpret_cast<uv_handle_t*>(immediate_idle_handle()),
69
      close_and_finish,
70
1554
      nullptr);
71
1554
  RegisterHandleCleanup(
72
      reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_),
73
      close_and_finish,
74
1554
      nullptr);
75
1554
  RegisterHandleCleanup(
76
      reinterpret_cast<uv_handle_t*>(&idle_check_handle_),
77
      close_and_finish,
78
1554
      nullptr);
79
80
1554
  if (start_profiler_idle_notifier) {
81
    StartProfilerIdleNotifier();
82
  }
83
84
3108
  auto process_template = FunctionTemplate::New(isolate());
85
1554
  process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate(), "process"));
86
87
  auto process_object =
88
6216
      process_template->GetFunction()->NewInstance(context()).ToLocalChecked();
89
1554
  set_process_object(process_object);
90
91
1554
  SetupProcessObject(this, argc, argv, exec_argc, exec_argv);
92
1554
  LoadAsyncWrapperInfo(this);
93
1554
}
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
71954
void Environment::PrintSyncTrace() const {
113
71954
  if (!trace_sync_io_)
114
71946
    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