GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_report_utils.cc Lines: 118 141 83.7 %
Date: 2019-02-26 22:23:30 Branches: 56 86 65.1 %

Line Branch Exec Source
1
#include "node_internals.h"
2
#include "node_report.h"
3
4
namespace report {
5
6
using node::MallocedBuffer;
7
8
static constexpr auto null = JSONWriter::Null{};
9
10
// Utility function to format libuv socket information.
11
4
static void ReportEndpoints(uv_handle_t* h, JSONWriter* writer) {
12
  struct sockaddr_storage addr_storage;
13
4
  struct sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
14
4
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
15
4
  int addr_size = sizeof(addr_storage);
16
4
  int rc = -1;
17
4
  bool wrote_local_endpoint = false;
18
4
  bool wrote_remote_endpoint = false;
19
20
4
  switch (h->type) {
21
    case UV_UDP:
22
1
      rc = uv_udp_getsockname(&handle->udp, addr, &addr_size);
23
1
      break;
24
    case UV_TCP:
25
3
      rc = uv_tcp_getsockname(&handle->tcp, addr, &addr_size);
26
3
      break;
27
    default:
28
      break;
29
  }
30
4
  if (rc == 0) {
31
    // uv_getnameinfo will format host and port and handle IPv4/IPv6.
32
    uv_getnameinfo_t local;
33
4
    rc = uv_getnameinfo(h->loop, &local, nullptr, addr, NI_NUMERICSERV);
34
35
4
    if (rc == 0) {
36
4
      writer->json_objectstart("localEndpoint");
37
4
      writer->json_keyvalue("host", local.host);
38
4
      writer->json_keyvalue("port", local.service);
39
4
      writer->json_objectend();
40
4
      wrote_local_endpoint = true;
41
    }
42
  }
43
4
  if (!wrote_local_endpoint) writer->json_keyvalue("localEndpoint", null);
44
45
4
  if (h->type == UV_TCP) {
46
    // Get the remote end of the connection.
47
3
    rc = uv_tcp_getpeername(&handle->tcp, addr, &addr_size);
48
3
    if (rc == 0) {
49
      uv_getnameinfo_t remote;
50
2
      rc = uv_getnameinfo(h->loop, &remote, nullptr, addr, NI_NUMERICSERV);
51
52
2
      if (rc == 0) {
53
2
        writer->json_objectstart("remoteEndpoint");
54
2
        writer->json_keyvalue("host", remote.host);
55
2
        writer->json_keyvalue("port", remote.service);
56
2
        writer->json_objectend();
57
2
        wrote_local_endpoint = true;
58
      }
59
    }
60
  }
61
4
  if (!wrote_remote_endpoint) writer->json_keyvalue("remoteEndpoint", null);
62
4
}
63
64
// Utility function to format libuv path information.
65
2
static void ReportPath(uv_handle_t* h, JSONWriter* writer) {
66
2
  MallocedBuffer<char> buffer(0);
67
2
  int rc = -1;
68
2
  size_t size = 0;
69
2
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
70
2
  bool wrote_filename = false;
71
  // First call to get required buffer size.
72
2
  switch (h->type) {
73
    case UV_FS_EVENT:
74
1
      rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
75
1
      break;
76
    case UV_FS_POLL:
77
1
      rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
78
1
      break;
79
    default:
80
      break;
81
  }
82
2
  if (rc == UV_ENOBUFS) {
83
2
    buffer = MallocedBuffer<char>(size + 1);
84
2
    switch (h->type) {
85
      case UV_FS_EVENT:
86
1
        rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
87
1
        break;
88
      case UV_FS_POLL:
89
1
        rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
90
1
        break;
91
      default:
92
        break;
93
    }
94
2
    if (rc == 0) {
95
      // buffer is not null terminated.
96
2
      buffer.data[size] = '\0';
97
2
      writer->json_keyvalue("filename", buffer.data);
98
2
      wrote_filename = true;
99
    }
100
  }
101
2
  if (!wrote_filename) writer->json_keyvalue("filename", null);
102
2
}
103
104
// Utility function to walk libuv handles.
105
81
void WalkHandle(uv_handle_t* h, void* arg) {
106
81
  const char* type = uv_handle_type_name(h->type);
107
81
  JSONWriter* writer = static_cast<JSONWriter*>(arg);
108
81
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
109
110
81
  writer->json_start();
111
112

81
  switch (h->type) {
113
    case UV_FS_EVENT:
114
    case UV_FS_POLL:
115
2
      ReportPath(h, writer);
116
2
      break;
117
    case UV_PROCESS:
118
1
      writer->json_keyvalue("pid", handle->process.pid);
119
1
      break;
120
    case UV_TCP:
121
    case UV_UDP:
122
4
      ReportEndpoints(h, writer);
123
4
      break;
124
    case UV_TIMER: {
125
10
      uint64_t due = handle->timer.timeout;
126
10
      uint64_t now = uv_now(handle->timer.loop);
127
10
      writer->json_keyvalue("repeat", uv_timer_get_repeat(&handle->timer));
128
      writer->json_keyvalue("firesInMsFromNow",
129
10
                            static_cast<int64_t>(due - now));
130
10
      writer->json_keyvalue("expired", now >= due);
131
10
      break;
132
    }
133
    case UV_TTY: {
134
      int height, width, rc;
135
      rc = uv_tty_get_winsize(&(handle->tty), &width, &height);
136
      if (rc == 0) {
137
        writer->json_keyvalue("width", width);
138
        writer->json_keyvalue("height", height);
139
      }
140
      break;
141
    }
142
    case UV_SIGNAL:
143
      // SIGWINCH is used by libuv so always appears.
144
      // See http://docs.libuv.org/en/v1.x/signal.html
145
      writer->json_keyvalue("signum", handle->signal.signum);
146
      writer->json_keyvalue("signal",
147
                            node::signo_string(handle->signal.signum));
148
      break;
149
    default:
150
64
      break;
151
  }
152
153

81
  if (h->type == UV_TCP || h->type == UV_UDP
154
#ifndef _WIN32
155
77
      || h->type == UV_NAMED_PIPE
156
#endif
157
  ) {
158
    // These *must* be 0 or libuv will set the buffer sizes to the non-zero
159
    // values they contain.
160
8
    int send_size = 0;
161
8
    int recv_size = 0;
162
8
    uv_send_buffer_size(h, &send_size);
163
8
    uv_recv_buffer_size(h, &recv_size);
164
8
    writer->json_keyvalue("sendBufferSize", send_size);
165
8
    writer->json_keyvalue("recvBufferSize", recv_size);
166
  }
167
168
#ifndef _WIN32
169


155
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY ||
170
147
      h->type == UV_UDP || h->type == UV_POLL) {
171
    uv_os_fd_t fd_v;
172
8
    int rc = uv_fileno(h, &fd_v);
173
174
8
    if (rc == 0) {
175
8
      writer->json_keyvalue("fd", static_cast<int>(fd_v));
176

8
      switch (fd_v) {
177
        case 0:
178
          writer->json_keyvalue("stdio", "stdin");
179
          break;
180
        case 1:
181
          writer->json_keyvalue("stdio", "stdout");
182
          break;
183
        case 2:
184
          writer->json_keyvalue("stdio", "stderr");
185
          break;
186
      }
187
    }
188
  }
189
#endif
190
191

81
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY) {
192
7
    writer->json_keyvalue("writeQueueSize", handle->stream.write_queue_size);
193
    writer->json_keyvalue("readable",
194
7
                          static_cast<bool>(uv_is_readable(&handle->stream)));
195
    writer->json_keyvalue("writable",
196
7
                          static_cast<bool>(uv_is_writable(&handle->stream)));
197
  }
