[lldb-dev] "reg read -a" and x86 drN registers

Greg Clayton gclayton at apple.com
Tue Nov 18 12:06:19 PST 2014


If the debugserver doesn't want to vend the debug registers, then it shouldn't return them in response to the qRegisterInfo packet. If it does want to vend them, then the read/write of those registers must work so yes you should fix the read/write register packet in llgs.

> On Nov 18, 2014, at 11:51 AM, Vince Harron <vharron at google.com> wrote:
> 
> Hi Greg,
> 
> It's enumerating the debug registers, which is different than what debugserver does.
> 
> <  60> read packet: $name:dr0;bitsize:64;offset:848;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo87#b1
> <  60> read packet: $name:dr1;bitsize:64;offset:856;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo88#b2
> <  60> read packet: $name:dr2;bitsize:64;offset:864;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo89#b3
> <  60> read packet: $name:dr3;bitsize:64;offset:872;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo8a#db
> <  60> read packet: $name:dr4;bitsize:64;offset:880;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo8b#dc
> <  60> read packet: $name:dr5;bitsize:64;offset:888;encoding:uint;format:hex;#5d
> <  19> send packet: $qRegisterInfo8c#dd
> <  60> read packet: $name:dr6;bitsize:64;offset:896;encoding:uint;format:hex;#5d
> <  19> send packet: $qRegisterInfo8d#de
> <  60> read packet: $name:dr7;bitsize:64;offset:904;encoding:uint;format:hex;#54
> <  19> send packet: $qRegisterInfo8e#df
> <   7> read packet: $E45#ae
> 
> 
> Later on, trying to read these registers returns an error
> 
> <  20> send packet: $p85;thread:71ec;#35
> <  68> read packet: $0000000000000000000000000000000000000000000000000000000000000000#00
> <  20> send packet: $p86;thread:71ec;#36
> <   7> read packet: $E15#ab
> <  20> send packet: $p87;thread:71ec;#37
> <   7> read packet: $E15#ab
> <  20> send packet: $p88;thread:71ec;#38
> <   7> read packet: $E15#ab
> <  20> send packet: $p89;thread:71ec;#39
> <   7> read packet: $E15#ab
> <  20> send packet: $p8a;thread:71ec;#61
> <   7> read packet: $E15#ab
> <  20> send packet: $p8b;thread:71ec;#62
> <   7> read packet: $E15#ab
> <  20> send packet: $p8c;thread:71ec;#63
> <   7> read packet: $E15#ab
> <  20> send packet: $p8d;thread:71ec;#64
> <   7> read packet: $E15#ab
> 
> I can probably fix the register read (not sure) but should I?  These will be used internally by LLDB for watchpoints, right?
> 
> > There should be no need to do anything special in GDBRemoteCommunicationServer::Handle_qRegisterInfo()
> 
> Then the solution is to remove the debug registers from RegisterInfos_x86_64.h
> 
> 
> 
> On Tue, Nov 18, 2014 at 11:27 AM, Greg Clayton <gclayton at apple.com> wrote:
> When running qRegisterInfo, there can be no gaps in the register numbering. There should be no need to do anything special in GDBRemoteCommunicationServer::Handle_qRegisterInfo(). The remote llgs should be correctly responding to the qRegisterInfo packet and if it is truthful then there should be no problem. It sounds like the bug is in llgs and it is sending back the wrong responses for qRegisterInfo. Can you elaborate on what is not correct in the qRegisterInfo packets? Maybe attach a log from "log enable -f /tmp/packets.txt gdb-remote packets" and I can tell you more.
> 
> Greg
> 
> > On Nov 17, 2014, at 7:31 PM, Vince Harron <vharron at google.com> wrote:
> >
> > Hi Ed/all,
> >
> > I'm working on Linux remote debugging.  I'm getting a failure in one of the TestRegisters.py tests.
> >
> > It stems from the fact that the register context's register list is longer than the number of registers covered by the union of all register sets (CPU/FPU/AVX).  (lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h has the x86 debug registers listed)
> >
> > For local debugging, registers are enumerated by set rather than index so we don't see any of those registers.
> >
> > For remote debugging, registers are enumerated by register index so those registers are sent over to the host.  This behavior differs from debugserver.
> >
> > I have a couple of options here
> >
> > 1) I can remove the debug registers from RegisterInfos_x86_64.h.  I'm inclined to do this but they seem be used by FreeBSD but I'm not sure why.
> >
> > 2) I can add a check that the register index being queried is part of a valid register set.  (See patch below)
> >
> > 3) I might be able to make these registers readable/writeable on Linux but I think we'll want to use them internally in LLDB (to implement watchpoints?)  and not display them to users at all.
> >
> > Thoughts?
> >
> > Thanks,
> >
> > Vince
> >
> > GDBRemoteCommunicationServer::Handle_qRegisterInfo (StringExtractorGDBRemote &pa
> >      // Ensure we have a thread.
> >      NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadAtIndex (0));
> >      if (!thread_sp)
> >          return SendErrorResponse (69);
> >
> >      // Get the register context for the first thread.
> >      NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
> >      if (!reg_context_sp)
> >          return SendErrorResponse (69);
> >
> >      // Parse out the register number from the request.
> >      packet.SetFilePos (strlen("qRegisterInfo"));
> >      const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
> >      if (reg_index == std::numeric_limits<uint32_t>::max ())
> >          return SendErrorResponse (69);
> >
> >      // Return the end of registers response if we've iterated one past the end of the register set.
> >      if (reg_index >= reg_context_sp->GetRegisterCount ())
> >          return SendErrorResponse (69);
> >
> > +    // Verify that the register index is part of a valid register set
> > +    const char* reg_set_name = reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
> > +    if (!reg_set_name)
> > +    {
> > +        return SendErrorResponse (69);
> > +    }
> > +
> > +    bool reg_set_available = false;
> > +    for (uint32_t reg_set_idx = 0; reg_set_idx < reg_context_sp->GetRegisterSetCount(); reg_set_idx++)
> > +    {
> > +        const RegisterSet* reg_set = reg_context_sp->GetRegisterSet(reg_set_idx);
> > +        if (0 == strcmp(reg_set->name,reg_set_name))
> > +        {
> > +            reg_set_available = true;
> > +            break;
> > +        }
> > +    }
> > +    if (!reg_set_available)
> > +    {
> > +        return SendErrorResponse (69);
> > +    }
> > +
> >      const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
> >      if (!reg_info)
> >          return SendErrorResponse (69);
> >
> >      // Build the reginfos response.
> >      StreamGDBRemote response;
> >
> >
> > --
> >
> > Vince Harron |         Technical Lead Manager |        vharron at google.com |    858-442-0868
> >
> > _______________________________________________
> > lldb-dev mailing list
> > lldb-dev at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 
> 
> 
> 
> -- 
> 
> Vince Harron |	 Technical Lead Manager |	 vharron at google.com |	 858-442-0868





More information about the lldb-dev mailing list