[Reproducers] Log inconsistencies during replay (NFC)

Make debugging of the GDB remote packet aspect of reproducers easier by
logging both requests and replies. This enables some sanity checking
during replay.

llvm-svn: 356638
This commit is contained in:
Jonas Devlieghere 2019-03-21 01:57:33 +00:00
parent 0e04ab7e94
commit e3ea27b640
2 changed files with 41 additions and 5 deletions

View File

@ -45,7 +45,7 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
if (m_stream && type == ePacketTypeRecv)
if (m_stream)
m_packets[idx].Serialize(*m_stream);
}
@ -62,7 +62,7 @@ void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
if (m_stream && type == ePacketTypeRecv)
if (m_stream)
m_packets[idx].Serialize(*m_stream);
}

View File

@ -30,6 +30,26 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
static bool unexpected(llvm::StringRef expected, llvm::StringRef actual) {
// The 'expected' string contains the raw data, including the leading $ and
// trailing checksum. The 'actual' string contains only the packet's content.
if (expected.contains(actual))
return false;
if (expected == "+" || actual == "+")
return false;
// Contains a PID which might be different.
if (expected.contains("vAttach"))
return false;
// Contains a ascii-hex-path.
if (expected.contains("QSetSTD"))
return false;
// Contains environment values.
if (expected.contains("QEnvironment"))
return false;
return true;
}
GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
: GDBRemoteCommunication("gdb-remote.server",
"gdb-remote.server.rx_packet"),
@ -87,15 +107,31 @@ GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
m_send_acks = false;
}
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
while (!m_packet_history.empty()) {
// Pop last packet from the history.
GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
m_packet_history.pop_back();
// We only care about what we received from the server. Skip everything
// the client sent.
if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv)
if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeSend) {
if (unexpected(entry.packet.data, packet.GetStringRef())) {
LLDB_LOG(log,
"GDBRemoteCommunicationReplayServer expected packet: '{}'\n",
entry.packet.data);
LLDB_LOG(log,
"GDBRemoteCommunicationReplayServer actual packet: '{}'\n",
packet.GetStringRef());
}
continue;
}
if (entry.type == GDBRemoteCommunicationHistory::ePacketTypeInvalid) {
LLDB_LOG(
log,
"GDBRemoteCommunicationReplayServer skipped invalid packet: '{}'\n",
packet.GetStringRef());
continue;
}
return SendRawPacketNoLock(entry.packet.data, true);
}