198
199
81
  writer->json_keyvalue("type", type);
200
81
  writer->json_keyvalue("is_active", static_cast<bool>(uv_is_active(h)));
201
81
  writer->json_keyvalue("is_referenced", static_cast<bool>(uv_has_ref(h)));
202
  writer->json_keyvalue("address",
203
81
                        ValueToHexString(reinterpret_cast<uint64_t>(h)));
204
81
  writer->json_end();
205
81
}
206
207
4263
std::string EscapeJsonChars(const std::string& str) {
208
  const std::string control_symbols[0x20] = {
209
      "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
210
      "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
211
      "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
212
      "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
213
      "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
214
140679
  };
215
216
4263
  std::string ret = "";
217
4263
  size_t last_pos = 0;
218
4263
  size_t pos = 0;
219
69876
  for (; pos < str.size(); ++pos) {
220
65613
    std::string replace;
221
65613
    char ch = str[pos];
222
65613
    if (ch == '\\') {
223
      replace = "\\\\";
224
65613
    } else if (ch == '\"') {
225
      replace = "\\\"";
226
    } else {
227
65613
      size_t num = static_cast<size_t>(ch);
228
65613
      if (num < 0x20) replace = control_symbols[num];
229
    }
230
65613
    if (!replace.empty()) {
231
      if (pos > last_pos) {
232
        ret += str.substr(last_pos, pos - last_pos);
233
      }
234
      last_pos = pos + 1;
235
      ret += replace;
236
    }
237
65613
  }
238
  // Append any remaining symbols.
239
4263
  if (last_pos < str.size()) {
240
4253
    ret += str.substr(last_pos, pos - last_pos);
241
  }
242
140679
  return ret;
243
}
244
245

12846
}  // namespace report