[lldb-dev] DW_OP_deref handling

Davide Italiano via lldb-dev lldb-dev at lists.llvm.org
Thu Oct 11 10:52:29 PDT 2018


Hi Greg,
I have this issue that I suspect is a bug in lldb’s handling of DW_OP_deref.
I wasn’t able to craft an easy C++ testcase, so I’ll start from my
motivating (swift) example.

Given the following code:

func use<T>(_ t : T) {}
func single<T>(_ t : T) {
  let x = t
  use(x)
}
let s = "hello"
single(s)

The IR emitted for the local binding `x` in `single<T>` is an alloca
containing the address of `x`. Hence, the DWARF, correctly contains a
DW_OP_deref expression, i.e.:

0x000000da:                 TAG_variable [9]
                             AT_location( fbreg -16, deref )
                             AT_name( "x" )
                             AT_decl_file(
"/Users/dcci/work/swift/build/Ninja-RelWithDebInfoAssert+stdlib-RelWithDebInfo/swift-macosx-x86_64/bin/pat.swift"
)
                             AT_decl_line( 4 )
                             AT_type( {0x00000204} ( $sxD ) )

When I debug this with lldb, I expect lldb to print the value that’s
pointed by %rbp - 16,
i.e.
(lldb) register read $rbp
     rbp = 0x00007ffeefbff860

(lldb) mem read 0x00007ffeefbff850
0x7ffeefbff850: 10 f8 bf ef fe 7f 00 00 b8 32 4d 00 01 00 00 00
.????...?2M.....
0x7ffeefbff860: c0 f8 bf ef fe 7f 00 00 64 09 00 00 01 00 00 00
?????...d.......

So, the value that I expected to be printed is 0x7ffeefbff810.

What I instead see in the debugger is:
(T) x = <read memory from 0xe500000000000000 failed (0 of 16 bytes read)>

The value `0xe500000000000000` happens to be the value that’s pointed
by the address 0x7ffeefbff810, that is:

(lldb) mem read 0x7ffeefbff810
0x7ffeefbff810: 00 00 00 00 00 00 00 e5 68 65 6c 6c 6f 00 00 00
.......?hello...
0x7ffeefbff820: 05 00 00 00 00 00 00 00 40 32 4d 00 01 00 00 00
........ at 2M.....

Is this an expected behavior? I did expect DW_OP_deref to just do a
single dereference and not two. It looks like when we call
`UpdateValue()` in lldb we do have the correct value in `m_value`, but
GetPointerValue() ends up printing the value that’s *pointed by*
what’s in `m_value`, i.e.

    m_integer = {
      U = {
        VAL = 0x00007ffeefbff810
        pVal = 0x00007ffeefbff810
      }

as this is a LoadAddress. Greg, as you wrote this code (and touched it
last), what do you expect to be the correct semantic here?

Removing a dereference from DW_OP_deref in the DWARFASTParser works
around the issue, but I’m fairly sure it’s the incorrect fix. Are we
maybe setting the value type incorrectly?


Best,


—

Davide


More information about the lldb-dev mailing list