[Lldb-commits] [PATCH] D53086: [PDB] Fix flaky `variables-locations.test` after PR38857

Zachary Turner via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 11 20:26:12 PDT 2018


zturner added a comment.

In https://reviews.llvm.org/D53086#1261697, @aleksandr.urakov wrote:

> Thanks a lot for so detailed answer, it helps!
>
> So we need to parse a FPO program and to convert it in a DWARF expression too. The problem here (in the DIA case) is that I don't know how to retrieve the required FPO range (we have a symbol context when creating a variable, but it seems that it doesn't contain enough information).


I think the `SymbolContext` should have enough information.  As long as you can find the `PDBSymbolFunction` for the current frame, that gives you the range of the function, and the `IDiaSymbol` for the variable should give you the important info like register, offset, etc.

> As for the raw PDB case, can the same `S_LOCAL` have several `S_DEFRANGE_FRAMEPOINTER_REL` records for several ranges?  If so, then the problem exists for the raw PDB case too, but there's a solution: we can combine processing of all `S_DEFRANGE_FRAMEPOINTER_REL` records in the single DWARF expression (and call the required FPO program depending on current `eip`).

Not as far as I know.  There should be only 1.  But note that is not the only type of record that can appear, there are several others.  But basically there will be `S_LOCAL` followed by 1 record describing the location.

> The interesting moment here is that MSVC doesn't emit correct information for locals. For the program `aaa.cpp`:
> 
>   void bar(char a, short b, int c) { }
>   
>   void __fastcall foo(short arg_0, float arg_1) {
>     char loc_0 = 'x';
>     double __declspec(align(8)) loc_1 = 0.5678;
>     bar(1, 2, 3);
>   }
>   
>   int main(int argc, char *argv[]) {
>     foo(1111, 0.1234);
>     return 0;
>   }
> 
> 
> compiled with `cl /Zi /Oy aaa.cpp` we have the next disassembly of `foo`:
> 
>   push    ebp
>   mov     ebp, esp
>   and     esp, 0FFFFFFF8h
>   sub     esp, 10h
>   mov     [esp+4], cx     ; arg_0
>   mov     byte ptr [esp+3], 'x' ; loc_0
>   movsd   xmm0, ds:__real at 3fe22b6ae7d566cf
>   movsd   qword ptr [esp+8], xmm0 ; loc_1
>   push    3               ; c
>   push    2               ; b
>   push    1               ; a
>   call    j_?bar@@YAXDFH at Z ; bar(char,short,int)
>   add     esp, 0Ch
>   mov     esp, ebp
>   pop     ebp
>   retn    4
> 
> 
> but MSVC emits the next info about locals:
> 
>   296 | S_GPROC32 [size = 44] `foo`
>         parent = 0, end = 452, addr = 0001:23616, code size = 53
>         type = `0x1003 (void (short, float))`, debug start = 14, debug end = 47, flags = has fp
>   340 | S_FRAMEPROC [size = 32]
>         size = 16, padding size = 0, offset to padding = 0
>         bytes of callee saved registers = 0, exception handler addr = 0000:0000
>         local fp reg = VFRAME, param fp reg = EBP
>         flags = has async eh | opt speed
>   372 | S_REGREL32 [size = 20] `arg_0`
>         type = 0x0011 (short), register = ESP, offset = 4294967284
>   392 | S_REGREL32 [size = 20] `arg_1`
>         type = 0x0040 (float), register = EBP, offset = 8
>   412 | S_REGREL32 [size = 20] `loc_1`
>         type = 0x0041 (double), register = ESP, offset = 4294967288
>   432 | S_REGREL32 [size = 20] `loc_0`
>         type = 0x0070 (char), register = ESP, offset = 4294967283
>   452 | S_END [size = 4]
>    
> 
> so neither LLDB nor Visual Studio show valid values (except for `arg_1`).

Generally speaking, if you're using `/Oy` all bets are off and good luck :)

Interestingly, clang actually gets this right but we use a totally different CodeView record.

  $ llvm-pdbutil.exe dump -symbols -modi=0 foo-clang.pdb | grep -A 4 loc_1
       392 | S_LOCAL [size = 16] `loc_1`
             type=0x0041 (double), flags = none
       408 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]
             offset = -16, range = [0001:0075,+51)
             gaps = 2
  
  D:\src\llvmbuild\ninja-release-x64>

If you try to debug the same program in VS built with clang with the exact same command line, it will work.

I need to study the disassembly and FPO program of the cl.exe version some more to decide if the bug is in the compiler or the debugger, but I think the bug is in the compiler.

It's funny because our optimized debug info is not very good, so I'm surprised there's a case where we're better than MSVC here :)


https://reviews.llvm.org/D53086





More information about the lldb-commits mailing list