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 131 0.8 %
Date: 2019-02-01 22:03:38 Branches: 2 92 2.2 %

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
// Utility function to format libuv socket information.
9
void ReportEndpoints(uv_handle_t* h, std::ostringstream& out) {
10
  struct sockaddr_storage addr_storage;
11
  struct sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage);
12
  char hostbuf[NI_MAXHOST];
13
  char portbuf[NI_MAXSERV];
14
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
15
  int addr_size = sizeof(addr_storage);
16
  int rc = -1;
17
18
  switch (h->type) {
19
    case UV_UDP: {
20
      rc = uv_udp_getsockname(&(handle->udp), addr, &addr_size);
21
      break;
22
    }
23
    case UV_TCP: {
24
      rc = uv_tcp_getsockname(&(handle->tcp), addr, &addr_size);
25
      break;
26
    }
27
    default:
28
      break;
29
  }
30
  if (rc == 0) {
31
    // getnameinfo will format host and port and handle IPv4/IPv6.
32
    rc = getnameinfo(addr,
33
                     addr_size,
34
                     hostbuf,
35
                     sizeof(hostbuf),
36
                     portbuf,
37
                     sizeof(portbuf),
38
                     NI_NUMERICSERV);
39
    if (rc == 0) {
40
      out << std::string(hostbuf) << ":" << std::string(portbuf);
41
    }
42
43
    if (h->type == UV_TCP) {
44
      // Get the remote end of the connection.
45
      rc = uv_tcp_getpeername(&(handle->tcp), addr, &addr_size);
46
      if (rc == 0) {
47
        rc = getnameinfo(addr,
48
                         addr_size,
49
                         hostbuf,
50
                         sizeof(hostbuf),
51
                         portbuf,
52
                         sizeof(portbuf),
53
                         NI_NUMERICSERV);
54
        if (rc == 0) {
55
          out << " connected to ";
56
          out << std::string(hostbuf) << ":" << std::string(portbuf);
57
        }
58
      } else if (rc == UV_ENOTCONN) {
59
        out << " (not connected)";
60
      }
61
    }
62
  }
