Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

LLDB reports out-of-scope variables as available at O3 #44872

Open Quuxplusone opened 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR45902
Status CONFIRMED
Importance P enhancement
Reported by Luca Massarelli (massarelli@diag.uniroma1.it)
Reported on 2020-05-13 06:33:46 -0700
Last modified on 2020-06-16 15:26:59 -0700
Version unspecified
Hardware PC Linux
CC ditaliano@apple.com, jan@jankratochvil.net, jdevlieghere@apple.com, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Debug information seems wrong at O3.
At line 7 variable j and k should not be visible.

$ cat a.c
int a[56];
int b ;
int c[1] ;
int d[1][9][8] ;
void
e (f) {
 b =
 b  & 5 ^
 a[b ^ f ];
}

void h (f) {
 long g = f;
 {
        b = b  & 5 ^ a[b ];
        b = b  & 5 ^ a[b ^ 8 ];
        b = b  & 5 ^ a[b ^ g ];
        b = b  & 5 ^ a[b ^ g ];
  }
  e (g & 5);
  e (g>>48 & 5);
  e (g>>56 & 5);
 }

int main ()
{
    int i, j, k,  dm ;
    {
            d[0][1][0] = 0;
    }
    printf("ciao");
    h(0);
    j = 0;
    for (; j < 9; j++)
    {
        k = 0;
        for (; k < 8; k++)
            h(d[0][j][k]);
    }
}

$ clang -v
clang version 11.0.0 (https://github.com/llvm/llvm-project.git
c25b20c0f6c13d68dbc2e185764082d61ae4a132)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/local/bin/../lib/gcc/x86_64-pc-linux-
gnu/11.0.0
Selected GCC installation: /usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/11.0.0
Candidate multilib: .;@m64
Selected multilib: .;@m64

$ lldb -v
lldb version 11.0.0
  clang revision c25b20c0f6c13d68dbc2e185764082d61ae4a132
  llvm revision c25b20c0f6c13d68dbc2e185764082d61ae4a132

$ clang -O3 -g -o opt a.c

$ lldb opt
(lldb) target create "opt"
Current executable set to 'opt' (x86_64).
(lldb) b -l 7
Breakpoint 1: 3 locations.
(lldb) r
Process 60 launched: 'opt' (x86_64)
Process 60 stopped
* thread #1, name = 'opt', stop reason = breakpoint 1.3
    frame #0: 0x0000000000400618 opt`main [inlined] e(f=0) at a.c:7:4
   4    int d[1][9][8] ;
   5    void
   6    e (f) {
-> 7     b =
   8     b  & 5 ^
   9     a[b ^ f ];
   10   }
(lldb) frame var
(int) f = 0
(lldb) s
Process 60 stopped
* thread #1, name = 'opt', stop reason = step in
    frame #0: 0x000000000040061e opt`main at a.c:7:4
   4    int d[1][9][8] ;
   5    void
   6    e (f) {
-> 7     b =
   8     b  & 5 ^
   9     a[b ^ f ];
   10   }
(lldb) frame var
(int) j = 0
(int) k = 0
(int) i = <no location, value may have been optimized out>

(int) dm = <no location, value may have been optimized out>

(lldb)

$ gdb opt
Breakpoint 1, e (f=0) at a.c:7
7        b =
(gdb) frame var
#0  e (f=0) at a.c:7
7        b =
(gdb) bt
#0  e (f=0) at a.c:7
#1  h (f=0) at a.c:22
#2  main () at a.c:32
(gdb) s
main () at a.c:38
38                  h(d[0][j][k]);
(gdb) frame var
#0  main () at a.c:38
38                  h(d[0][j][k]);
(gdb) c
Continuing.
ciao[Inferior 1 (process 153) exited normally]
(gdb)
Quuxplusone commented 4 years ago
The debug info (generated DWARF) looks reasonable, offhand; there's a lot
of inlining going on, which I didn't fully verify against the instructions,
but I see that local variables "j" and "k" have ranges that encompass the
inlined functions.  That seems quite reasonable as a description of the
generated instructions.

