[lldb-dev] LLDB using Valgrind's embedded gdbserver

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Fri Dec 4 10:55:09 PST 2015


The issue is LLDB wants to know information in the registers in the register context regarding how they map to "generic" registers. For x86_64 this means:

LLDB_REGNUM_GENERIC_PC          -> rip
LLDB_REGNUM_GENERIC_SP          -> rsp
LLDB_REGNUM_GENERIC_FP          -> rbp
LLDB_REGNUM_GENERIC_RA          -> <none for x86>
LLDB_REGNUM_GENERIC_FLAGS       -> rflags
LLDB_REGNUM_GENERIC_ARG1        -> rdi
LLDB_REGNUM_GENERIC_ARG2        -> rsi
LLDB_REGNUM_GENERIC_ARG3        -> rdx
LLDB_REGNUM_GENERIC_ARG4        -> rcx
LLDB_REGNUM_GENERIC_ARG5        -> r8
LLDB_REGNUM_GENERIC_ARG6        -> r9

We also want to know what DWARF register number each register has, what compiler register number (for EH frame) each register is, and more.

There are two ways to do this:

1 - if you want to change the LLDB code
2 - if you want to make this work by only modifying valgrind's GDB server

If you go with option 1, it looks like the bug here is in:

static void
AugmentRegisterInfoViaABI (RegisterInfo &reg_info, ConstString reg_name, ABISP abi_sp)

It grabs the register info from the ABI and fills it in, but it wasn't filling in the generic register number. I just fixed this with:

r254743 | gclayton | 2015-12-04 10:37:48 -0800 (Fri, 04 Dec 2015) | 1 line

Fill in the generic register kind if in AugmentRegisterInfoViaABI if it is available.

So if you update your sources, it might start working.

If you don't want the change LLDB, you can make the XML returned for the registers contain extra attributes to specify these things. If you check the code in ProcessGDBRemote.cpp around line 4327:

bool
ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp)

You can see the extra attributes a "reg" element node can contain. 

We extended the XML to include keys that LLDB can use. The assert that is causing the crash is the fact that we are asking a register context for the "generic" register that is "arg1". If you can modify the XML that is returned to mark up the registers so the generic name is attached to each register, it will help out LLDB. "debugserver" actually used this modified XML, so to see what it would look like with all of the new things we added you can copy what you need from the XML below. But lets look at the definition for "rip" alone:

  <reg name="rip" regnum="16" offset="128" bitsize="64" group="general" altname="pc" group_id="1" gcc_regnum="16" dwarf_regnum="16" generic="pc"/>

Note we specify regnum (the lldb register number), offset (the byte offset for this register in the register context), altname, group_id (the register group this should appear in, see the "groups" at the end of the XML to see the register set names), gcc_regnum which is the compiler register number, dwarf_regnum, and the generic register name ("pc", "sp", "fp", "arg1", "arg2", etc).

So our full XML which specifies the compiler register numbers, DWARF register numbers and generic register names looks like:

