[lldb-dev] "reg read -a" and x86 drN registers
Greg Clayton
gclayton at apple.com
Tue Nov 18 11:27:45 PST 2014
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
More information about the lldb-dev
mailing list