[Lldb-commits] [lldb] r364494 - [Reproducers] Fix flakiness and off-by-one during replay.

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 1 01:30:13 PDT 2019


Do we have a test which records us interrupting a process, and then 
makes sure this replays correctly ?



On 27/06/2019 04:03, Jonas Devlieghere via lldb-commits wrote:
> Author: jdevlieghere
> Date: Wed Jun 26 19:03:34 2019
> New Revision: 364494
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=364494&view=rev
> Log:
> [Reproducers] Fix flakiness and off-by-one during replay.
> 
> This fixes two replay issues that caused the tests to behave
> erratically:
> 
> 1. It fixes an off-by-one error, where all replies where shifted by 1
>     because of a `+` packet that should've been ignored.
> 
> 2. It fixes another off-by-one-error, where an asynchronous ^C was
>     offsetting all subsequent packets. The reason is that we
>     'synchronize' requests and replies. In reality, a stop reply is only
>     sent when the process halt. During replay however, we instantly
>     report the stop, as the reply to packets like continue (vCont).
> 
> Both packets should be ignored, and indeed, checking the gdb-remote log,
> no unexpected packets are received anymore.
> 
> Additionally, be more pedantic when it comes to unexpected packets and
> return an failure form the replay server. This way we should be able to
> catch these things faster in the future.
> 
> Modified:
>      lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
> 
> Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp?rev=364494&r1=364493&r2=364494&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp (original)
> +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp Wed Jun 26 19:03:34 2019
> @@ -30,6 +30,7 @@ using namespace lldb;
>   using namespace lldb_private;
>   using namespace lldb_private::process_gdb_remote;
>   
> +/// Check if the given expected packet matches the actual packet.
>   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.
> @@ -48,6 +49,25 @@ static bool unexpected(llvm::StringRef e
>     return true;
>   }
>   
> +/// Check if we should reply to the given packet.
> +static bool skip(llvm::StringRef data) {
> +  assert(!data.empty() && "Empty packet?");
> +
> +  // We've already acknowledge the '+' packet so we're done here.
> +  if (data == "+")
> +    return true;
> +
> +  /// Don't 't reply to ^C. We need this because of stop reply packets, which
> +  /// are only returned when the target halts. Reproducers synchronize these
> +  /// 'asynchronous' replies, by recording them as a regular replies to the
> +  /// previous packet (e.g. vCont). As a result, we should ignore real
> +  /// asynchronous requests.
> +  if (data.data()[0] == 0x03)
> +    return true;
> +
> +  return false;
> +}
> +
>   GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
>       : GDBRemoteCommunication("gdb-replay", "gdb-replay.rx_packet"),
>         m_async_broadcaster(nullptr, "lldb.gdb-replay.async-broadcaster"),
> @@ -89,9 +109,8 @@ GDBRemoteCommunicationReplayServer::GetP
>   
>     m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
>   
> -  // If m_send_acks is true, we're before the handshake phase. We've already
> -  // acknowledge the '+' packet so we're done here.
> -  if (m_send_acks && packet.GetStringRef() == "+")
> +  // Check if we should reply to this packet.
> +  if (skip(packet.GetStringRef()))
>       return PacketResult::Success;
>   
>     // This completes the handshake. Since m_send_acks was true, we can unset it
> @@ -102,9 +121,8 @@ GDBRemoteCommunicationReplayServer::GetP
>     // A QEnvironment packet is sent for every environment variable. If the
>     // number of environment variables is different during replay, the replies
>     // become out of sync.
> -  if (packet.GetStringRef().find("QEnvironment") == 0) {
> +  if (packet.GetStringRef().find("QEnvironment") == 0)
>       return SendRawPacketNoLock("$OK#9a");
> -  }
>   
>     Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
>     while (!m_packet_history.empty()) {
> @@ -112,7 +130,7 @@ GDBRemoteCommunicationReplayServer::GetP
>       GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
>       m_packet_history.pop_back();
>   
> -    // We're handled the handshake implicitly before. Skip the packet and move
> +    // We've handled the handshake implicitly before. Skip the packet and move
>       // on.
>       if (entry.packet.data == "+")
>         continue;
> @@ -124,6 +142,7 @@ GDBRemoteCommunicationReplayServer::GetP
>                    entry.packet.data);
>           LLDB_LOG(log, "GDBRemoteCommunicationReplayServer actual packet: '{0}'",
>                    packet.GetStringRef());
> +        return PacketResult::ErrorSendFailed;
>         }
>   
>         // Ignore QEnvironment packets as they're handled earlier.
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
> 



More information about the lldb-commits mailing list