I guess the question is whether lldb should report the full truth about
the set of available variables, or whether it should pretend that variables
from the containing scope are unavailable.  I doubt there is broad consensus
on the answer to that question, but it's up to the debugger folks really.
Quuxplusone commented 4 years ago
Modified the title from "Wrong debug information at O3" to "LLDB reports
out-of-scope variables as available at O3" to avoid the implication that
the compiler is doing something wrong.  (I don't think it is.)
Quuxplusone commented 4 years ago

Luca, any chance you can try if you this can be reproduced with gdb ?

Quuxplusone commented 4 years ago

This can't be repro'd with gdb. It's a bug in lldb, very likely.

Quuxplusone commented 4 years ago
(1)
LLDB 'frame var' equals to GDB 'info args' + 'info locals'.

(2)
LLDB step and GDB step end at a different address as LLDB ignores .debug_line
is_stmt. It is questionable whether it is a LLDB bug as clang AFAIK does not
produce much useful is_stmts anyway (Bug 46032 Comment 3).

After fixing (1)+(2) both GDB and LLDB show the same variables list:
--------------------------------------------------------------------------------
(~/redhat/llvm-monorepo-clangassert/bin/clang -O3 -g -o lldb45902
lldb45902.c;~/redhat/llvm-monorepo-clangassert/bin/lldb ./lldb45902 -o 'b 7' -o
r -o s -o bt -o 'p/x $pc' -o 'frame var' -o quit;gdb -q ./lldb45902 -ex 'set
trace-commands on' -ex 'b *0x40127e' -ex r -ex bt -ex 'info args' -ex 'info
locals' -batch)
lldb45902.c:31:5: warning: implicitly declaring library function 'printf' with
type 'int (const char *, ...)' [-Wimplicit-function-declaration]
    printf("ciao");
    ^
lldb45902.c:31:5: note: include the header <stdio.h> or explicitly provide a
declaration for 'printf'
1 warning generated.
(lldb) target create "./lldb45902"
Current executable set to '/home/jkratoch/t/lldb45902' (x86_64).
(lldb) b 7
Breakpoint 1: 3 locations.
(lldb) r
Process 2391165 stopped
* thread #1, name = 'lldb45902', stop reason = breakpoint 1.3
    frame #0: 0x0000000000401278 lldb45902`main [inlined] e(f=0) at lldb45902.c:7:4
   4    int d[1][9][8] ;
   5    void
   6    e (f) {
-> 7     b =
   8     b  & 5 ^
   9     a[b ^ f ];
   10   }

Process 2391165 launched: '/home/jkratoch/t/lldb45902' (x86_64)
(lldb) s
Process 2391165 stopped
* thread #1, name = 'lldb45902', stop reason = step in
    frame #0: 0x000000000040127e lldb45902`main at lldb45902.c:7:4
   4    int d[1][9][8] ;
   5    void
   6    e (f) {
-> 7     b =
   8     b  & 5 ^
   9     a[b ^ f ];
   10   }

(lldb) bt
* thread #1, name = 'lldb45902', stop reason = step in
  * frame #0: 0x000000000040127e lldb45902`main at lldb45902.c:7:4
    frame #1: 0x00007ffff7dea042 libc.so.6`__libc_start_main(main=(lldb45902`main at lldb45902.c:26), argc=1, argv=0x00007fffffffcfd8, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffcfc8) at libc-start.c:308:16
    frame #2: 0x000000000040106e lldb45902`_start + 46
(lldb) p/x $pc
(unsigned long) $0 = 0x000000000040127e
(lldb) frame var
(int) j = 0
(int) k = 0
(int) i = <no location, value may have been optimized out>

(int) dm = <no location, value may have been optimized out>

(lldb) quit
+b *0x40127e
Breakpoint 1 at 0x40127e: file lldb45902.c, line 7.
+r

Breakpoint 1, 0x000000000040127e in main () at lldb45902.c:7
7    b =
+bt
#0  0x000000000040127e in main () at lldb45902.c:7
+info args
No arguments.
+info locals
j = 0
k = 0
i = <optimized out>
dm = <optimized out>
--------------------------------------------------------------------------------

(3)
There is rather a bug in clang that 0x40127e belongs in .debug_info to main()
but in .debug_line it still belongs to inlined e() which makes the debugger
output confusing. I haven't filed this bug to clang (yet).

--------------------------------------------------------------------------------
0x000001de:     DW_TAG_inlined_subroutine
                  DW_AT_abstract_origin (0x0000016b "h")
                  DW_AT_low_pc  (0x0000000000401212)
                  DW_AT_high_pc (0x000000000040127e)
                                             ^^^^^^
0x0000023a:       DW_TAG_inlined_subroutine
                    DW_AT_abstract_origin       (0x000000d9 "e")
                    DW_AT_low_pc        (0x000000000040126b)
                    DW_AT_high_pc       (0x000000000040127e)
                                                     ^^^^^^
Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x0000000000401278      7      4      1   0             0  is_stmt
            ^^^^^^      ^
0x0000000000401280      0      0      1   0             0
--------------------------------------------------------------------------------