l<?xml version="1.0"?>
<target version="1.0">
<feature name="com.apple.debugserver.x86_64">
  <reg name="rax" regnum="0" offset="0" bitsize="64" group="general" group_id="1" gcc_regnum="0" dwarf_regnum="0"/>
  <reg name="rbx" regnum="1" offset="8" bitsize="64" group="general" group_id="1" gcc_regnum="3" dwarf_regnum="3"/>
  <reg name="rcx" regnum="2" offset="16" bitsize="64" group="general" altname="arg4" group_id="1" gcc_regnum="2" dwarf_regnum="2" generic="arg4"/>
  <reg name="rdx" regnum="3" offset="24" bitsize="64" group="general" altname="arg3" group_id="1" gcc_regnum="1" dwarf_regnum="1" generic="arg3"/>
  <reg name="rdi" regnum="4" offset="32" bitsize="64" group="general" altname="arg1" group_id="1" gcc_regnum="5" dwarf_regnum="5" generic="arg1"/>
  <reg name="rsi" regnum="5" offset="40" bitsize="64" group="general" altname="arg2" group_id="1" gcc_regnum="4" dwarf_regnum="4" generic="arg2"/>
  <reg name="rbp" regnum="6" offset="48" bitsize="64" group="general" altname="fp" group_id="1" gcc_regnum="6" dwarf_regnum="6" generic="fp"/>
  <reg name="rsp" regnum="7" offset="56" bitsize="64" group="general" altname="sp" group_id="1" gcc_regnum="7" dwarf_regnum="7" generic="sp"/>
  <reg name="r8" regnum="8" offset="64" bitsize="64" group="general" altname="arg5" group_id="1" gcc_regnum="8" dwarf_regnum="8" generic="arg5"/>
  <reg name="r9" regnum="9" offset="72" bitsize="64" group="general" altname="arg6" group_id="1" gcc_regnum="9" dwarf_regnum="9" generic="arg6"/>
  <reg name="r10" regnum="10" offset="80" bitsize="64" group="general" group_id="1" gcc_regnum="10" dwarf_regnum="10"/>
  <reg name="r11" regnum="11" offset="88" bitsize="64" group="general" group_id="1" gcc_regnum="11" dwarf_regnum="11"/>
  <reg name="r12" regnum="12" offset="96" bitsize="64" group="general" group_id="1" gcc_regnum="12" dwarf_regnum="12"/>
  <reg name="r13" regnum="13" offset="104" bitsize="64" group="general" group_id="1" gcc_regnum="13" dwarf_regnum="13"/>
  <reg name="r14" regnum="14" offset="112" bitsize="64" group="general" group_id="1" gcc_regnum="14" dwarf_regnum="14"/>
  <reg name="r15" regnum="15" offset="120" bitsize="64" group="general" group_id="1" gcc_regnum="15" dwarf_regnum="15"/>
  <reg name="rip" regnum="16" offset="128" bitsize="64" group="general" altname="pc" group_id="1" gcc_regnum="16" dwarf_regnum="16" generic="pc"/>
  <reg name="rflags" regnum="17" offset="136" bitsize="64" group="general" altname="flags" group_id="1" generic="flags"/>
  <reg name="cs" regnum="18" offset="144" bitsize="64" group="general" group_id="1"/>
  <reg name="fs" regnum="19" offset="152" bitsize="64" group="general" group_id="1"/>
  <reg name="gs" regnum="20" offset="160" bitsize="64" group="general" group_id="1"/>
  <reg name="fctrl" regnum="73" offset="168" bitsize="16" group="general" group_id="2"/>
  <reg name="fstat" regnum="74" offset="170" bitsize="16" group="general" group_id="2"/>
  <reg name="ftag" regnum="75" offset="172" bitsize="8" group="general" group_id="2"/>
  <reg name="fop" regnum="76" offset="173" bitsize="16" group="general" group_id="2"/>
  <reg name="fioff" regnum="77" offset="175" bitsize="32" group="general" group_id="2"/>
  <reg name="fiseg" regnum="78" offset="179" bitsize="16" group="general" group_id="2"/>
  <reg name="fooff" regnum="79" offset="181" bitsize="32" group="general" group_id="2"/>
  <reg name="foseg" regnum="80" offset="185" bitsize="16" group="general" group_id="2"/>
  <reg name="mxcsr" regnum="81" offset="187" bitsize="32" group="general" group_id="2"/>
  <reg name="mxcsrmask" regnum="82" offset="191" bitsize="32" group="general" group_id="2"/>
  <reg name="stmm0" regnum="83" offset="195" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="33" dwarf_regnum="33"/>
  <reg name="stmm1" regnum="84" offset="205" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="34" dwarf_regnum="34"/>
  <reg name="stmm2" regnum="85" offset="215" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="35" dwarf_regnum="35"/>
  <reg name="stmm3" regnum="86" offset="225" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="36" dwarf_regnum="36"/>
  <reg name="stmm4" regnum="87" offset="235" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="37" dwarf_regnum="37"/>
  <reg name="stmm5" regnum="88" offset="245" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="38" dwarf_regnum="38"/>
  <reg name="stmm6" regnum="89" offset="255" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="39" dwarf_regnum="39"/>
  <reg name="stmm7" regnum="90" offset="265" bitsize="80" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="40" dwarf_regnum="40"/>
  <reg name="ymm0" regnum="91" offset="275" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="17" dwarf_regnum="17"/>
  <reg name="ymm1" regnum="92" offset="307" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="18" dwarf_regnum="18"/>
  <reg name="ymm2" regnum="93" offset="339" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="19" dwarf_regnum="19"/>
  <reg name="ymm3" regnum="94" offset="371" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="20" dwarf_regnum="20"/>
  <reg name="ymm4" regnum="95" offset="403" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="21" dwarf_regnum="21"/>
  <reg name="ymm5" regnum="96" offset="435" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="22" dwarf_regnum="22"/>
  <reg name="ymm6" regnum="97" offset="467" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="23" dwarf_regnum="23"/>
  <reg name="ymm7" regnum="98" offset="499" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="24" dwarf_regnum="24"/>
  <reg name="ymm8" regnum="99" offset="531" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="25" dwarf_regnum="25"/>
  <reg name="ymm9" regnum="100" offset="563" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="26" dwarf_regnum="26"/>
  <reg name="ymm10" regnum="101" offset="595" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="27" dwarf_regnum="27"/>
  <reg name="ymm11" regnum="102" offset="627" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="28" dwarf_regnum="28"/>
  <reg name="ymm12" regnum="103" offset="659" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="29" dwarf_regnum="29"/>
  <reg name="ymm13" regnum="104" offset="691" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="30" dwarf_regnum="30"/>
  <reg name="ymm14" regnum="105" offset="723" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="31" dwarf_regnum="31"/>
  <reg name="ymm15" regnum="106" offset="755" bitsize="256" group="vector" type="float" encoding="vector" format="vector-uint8" group_id="2" gcc_regnum="32" dwarf_regnum="32"/>
  <reg name="trapno" regnum="123" offset="787" bitsize="32" group="general" group_id="3"/>
  <reg name="err" regnum="124" offset="791" bitsize="32" group="general" group_id="3"/>
  <reg name="faultvaddr" regnum="125" offset="795" bitsize="64" group="general" group_id="3"/>
