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

Vince Harron vharron at google.com
Mon Nov 17 19:31:44 PST 2014


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20141117/95019f3c/attachment.html>


More information about the lldb-dev mailing list