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: 1 122 0.8 %
Date: 2021-02-19 04:08:54 Branches: 2 75 2.7 %

Line Branch Exec Source
1
#include "json_utils.h"
2
#include "node_internals.h"
3
#include "node_report.h"
4
#include "util-inl.h"
5
6
namespace report {
7
8
using node::JSONWriter;
9
using node::MallocedBuffer;
10
11
static constexpr auto null = JSONWriter::Null{};
12
13
// Utility function to format socket information.
14
static void ReportEndpoint(uv_handle_t* h,
15
                           struct sockaddr* addr,
16
                           const char* name,
17
                           JSONWriter* writer) {
18
  if (addr == nullptr) {
19
    writer->json_keyvalue(name, null);
20
    return;
21
  }
22
23
  uv_getnameinfo_t endpoint;
24
  char* host = nullptr;
25
  char hostbuf[INET6_ADDRSTRLEN];
26
  const int family = addr->sa_family;
27
  const int port = ntohs(family == AF_INET ?
28
                         reinterpret_cast<sockaddr_in*>(addr)->sin_port :
29
                         reinterpret_cast<sockaddr_in6*>(addr)->sin6_port);
30
31
  if (uv_getnameinfo(h->loop, &endpoint, nullptr, addr, NI_NUMERICSERV) == 0) {
32
    host = endpoint.host;
33
    DCHECK_EQ(port, std::stoi(endpoint.service));
34
  } else {
35
    const void* src = family == AF_INET ?
36
                      static_cast<void*>(
37
                        &(reinterpret_cast<sockaddr_in*>(addr)->sin_addr)) :
38
                      static_cast<void*>(
39
                        &(reinterpret_cast<sockaddr_in6*>(addr)->sin6_addr));
40
    if (uv_inet_ntop(family, src, hostbuf, sizeof(hostbuf)) == 0) {
41
      host = hostbuf;
42
    }
43
  }
44
  writer->json_objectstart(name);
45
  if (host != nullptr) {
46
    writer->json_keyvalue("host", host);
47
  }
48
  writer->json_keyvalue("port", port);
49
  writer->json_objectend();
50
}
51
52
// Utility function to format libuv socket information.
53
static void ReportEndpoints(uv_handle_t* h, JSONWriter* writer) {
54
  struct sockaddr_storage addr_storage;
55
  struct sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
56
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
57
  int addr_size = sizeof(addr_storage);
58
  int rc = -1;
59
60
  switch (h->type) {
61
    case UV_UDP:
62
      rc = uv_udp_getsockname(&handle->udp, addr, &addr_size);
63
      break;
64
    case UV_TCP:
65
      rc = uv_tcp_getsockname(&handle->tcp, addr, &addr_size);
66
      break;
67
    default:
68
      break;
69
  }
70
  ReportEndpoint(h, rc == 0 ? addr : nullptr,  "localEndpoint", writer);
71
72
  switch (h->type) {
73
    case UV_UDP:
74
      rc = uv_udp_getpeername(&handle->udp, addr, &addr_size);
75
      break;
76
    case UV_TCP:
77
      rc = uv_tcp_getpeername(&handle->tcp, addr, &addr_size);
78
      break;
79
    default:
80
      break;
81
  }
82
  ReportEndpoint(h, rc == 0 ? addr : nullptr, "remoteEndpoint", writer);
83
}
84
85
// Utility function to format libuv path information.
86
static void ReportPath(uv_handle_t* h, JSONWriter* writer) {
87
  MallocedBuffer<char> buffer(0);
88
  int rc = -1;
89
  size_t size = 0;
90
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
91
  bool wrote_filename = false;
92
  // First call to get required buffer size.
93
  switch (h->type) {
94
    case UV_FS_EVENT:
95
      rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
96
      break;
97
    case UV_FS_POLL:
98
      rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
99
      break;
100
    default:
101
      break;
102
  }
103
  if (rc == UV_ENOBUFS) {
104
    buffer = MallocedBuffer<char>(size + 1);
105
    switch (h->type) {
106
      case UV_FS_EVENT:
107
        rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
108
        break;
109
      case UV_FS_POLL:
110
        rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
111
        break;
112
      default:
113
        break;
114
    }
115
    if (rc == 0) {
116
      // buffer is not null terminated.
117
      buffer.data[size] = '\0';
118
      writer->json_keyvalue("filename", buffer.data);
119
      wrote_filename = true;
120
    }
121
  }
122
  if (!wrote_filename) writer->json_keyvalue("filename", null);
123
}
124
125
// Utility function to walk libuv handles.
126
void WalkHandle(uv_handle_t* h, void* arg) {
127
  const char* type = uv_handle_type_name(h->type);
128
  JSONWriter* writer = static_cast<JSONWriter*>(arg);
129
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
130
131
  writer->json_start();
132
  writer->json_keyvalue("type", type);
133
  writer->json_keyvalue("is_active", static_cast<bool>(uv_is_active(h)));
134
  writer->json_keyvalue("is_referenced", static_cast<bool>(uv_has_ref(h)));
135
  writer->json_keyvalue("address",
136
                        ValueToHexString(reinterpret_cast<uint64_t>(h)));
137
138
  switch (h->type) {
139
    case UV_FS_EVENT:
140
    case UV_FS_POLL:
141
      ReportPath(h, writer);
142
      break;
143
    case UV_PROCESS:
144
      writer->json_keyvalue("pid", handle->process.pid);
145
      break;
146
    case UV_TCP:
147
    case UV_UDP:
148
      ReportEndpoints(h, writer);
149
      break;
150
    case UV_TIMER: {
151
      uint64_t due = handle->timer.timeout;
152
      uint64_t now = uv_now(handle->timer.loop);
153
      writer->json_keyvalue("repeat", uv_timer_get_repeat(&handle->timer));
154
      writer->json_keyvalue("firesInMsFromNow",
155
                            static_cast<int64_t>(due - now));
156
      writer->json_keyvalue("expired", now >= due);
157
      break;
158
    }
159
    case UV_TTY: {
160
      int height, width, rc;
161
      rc = uv_tty_get_winsize(&(handle->tty), &width, &height);
162
      if (rc == 0) {
163
        writer->json_keyvalue("width", width);
164
        writer->json_keyvalue("height", height);
165
      }
166
      break;
167
    }
168
    case UV_SIGNAL:
169
      // SIGWINCH is used by libuv so always appears.
170
      // See http://docs.libuv.org/en/v1.x/signal.html
171
      writer->json_keyvalue("signum", handle->signal.signum);
172
      writer->json_keyvalue("signal",
173
                            node::signo_string(handle->signal.signum));
174
      break;
175
    default:
176
      break;
177
  }
178
179
  if (h->type == UV_TCP || h->type == UV_UDP
180
#ifndef _WIN32
181
      || h->type == UV_NAMED_PIPE
182
#endif
183
  ) {
184
    // These *must* be 0 or libuv will set the buffer sizes to the non-zero
185
    // values they contain.
186
    int send_size = 0;
187
    int recv_size = 0;
188
    uv_send_buffer_size(h, &send_size);
189
    uv_recv_buffer_size(h, &recv_size);
190
    writer->json_keyvalue("sendBufferSize", send_size);
191
    writer->json_keyvalue("recvBufferSize", recv_size);
192
  }
193
194
#ifndef _WIN32
195
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY ||
196
      h->type == UV_UDP || h->type == UV_POLL) {
197
    uv_os_fd_t fd_v;
198
    int rc = uv_fileno(h, &fd_v);
199
200
    if (rc == 0) {
201
      writer->json_keyvalue("fd", static_cast<int>(fd_v));
202
      switch (fd_v) {
203
        case STDIN_FILENO:
204
          writer->json_keyvalue("stdio", "stdin");
205
          break;
206
        case STDOUT_FILENO:
207
          writer->json_keyvalue("stdio", "stdout");
208
          break;
209
        case STDERR_FILENO:
210
          writer->json_keyvalue("stdio", "stderr");
211
          break;
212
        default:
213
          break;
214
      }
215
    }
216
  }
217
#endif
218
219
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY) {
220
    writer->json_keyvalue("writeQueueSize", handle->stream.write_queue_size);
221
    writer->json_keyvalue("readable",
222
                          static_cast<bool>(uv_is_readable(&handle->stream)));
223
    writer->json_keyvalue("writable",
224
                          static_cast<bool>(uv_is_writable(&handle->stream)));
225
  }
226
227
  writer->json_end();
228
}
229
230

366
}  // namespace report