<div dir="ltr"><div>Hi,</div><div><br></div><div>Here's a new patch with the mutex check (full patch attached, diff against prior patch follows inline).</div><div><br></div><div>Thanks,</div><div>   Steve</div><div><br>
</div><div><div>diff -r svn2/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp svn/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp</div><div>461a462,472</div>
<div>>     Mutex::Locker locker;</div><div>>     if (!GetSequenceMutex(locker,</div><div>>                           "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))</div>
<div>>     {</div><div>>         Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));</div><div>>         if (log)</div><div>>             log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",</div>
<div>>                         payload_prefix);</div><div>>         return PacketResult::ErrorNoSequenceLock;</div><div>>     }</div><div>> </div><div>diff -r svn2/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h svn/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h</div>
<div>48c48,49</div><div><         ErrorDisconnected   // We were disconnected</div><div>---</div><div>>         ErrorDisconnected,  // We were disconnected</div><div>>         ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request</div>
</div><div><br></div><div><br></div><div><br></div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jan 24, 2014 at 10:34 AM, Steve Pucci <span dir="ltr"><<a href="mailto:spucci@google.com" target="_blank">spucci@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">OK, thanks Greg.  I'll incorporate that and resend the patch.<span class="HOEnZb"><font color="#888888"><div>
<br></div><div>- Steve</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jan 24, 2014 at 10:22 AM, Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Looks ok, but one fix is needed:<br>
<br>
Since LLDB us multi-threaded, when you need to send more than one packet/response for a given command, you need to manually take the sequence mutex (which is recursive) to stop other threads from interfering with your packet sequence.<br>


<br>
See the "GDBRemoteCommunicationClient::GetCurrentThreadIDs()" function for details.<br>
<br>
You basically don't want this to happen:<br>
<br>
thread 1 sends: qfThreadInfo<br>
thread 2 sends: qfThreadInfo<br>
thread 1 sends: qsThreadInfo<br>
thread 2 sends: qsThreadInfo << possible error?<br>
<br>
The sequence mutex guarantees all your packets go out in the correct order<br>
<br>
thread 1: get sequence mutex<br>
thread 1 sends: qfThreadInfo<br>
thread 1 sends: qsThreadInfo<br>
thread 1: release sequence mutex<br>
<br>
We do have to watch out for when we are running because when running we do this:<br>
<br>
thread 1: get sequence mutex<br>
thread 1: send "c" packet to continue<br>
....<br>
thread 2: send 'qfThreadInfo' packet and get error back<br>
<br>
Each packet can determine if it is ok to interrupt the process in order for it to send and this is a boolean that is included in:<br>
<br>
GDBRemoteCommunicationClient::PacketResult<br>
GDBRemoteCommunicationClient::SendPacketAndWaitForResponse<br>
(<br>
    const char *payload,<br>
    size_t payload_length,<br>
    StringExtractorGDBRemote &response,<br>
    bool send_async<br>
)<br>
<br>
<br>
If "send_async" is true, then we will send a "\x03" to interrupt the process and stop it, then send the packet we wanted to send and get a response, and then continue the process.<br>
<br>
The only packets that are currently allows to send as async are memory read/write and breakpoint/watchpoint set/clear.<br>
<br>
So most commands try to get the sequence mutex and if that fails, they bail with an error as they should. This is something that is good to understand.<br>
<br>
Greg<br>
<div><div><br>
<br>
On Jan 24, 2014, at 8:13 AM, Steve Pucci <<a href="mailto:spucci@google.com" target="_blank">spucci@google.com</a>> wrote:<br>
<br>
> Hi,<br>
><br>
> A diff against the previous patch, incorporating Abid's comments, follows inline.  A modified full patch is included as an attachment.<br>
><br>
> Thanks,<br>
>    Steve<br>
><br>
> diff --git a/usr/local/google/home/spucci/lldb/work/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h<br>


> index 2026e50..a1e982b 100644<br>
> --- a/usr/local/google/home/spucci/lldb/work/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h<br>
> +++ b/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h<br>
> @@ -59,16 +59,22 @@ public:<br>
>                                    bool send_async);<br>
><br>
>      // For packets which specify a range of output to be returned,<br>
> -    // return all of the output via a series of packets of the form<br>
> -    // <prefix>:000,<size><br>
> -    // <prefix>:<size>,<size><br>
> -    // <prefix>:<size>*2,<size><br>
> -    // <prefix>:<size>*3,<size><br>
> +    // return all of the output via a series of request packets of the form<br>
> +    // <prefix>0,<size><br>
> +    // <prefix><size>,<size><br>
> +    // <prefix><size>*2,<size><br>
> +    // <prefix><size>*3,<size><br>
>      // ...<br>
>      // until a "$l..." packet is received, indicating the end.<br>
> -    // Concatenate the results together and return in response.<br>
> -    // If any packet fails, the response indicates that failure<br>
> -    // and the returned string value is undefined.<br>
> +    // (size is in hex; this format is used by a standard gdbserver to<br>
> +    // return the given portion of the output specified by <prefix>;<br>
> +    // for example, "qXfer:libraries-svr4:read::fff,1000" means<br>
> +    // "return a chunk of the xml description file for shared<br>
> +    // library load addresses, where the chunk starts at offset 0xfff<br>
> +    // and continues for 0x1000 bytes").<br>
> +    // Concatenate the resulting server response packets together and<br>
> +    // return in response_string.  If any packet fails, the return value<br>
> +    // indicates that failure and the returned string value is undefined.<br>
>      PacketResult<br>
>      SendPacketsAndConcatenateResponses (const char *send_payload_prefix,<br>
>                                          std::string &response_string);<br>
> diff --git a/usr/local/google/home/spucci/lldb/work/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp<br>


