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-13 22:28:58 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
59
void WalkHandle(uv_handle_t* h, void* arg) {
106
59
  const char* type = uv_handle_type_name(h->type);
107
59
  JSONWriter* writer = static_cast<JSONWriter*>(arg);
108
59
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
109
110
59
  writer->json_start();
111
112

59
  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
6
      uint64_t due = handle->timer.timeout;
126
6
      uint64_t now = uv_now(handle->timer.loop);
127
6
      writer->json_keyvalue("repeat", uv_timer_get_repeat(&handle->timer));
128
      writer->json_keyvalue("firesInMsFromNow",
129
6
                            static_cast<int64_t>(due - now));
130
6
      writer->json_keyvalue("expired", now >= due);
131
6
      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
46
      break;
151
  }
152
153

59
  if (h->type == UV_TCP || h->type == UV_UDP
154
#ifndef _WIN32
155
55
      || 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


111
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY ||
170
103
      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

59
  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
59
  writer->json_keyvalue("type", type);
200
59
  writer->json_keyvalue("is_active", static_cast<bool>(uv_is_active(h)));
201
59
  writer->json_keyvalue("is_referenced", static_cast<bool>(uv_has_ref(h)));
202
  writer->json_keyvalue("address",
203
59
                        ValueToHexString(reinterpret_cast<uint64_t>(h)));
204
59
  writer->json_end();
205
59
}
206
207
2662
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
87846
  };
215
216
2662
  std::string ret = "";
217
2662
  size_t last_pos = 0;
218
2662
  size_t pos = 0;
219
46794
  for (; pos < str.size(); ++pos) {
220
44132
    std::string replace;
221
44132
    char ch = str[pos];
222
44132
    if (ch == '\\') {
223
      replace = "\\\\";
224
44132
    } else if (ch == '\"') {
225
      replace = "\\\"";
226
    } else {
227
44132
      size_t num = static_cast<size_t>(ch);
228
44132
      if (num < 0x20) replace = control_symbols[num];
229
    }
230
44132
    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
44132
  }
238
  // Append any remaining symbols.
239
2662
  if (last_pos < str.size()) {
240
2656
    ret += str.substr(last_pos, pos - last_pos);
241
  }
242
87846
  return ret;
243
}
244
245

12942
}  // namespace report