Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/Communication.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Communication.cpp -------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "lldb/Core/Communication.h"
10
11
#include "lldb/Utility/Connection.h"
12
#include "lldb/Utility/LLDBLog.h"
13
#include "lldb/Utility/Log.h"
14
#include "lldb/Utility/Status.h"
15
16
#include "llvm/Support/Compiler.h"
17
18
#include <algorithm>
19
#include <cstring>
20
#include <memory>
21
22
#include <cerrno>
23
#include <cinttypes>
24
#include <cstdio>
25
26
using namespace lldb;
27
using namespace lldb_private;
28
29
Communication::Communication()
30
11.0k
    : m_connection_sp(), m_write_mutex(), m_close_on_eof(true) {
31
11.0k
}
32
33
10.7k
Communication::~Communication() {
34
10.7k
  Clear();
35
10.7k
}
36
37
12.9k
void Communication::Clear() {
38
12.9k
  Disconnect(nullptr);
39
12.9k
}
40
41
16
ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) {
42
16
  Clear();
43
44
16
  LLDB_LOG(GetLog(LLDBLog::Communication),
45
16
           "{0} Communication::Connect (url = {1})", this, url);
46
47
16
  lldb::ConnectionSP connection_sp(m_connection_sp);
48
16
  if (connection_sp)
49
16
    return connection_sp->Connect(url, error_ptr);
50
0
  if (error_ptr)
51
0
    error_ptr->SetErrorString("Invalid connection.");
52
0
  return eConnectionStatusNoConnection;
53
16
}
54
55
37.9k
ConnectionStatus Communication::Disconnect(Status *error_ptr) {
56
37.9k
  LLDB_LOG(GetLog(LLDBLog::Communication), "{0} Communication::Disconnect ()",
57
37.9k
           this);
58
59
37.9k
  lldb::ConnectionSP connection_sp(m_connection_sp);
60
37.9k
  if (connection_sp) {
61
23.5k
    ConnectionStatus status = connection_sp->Disconnect(error_ptr);
62
    // We currently don't protect connection_sp with any mutex for multi-
63
    // threaded environments. So lets not nuke our connection class without
64
    // putting some multi-threaded protections in. We also probably don't want
65
    // to pay for the overhead it might cause if every time we access the
66
    // connection we have to take a lock.
67
    //
68
    // This unique pointer will cleanup after itself when this object goes
69
    // away, so there is no need to currently have it destroy itself
70
    // immediately upon disconnect.
71
    // connection_sp.reset();
72
23.5k
    return status;
73
23.5k
  }
74
14.4k
  return eConnectionStatusNoConnection;
75
37.9k
}
76
77
2.04M
bool Communication::IsConnected() const {
78
2.04M
  lldb::ConnectionSP connection_sp(m_connection_sp);
79
2.04M
  return (connection_sp ? 
connection_sp->IsConnected()2.04M
:
false2.31k
);
80
2.04M
}
81
82
0
bool Communication::HasConnection() const {
83
0
  return m_connection_sp.get() != nullptr;
84
0
}
85
86
size_t Communication::Read(void *dst, size_t dst_len,
87
                           const Timeout<std::micro> &timeout,
88
722k
                           ConnectionStatus &status, Status *error_ptr) {
89
722k
  Log *log = GetLog(LLDBLog::Communication);
90
722k
  LLDB_LOG(
91
722k
      log,
92
722k
      "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}",
93
722k
      this, dst, dst_len, timeout, m_connection_sp.get());
94
95
722k
  return ReadFromConnection(dst, dst_len, timeout, status, error_ptr);
96
722k
}
97
98
size_t Communication::Write(const void *src, size_t src_len,
99
414k
                            ConnectionStatus &status, Status *error_ptr) {
100
414k
  lldb::ConnectionSP connection_sp(m_connection_sp);
101
102
414k
  std::lock_guard<std::mutex> guard(m_write_mutex);
103
414k
  LLDB_LOG(GetLog(LLDBLog::Communication),
104
414k
           "{0} Communication::Write (src = {1}, src_len = {2}"
105
414k
           ") connection = {3}",
106
414k
           this, src, (uint64_t)src_len, connection_sp.get());
107
108
414k
  if (connection_sp)
109
414k
    return connection_sp->Write(src, src_len, status, error_ptr);
110
111
1
  if (error_ptr)
112
0
    error_ptr->SetErrorString("Invalid connection.");
113
1
  status = eConnectionStatusNoConnection;
114
1
  return 0;
115
414k
}
116
117
size_t Communication::WriteAll(const void *src, size_t src_len,
118
413k
                               ConnectionStatus &status, Status *error_ptr) {
119
413k
  size_t total_written = 0;
120
413k
  do
121
414k
    total_written += Write(static_cast<const char *>(src) + total_written,
122
414k
                           src_len - total_written, status, error_ptr);
123
414k
  while (status == eConnectionStatusSuccess && total_written < src_len);
124
413k
  return total_written;
125
413k
}
126
127
size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
128
                                         const Timeout<std::micro> &timeout,
129
                                         ConnectionStatus &status,
130
741k
                                         Status *error_ptr) {
131
741k
  lldb::ConnectionSP connection_sp(m_connection_sp);
132
741k
  if (connection_sp)
133
741k
    return connection_sp->Read(dst, dst_len, timeout, status, error_ptr);
134
135
0
  if (error_ptr)
136
2
    error_ptr->SetErrorString("Invalid connection.");
137
0
  status = eConnectionStatusNoConnection;
138
0
  return 0;
139
741k
}
140
141
4.48k
void Communication::SetConnection(std::unique_ptr<Connection> connection) {
142
4.48k
  Disconnect(nullptr);
143
4.48k
  m_connection_sp = std::move(connection);
144
4.48k
}
145
146
std::string
147
0
Communication::ConnectionStatusAsString(lldb::ConnectionStatus status) {
148
0
  switch (status) {
149
0
  case eConnectionStatusSuccess:
150
0
    return "success";
151
0
  case eConnectionStatusError:
152
0
    return "error";
153
0
  case eConnectionStatusTimedOut:
154
0
    return "timed out";
155
0
  case eConnectionStatusNoConnection:
156
0
    return "no connection";
157
0
  case eConnectionStatusLostConnection:
158
0
    return "lost connection";
159
0
  case eConnectionStatusEndOfFile:
160
0
    return "end of file";
161
0
  case eConnectionStatusInterrupted:
162
0
    return "interrupted";
163
0
  }
164
165
0
  return "@" + std::to_string(status);
166
0
}