> index 9f591c8..4a3292a 100644<br>
> --- a/usr/local/google/home/spucci/lldb/work/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp<br>
> +++ b/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp<br>
> @@ -341,7 +341,6 @@ GDBRemoteCommunicationClient::GetRemoteQSupported ()<br>
>          {<br>
>              StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));<br>
>              m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);<br>
> -            printf("max packet size %lu\n", (unsigned long)m_max_packet_size);<br>
>              if (m_max_packet_size == 0)<br>
>              {<br>
>                  m_max_packet_size = UINT64_MAX;  // Must have been a garbled response<br>
> spucci-linux %emacs ~/lldb/svn% 1497%<br>
><br>
><br>
><br>
><br>
> On Fri, Jan 24, 2014 at 7:41 AM, Steve Pucci <<a href="mailto:spucci@google.com" target="_blank">spucci@google.com</a>> wrote:<br>
> Thanks, Abid.  Answers to your questions below.<br>
><br>
> On Fri, Jan 24, 2014 at 2:11 AM, Abid, Hafiz <<a href="mailto:Hafiz_Abid@mentor.com" target="_blank">Hafiz_Abid@mentor.com</a>> wrote:<br>
> Hi Steve,<br>
><br>
> I had a quick look at the patch. It mostly looks good. Some small comments below.<br>
><br>
><br>
><br>
> +    // For packets which specify a range of output to be returned,<br>
><br>
> +    // return all of the output via a series of packets of the form<br>
><br>
> +    // <prefix>:000,<size><br>
><br>
> +    // <prefix>:<size>,<size><br>
><br>
> +    // <prefix>:<size>*2,<size><br>
><br>
> +    // <prefix>:<size>*3,<size><br>
><br>
> +    // ...<br>
><br>
> +    // until a "$l..." packet is received, indicating the end.<br>
><br>
> +    // Concatenate the results together and return in response.<br>
><br>
> I think that perhaps you can make this comment a bit more clear. Just separate what the remote target will do and what this function will do.<br>
><br>
><br>
> OK, will do, thanks.<br>
><br>
><br>
>  +            printf("max packet size %lu\n", (unsigned long)m_max_packet_size);<br>
><br>
> You forgot to remove this printf.<br>
><br>
><br>
> Right, thanks.<br>
><br>
><br>
>  +        snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);<br>
><br>
> +        PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),<br>
><br>
> +                                                           this_response,<br>
><br>
> +                                                           /*send_async=*/false);<br>
><br>
> When I see such packets in GDB remote log (e.g. $qXfer:features:read:64bit-core.xml:0,fff), there is a colon before offset. I don’t see it being added here. Is it supposed to be in payload_prefix_str?<br>
><br>
><br>
> Yes, that's the way I have it currently in my calling code.  It's been tested in that environment and works but I'm not ready to check in the calling code yet.  (I've also tested it in an environment without my calling code to ensure this works as a standalone patch, though it's unused).<br>


><br>
> I suppose after this is approved, you would be working on parsing the xml that came from the gdbserver. Would it be only for shared libraries or you are also interested in xml target description?<br>
><br>
><br>
> Yes, my calling code parses using libxml2, and the plan is to have libxml2 conditionally compiled and linked in (using the same mechanism that clang uses for the same purpose).  I have that working also in the calling code.<br>


><br>
> I considered putting the xml parser in GDBRemoteCommunicationClient also but it seemed a bit higher-level than that class operates at.  But I'm open to whatever people think here.  One possibility would be to split the creation of the XML DOM and the walking of the DOM tree, and put the creation of the DOM in GDBRemoteCommunicationClient.<br>


><br>
> We are also interested in the xml target description but it's not a priority at the moment.<br>
><br>
> Thanks again for the review.  I'll send out the modified patch before committing.<br>
><br>
>  - Steve<br>
><br>
><br>
><br>
><br>
> Regards,<br>
><br>
> Abid<br>
><br>
><br>
><br>
><br>
><br>
><br>
><br>
><br>
><br>
> From: <a href="mailto:lldb-dev-bounces@cs.uiuc.edu" target="_blank">lldb-dev-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:lldb-dev-bounces@cs.uiuc.edu" target="_blank">lldb-dev-bounces@cs.uiuc.edu</a>] On Behalf Of Steve Pucci<br>

> Sent: 23 January 2014 21:04<br>
> To: <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> Subject: [lldb-dev] [PATCH] new utility methods in GDBRemoteCommunicationClient<br>
><br>
><br>
><br>
> I'm working on better support for debugging against a remote stock gdbserver, and these are some new support methods I'm using.  I'm sending this separately for easier digestion.<br>
><br>
><br>
><br>
> There are a couple of pieces:<br>
><br>
>  * some lazy-evaluation members that store info listed in a qSupported response<br>
><br>
>  * new method SendPacketsAndConcatenateResponses which is used for fetching fixed-size objects from the remote gdbserver by using multiple packets if necessary (first use will be to fetch shared-library XML files).<br>


><br>
><br>
><br>
> Thanks,<br>
><br>
>    Steve<br>
><br>
><br>
><br>
><br>
><br>
</div></div>> <patch-GDBRemoteCommClient-2.txt>_______________________________________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
<br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>