63
}
64
65
// Utility function to format libuv path information.
66
void ReportPath(uv_handle_t* h, std::ostringstream& out) {
67
  MallocedBuffer<char> buffer(0);
68
  int rc = -1;
69
  size_t size = 0;
70
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
71
  // First call to get required buffer size.
72
  switch (h->type) {
73
    case UV_FS_EVENT: {
74
      rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
75
      break;
76
    }
77
    case UV_FS_POLL: {
78
      rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
79
      break;
80
    }
81
    default:
82
      break;
83
  }
84
  if (rc == UV_ENOBUFS) {
85
    buffer = MallocedBuffer<char>(size);
86
    switch (h->type) {
87
      case UV_FS_EVENT: {
88
        rc = uv_fs_event_getpath(&(handle->fs_event), buffer.data, &size);
89
        break;
90
      }
91
      case UV_FS_POLL: {
92
        rc = uv_fs_poll_getpath(&(handle->fs_poll), buffer.data, &size);
93
        break;
94
      }
95
      default:
96
        break;
97
    }
98
    if (rc == 0) {
99
      // buffer is not null terminated.
100
      std::string name(buffer.data, size);
101
      out << "filename: " << name;
102
    }
103
  }
104
}
105
106
// Utility function to walk libuv handles.
107
void WalkHandle(uv_handle_t* h, void* arg) {
108
  const char* type = uv_handle_type_name(h->type);
109
  std::ostringstream data;
110
  JSONWriter* writer = static_cast<JSONWriter*>(arg);
111
  uv_any_handle* handle = reinterpret_cast<uv_any_handle*>(h);
112
113
  switch (h->type) {
114
    case UV_FS_EVENT:
115
    case UV_FS_POLL:
116
      ReportPath(h, data);
117
      break;
118
    case UV_PROCESS:
119
      data << "pid: " << handle->process.pid;
120
      break;
121
    case UV_TCP:
122
    case UV_UDP:
123
      ReportEndpoints(h, data);
124
      break;
125
    case UV_TIMER: {
126
      uint64_t due = handle->timer.timeout;
127
      uint64_t now = uv_now(handle->timer.loop);
128
      data << "repeat: " << uv_timer_get_repeat(&(handle->timer));
129
      if (due > now) {
130
        data << ", timeout in: " << (due - now) << " ms";
131
      } else {
132
        data << ", timeout expired: " << (now - due) << " ms ago";
133
      }
134
      break;
135
    }
136
    case UV_TTY: {
137
      int height, width, rc;
138
      rc = uv_tty_get_winsize(&(handle->tty), &width, &height);
139
      if (rc == 0) {
140
        data << "width: " << width << ", height: " << height;
141
      }
142
      break;
143
    }
144
    case UV_SIGNAL: {
145
      // SIGWINCH is used by libuv so always appears.
146
      // See http://docs.libuv.org/en/v1.x/signal.html
147
      data << "signum: " << handle->signal.signum
148
#ifndef _WIN32
149
           << " (" << node::signo_string(handle->signal.signum) << ")"
150
#endif
151
           << "";
152
      break;
153
    }
154
    default:
155
      break;
156
  }
157
158
  if (h->type == UV_TCP || h->type == UV_UDP
159
#ifndef _WIN32
160
      || h->type == UV_NAMED_PIPE
161
#endif
162
  ) {
163
    // These *must* be 0 or libuv will set the buffer sizes to the non-zero
164
    // values they contain.
165
    int send_size = 0;
166
    int recv_size = 0;
167
    if (h->type == UV_TCP || h->type == UV_UDP) {
168
      data << ", ";
169
    }
170
    uv_send_buffer_size(h, &send_size);
171
    uv_recv_buffer_size(h, &recv_size);
172
    data << "send buffer size: " << send_size
173
         << ", recv buffer size: " << recv_size;
174
  }
175
176
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY ||
177
      h->type == UV_UDP || h->type == UV_POLL) {
178
    uv_os_fd_t fd_v;
179
    int rc = uv_fileno(h, &fd_v);
180
    // uv_os_fd_t is an int on Unix and HANDLE on Windows.
181
#ifndef _WIN32
182
    if (rc == 0) {
183
      switch (fd_v) {
184
        case 0:
185
          data << ", stdin";
186
          break;
187
        case 1:
188
          data << ", stdout";
189
          break;
190
        case 2:
191
          data << ", stderr";
192
          break;
193
        default:
194
          data << ", file descriptor: " << static_cast<int>(fd_v);
195
          break;
196
      }
197
    }
198
#endif
199
  }
200
201
  if (h->type == UV_TCP || h->type == UV_NAMED_PIPE || h->type == UV_TTY) {
202
    data << ", write queue size: " << handle->stream.write_queue_size;
203
    data << (uv_is_readable(&handle->stream) ? ", readable" : "")
204
         << (uv_is_writable(&handle->stream) ? ", writable" : "");
205
  }
206
207
  writer->json_start();
208
  writer->json_keyvalue("type", type);
209
  writer->json_keyvalue("is_active", static_cast<bool>(uv_is_active(h)));
210
  writer->json_keyvalue("is_referenced", static_cast<bool>(uv_has_ref(h)));
211
  writer->json_keyvalue("address",
212
                        std::to_string(reinterpret_cast<int64_t>(h)));
213
  writer->json_keyvalue("details", data.str());
214
  writer->json_end();
215
}
216
217
std::string EscapeJsonChars(const std::string& str) {
218
  const std::string control_symbols[0x20] = {
219
      "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
220
      "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r",
221
      "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013",
222
      "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019",
223
      "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"
224
  };
225
226
  std::string ret = "";
227
  size_t last_pos = 0;
228
  size_t pos = 0;
229
  for (; pos < str.size(); ++pos) {
230
    std::string replace;
231
    char ch = str[pos];
232
    if (ch == '\\') {
233
      replace = "\\\\";
234
    } else if (ch == '\"') {
235
      replace = "\\\"";
236
    } else {
237
      size_t num = static_cast<size_t>(ch);
238
      if (num < 0x20) replace = control_symbols[num];
239
    }
240
    if (!replace.empty()) {
241
      if (pos > last_pos) {
242
        ret += str.substr(last_pos, pos - last_pos);
243
      }
244
      last_pos = pos + 1;
245
      ret += replace;
246
    }
247
  }
248
  // Append any remaining symbols.
249
  if (last_pos < str.size()) {
250
    ret += str.substr(last_pos, pos - last_pos);
251
  }
252
  return ret;
253
}
254
255

492
}  // namespace report