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

Daniel Trebbien via lldb-dev lldb-dev at lists.llvm.org
Sat Dec 5 05:07:19 PST 2015


Hello Greg,

Thank you very much for this explanation.  It makes perfect sense to me now
the reason for the crash at ABISysV_x86_64.cpp:485, and that supplying the
generic register information will solve the problem.

Testing out the following, the crash no longer occurs:

  <reg name="rax" bitsize="64" type="int64" group="general"/>
  <reg name="rbx" bitsize="64" type="int64" group="general"/>
  <reg name="rcx" bitsize="64" type="int64" group="general" altname="arg4"
generic="arg4"/>
  <reg name="rdx" bitsize="64" type="int64" group="general" altname="arg3"
generic="arg3"/>
  <reg name="rsi" bitsize="64" type="int64" group="general" altname="arg2"
generic="arg2"/>
  <reg name="rdi" bitsize="64" type="int64" group="general" altname="arg1"
generic="arg1"/>
  <reg name="rbp" bitsize="64" type="data_ptr" group="general" altname="fp"
generic="fp"/>
  <reg name="rsp" bitsize="64" type="data_ptr" group="general" altname="sp"
generic="sp"/>
  <reg name="r8" bitsize="64" type="int64" group="general" altname="arg5"
generic="arg5"/>
  <reg name="r9" bitsize="64" type="int64" group="general" altname="arg6"
generic="arg6"/>
  <reg name="r10" bitsize="64" type="int64" group="general"/>
  <reg name="r11" bitsize="64" type="int64" group="general"/>
  <reg name="r12" bitsize="64" type="int64" group="general"/>
  <reg name="r13" bitsize="64" type="int64" group="general"/>
  <reg name="r14" bitsize="64" type="int64" group="general"/>
  <reg name="r15" bitsize="64" type="int64" group="general"/>

  <reg name="rip" bitsize="64" type="code_ptr" altname="pc" generic="pc"/>
  <reg name="eflags" bitsize="32" type="i386_eflags" altname="flags"
generic="flags"/>


Daniel Trebbien


On Fri, Dec 4, 2015 at 1:55 PM, Greg Clayton <gclayton at apple.com> wrote:

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


More information about the lldb-dev mailing list