</feature>
<groups>
  <group id="1" name="General Purpose Registers"/>
  <group id="2" name="Floating Point Registers"/>
  <group id="3" name="Exception State Registers"/>
</groups>
</target>



So if you get the generic register numbers fixed, you should probably not be crashing anymore.

Greg Clayton




> On Dec 3, 2015, at 4:24 PM, Daniel Trebbien via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hello,
> 
> I am working on enhancing Valgrind's embedded gdbserver to allow LLDB to use it (https://bugs.kde.org/show_bug.cgi?id=356174 ).  After adding support for 'qC' packets to the embedded gdbserver, LLDB is able to continue the halted program running under Valgrind; however, a short moment later LLDB crashes.
> 
> I am using OS X 10.11.1 (15B42) and lldb-340.4.110.1.
> 
> The location of the segmentation fault is ABISysV_x86_64::GetArgumentValues(lldb_private::Thread&, lldb_private::ValueList&) const + 147:
> 
> [  0] 0x000000010432d7ad LLDB`ABISysV_x86_64::GetArgumentValues(lldb_private::Thread&, lldb_private::ValueList&) const + 147 at ABISysV_x86_64.cpp:485:32
>        481 	    addr_t current_stack_argument = sp + 8; // jump over return address
>        482 	    
>        483 	    uint32_t argument_register_ids[6];
>        484 	    
>     -> 485 	    argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
> 
> 
> Someone at Apple Developer Relations (ADR) informed me that unlike gdb, lldb does not have an initial target definition set, and relies on the gdbserver to tell it which registers the gdbserver supports.  This can be done either by responding to 'qRegisterInfo XX' packets or to 'qXfer:features:read:target.xml'.
> 
> ADR also informed me about the plugin.process.gdb-remote.target-definition-file LLDB setting and the example target definitions at http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/
> I can confirm that using either x86_64_linux_target_definition.py or x86_64_target_definition.py fixes the segfault issue.
> 
> Valgrind's gdbserver does not support qRegisterInfo, but it does support qXfer:features:read:target.xml.
> 
> Enabling LLDB's gdb-remote logging, I am seeing that the Valgrind embedded gdbserver is sending:
> 
> target.xml:
> ```
> <?xml version="1.0"?>
> <!-- Copyright (C) 2010 Free Software Foundation, Inc.
> 
>      Copying and distribution of this file, with or without modification,
>      are permitted in any medium without royalty provided the copyright
>      notice and this notice are preserved.  -->
> 
> <!-- AMD64 - core and sse and avx.  -->
> 
> <!DOCTYPE target SYSTEM "gdb-target.dtd">
> <target>
>   <architecture>i386:x86-64</architecture>
>   <xi:include href="64bit-core.xml"/>
>   <xi:include href="64bit-sse.xml"/>
>   <xi:include href="64bit-avx.xml"/>
> </target>
> 
> ```
> 
> 64bit-core.xml:
> ```
> <?xml version="1.0"?>
> <!-- Copyright (C) 2010 Free Software Foundation, Inc.
> 
>      Copying and distribution of this file, with or without modification,
>      are permitted in any medium without royalty provided the copyright
>      notice and this notice are preserved.  -->
> 
> <!DOCTYPE feature SYSTEM "gdb-target.dtd">
> <feature name="org.gnu.gdb.i386.core">
>   <flags id="i386_eflags" size="4">
>     <field name="CF" start="0" end="0"/>
>     <field name="" start="1" end="1"/>
>     <field name="PF" start="2" end="2"/>
>     <field name="AF" start="4" end="4"/>
>     <field name="ZF" start="6" end="6"/>
>     <field name="SF" start="7" end="7"/>
>     <field name="TF" start="8" end="8"/>
>     <field name="IF" start="9" end="9"/>
>     <field name="DF" start="10" end="10"/>
>     <field name="OF" start="11" end="11"/>
>     <field name="NT" start="14" end="14"/>
>     <field name="RF" start="16" end="16"/>
>     <field name="VM" start="17" end="17"/>
>     <field name="AC" start="18" end="18"/>
>     <field name="VIF" start="19" end="19"/>
>     <field name="VIP" start="20" end="20"/>
>     <field name="ID" start="21" end="21"/>
>   </flags>
> 
>   <reg name="rax" bitsize="64" type="int64"/>
>   <reg name="rbx" bitsize="64" type="int64"/>
>   <reg name="rcx" bitsize="64" type="int64"/>
>   <reg name="rdx" bitsize="64" type="int64"/>
>   <reg name="rsi" bitsize="64" type="int64"/>
>   <reg name="rdi" bitsize="64" type="int64"/>
>   <reg name="rbp" bitsize="64" type="data_ptr"/>
>   <reg name="rsp" bitsize="64" type="data_ptr"/>
>   <reg name="r8" bitsize="64" type="int64"/>
>   <reg name="r9" bitsize="64" type="int64"/>
>   <reg name="r10" bitsize="64" type="int64"/>
>   <reg name="r11" bitsize="64" type="int64"/>
>   <reg name="r12" bitsize="64" type="int64"/>
>   <reg name="r13" bitsize="64" type="int64"/>
>   <reg name="r14" bitsize="64" type="int64"/>
>   <reg name="r15" bitsize="64" type="int64"/>
> 
>   <reg name="rip" bitsize="64" type="code_ptr"/>
>   <reg name="eflags" bitsize="32" type="i386_eflags"/>
>   <reg name="cs" bitsize="32" type="int32"/>
>   <reg name="ss" bitsize="32" type="int32"/>
>   <reg name="ds" bitsize="32" type="int32"/>
>   <reg name="es" bitsize="32" type="int32"/>
>   <reg name="fs" bitsize="32" type="int32"/>
>   <reg name="gs" bitsize="32" type="int32"/>
> 
>   <reg name="st0" bitsize="80" type="i387_ext"/>
>   <reg name="st1" bitsize="80" type="i387_ext"/>
>   <reg name="st2" bitsize="80" type="i387_ext"/>
>   <reg name="st3" bitsize="80" type="i387_ext"/>
>   <reg name="st4" bitsize="80" type="i387_ext"/>
>   <reg name="st5" bitsize="80" type="i387_ext"/>
>   <reg name="st6" bitsize="80" type="i387_ext"/>
>   <reg name="st7" bitsize="80" type="i387_ext"/>
> 
>   <reg name="fctrl" bitsize="32" type="int" group="float"/>
>   <reg name="fstat" bitsize="32" type="int" group="float"/>
>   <reg name="ftag" bitsize="32" type="int" group="float"/>
>   <reg name="fiseg" bitsize="32" type="int" group="float"/>
>   <reg name="fioff" bitsize="32" type="int" group="float"/>
>   <reg name="foseg" bitsize="32" type="int" group="float"/>
>   <reg name="fooff" bitsize="32" type="int" group="float"/>
>   <reg name="fop" bitsize="32" type="int" group="float"/>
> </feature>
> 
> ```
> 
> (64bit-sse.xml and 64bit-avx.xml omitted.)
> 
> Can anyone see why this XML target definition would be causing the crash?
> 
> Daniel Trebbien
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list