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@3fe22b6ae7d566cf > movsd qword ptr [esp+8], xmm0 ; loc_1 > push 3 ; c > push 2 ; b > push 1 ; a > call j_?bar@@YAXDFH@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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits