via llvm-dev
2021-May-06 17:50 UTC
[llvm-dev] [debug-info] Stack pointer based variable locations
Hello llvm-dev,
I've noticed some behaviour I found surprising with the way that we emit
stack pointer relative
variable locations. It seems that locations defined by DBG_VALUEs that are
written in terms of RSP
(for x86) are terminated by any stack manipulation operations, e.g. pushing
arguments before a
call. Since we know the stack offset at each adjustment it seems like we could
maintain the variable
location by generating location list entries with adjusted RSP offsets.
Here's a source reproducer with clang built at 71597d40e878 (recent), target
x86_64-unknown-linux-gnu).
$ cat test.cpp
void ext(int, int, int, int, int, int, int, int, int, int);
void escape(int*);
int example() {
int local = 0;
escape(&local);
ext(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
local += 2;
return local;
}
$ clang -O2 -g -c test.cpp -o test.o
$ llvm-objdump -d test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_Z7examplev>:
0: 50 pushq %rax
1: c7 44 24 04 00 00 00 00 movl $0, 4(%rsp)
9: 48 8d 7c 24 04 leaq 4(%rsp), %rdi
e: e8 00 00 00 00 callq 0x13
<_Z7examplev+0x13>
13: 31 ff xorl %edi, %edi
15: be 01 00 00 00 movl $1, %esi
1a: ba 02 00 00 00 movl $2, %edx
1f: b9 03 00 00 00 movl $3, %ecx
24: 41 b8 04 00 00 00 movl $4, %r8d
2a: 41 b9 05 00 00 00 movl $5, %r9d
30: 6a 09 pushq $9
32: 6a 08 pushq $8
34: 6a 07 pushq $7
36: 6a 06 pushq $6
38: e8 00 00 00 00 callq 0x3d
<_Z7examplev+0x3d>
3d: 48 83 c4 20 addq $32, %rsp
41: 8b 44 24 04 movl 4(%rsp), %eax
45: 83 c0 02 addl $2, %eax
48: 59 popq %rcx
49: c3 retq
$ llvm-dwarfdump test.o --name local
test.o: file format elf64-x86-64
0x00000047: DW_TAG_variable
DW_AT_location (0x00000000:
[0x0000000000000001, 0x0000000000000009): DW_OP_consts +0,
DW_OP_stack_value
[0x0000000000000009, 0x0000000000000032): DW_OP_breg7 RSP+4
[0x0000000000000045, 0x000000000000004a): DW_OP_reg0 RAX)
DW_AT_name ("local")
DW_AT_decl_file
("/home/och/dev/bugs/scratch/test.cpp")
DW_AT_decl_line (4)
DW_AT_type (0x000000ad "int")
The variable 'local' is not given a location over the interval [32, 45)
even though we
know where it is (RSP+8, RSP+12, ..., back to RSP+4 after the stack adjustment
following the
call). It seems unfortunate to lose variable locations in this way, especially
around call sites. Is
this a deliberate omission, perhaps made in order to save space? Jeremy
mentioned that we do
something similar in prologues/epilogues to avoid generating large location
lists.
Many thanks,
Orlando
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210506/39170e1c/attachment.html>
via llvm-dev
2021-May-06 18:06 UTC
[llvm-dev] [debug-info] Stack pointer based variable locations
In functions without a frame pointer, emitting a one-instruction location range
at every push/pop (for a potentially large set of stack-homed local variables)
does seem like it would take up a lot of space for not much real-world benefit.
On the other hand, having a location range that covers the actual call
instruction (or I suppose, more precisely, its return address) would make the
locals available to the user when the debugger is stopped in the callee, and
that seems *very* valuable.
Wondering what other people think.
--paulr
From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of via
llvm-dev
Sent: Thursday, May 6, 2021 1:51 PM
To: llvm-dev at lists.llvm.org
Subject: [llvm-dev] [debug-info] Stack pointer based variable locations
Hello llvm-dev,
I've noticed some behaviour I found surprising with the way that we emit
stack pointer relative
variable locations. It seems that locations defined by DBG_VALUEs that are
written in terms of RSP
(for x86) are terminated by any stack manipulation operations, e.g. pushing
arguments before a
call. Since we know the stack offset at each adjustment it seems like we could
maintain the variable
location by generating location list entries with adjusted RSP offsets.
Here's a source reproducer with clang built at 71597d40e878 (recent), target
x86_64-unknown-linux-gnu).
$ cat test.cpp
void ext(int, int, int, int, int, int, int, int, int, int);
void escape(int*);
int example() {
int local = 0;
escape(&local);
ext(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
local += 2;
return local;
}
$ clang -O2 -g -c test.cpp -o test.o
$ llvm-objdump -d test.o
test.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_Z7examplev>:
0: 50 pushq %rax
1: c7 44 24 04 00 00 00 00 movl $0, 4(%rsp)
9: 48 8d 7c 24 04 leaq 4(%rsp), %rdi
e: e8 00 00 00 00 callq 0x13
<_Z7examplev+0x13>
13: 31 ff xorl %edi, %edi
15: be 01 00 00 00 movl $1, %esi
1a: ba 02 00 00 00 movl $2, %edx
1f: b9 03 00 00 00 movl $3, %ecx
24: 41 b8 04 00 00 00 movl $4, %r8d
2a: 41 b9 05 00 00 00 movl $5, %r9d
30: 6a 09 pushq $9
32: 6a 08 pushq $8
34: 6a 07 pushq $7
36: 6a 06 pushq $6
38: e8 00 00 00 00 callq 0x3d
<_Z7examplev+0x3d>
3d: 48 83 c4 20 addq $32, %rsp
41: 8b 44 24 04 movl 4(%rsp), %eax
45: 83 c0 02 addl $2, %eax
48: 59 popq %rcx
49: c3 retq
$ llvm-dwarfdump test.o --name local
test.o: file format elf64-x86-64
0x00000047: DW_TAG_variable
DW_AT_location (0x00000000:
[0x0000000000000001, 0x0000000000000009): DW_OP_consts +0,
DW_OP_stack_value
[0x0000000000000009, 0x0000000000000032): DW_OP_breg7 RSP+4
[0x0000000000000045, 0x000000000000004a): DW_OP_reg0 RAX)
DW_AT_name ("local")
DW_AT_decl_file
("/home/och/dev/bugs/scratch/test.cpp")
DW_AT_decl_line (4)
DW_AT_type (0x000000ad "int")
The variable 'local' is not given a location over the interval [32, 45)
even though we
know where it is (RSP+8, RSP+12, ..., back to RSP+4 after the stack adjustment
following the
call). It seems unfortunate to lose variable locations in this way, especially
around call sites. Is
this a deliberate omission, perhaps made in order to save space? Jeremy
mentioned that we do
something similar in prologues/epilogues to avoid generating large location
lists.
Many thanks,
Orlando
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20210506/5905dc68/attachment.html>
pawel k. via llvm-dev
2021-May-07 06:05 UTC
[llvm-dev] [debug-info] Stack pointer based variable locations
Hello, If its really so, if i could, id vote for implementing full debuginfo as default and maybe left optimized path as optional. If that matters to anyone. It will help in tracking locals while debugging. Best regards, Pawel Kunio czw., 6.05.2021, 19:51 użytkownik via llvm-dev <llvm-dev at lists.llvm.org> napisał:> Hello llvm-dev, > > > > I've noticed some behaviour I found surprising with the way that we emit > stack pointer relative > > variable locations. It seems that locations defined by DBG_VALUEs that are > written in terms of RSP > > (for x86) are terminated by any stack manipulation operations, e.g. > pushing arguments before a > > call. Since we know the stack offset at each adjustment it seems like we > could maintain the variable > > location by generating location list entries with adjusted RSP offsets. > > > > Here's a source reproducer with clang built at 71597d40e878 (recent), > target > > x86_64-unknown-linux-gnu). > > > > $ cat test.cpp > > void ext(int, int, int, int, int, int, int, int, int, int); > > void escape(int*); > > int example() { > > int local = 0; > > escape(&local); > > ext(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); > > local += 2; > > return local; > > } > > > > $ clang -O2 -g -c test.cpp -o test.o > > > > $ llvm-objdump -d test.o > > test.o: file format elf64-x86-64 > > Disassembly of section .text: > > 0000000000000000 <_Z7examplev>: > > 0: 50 pushq %rax > > 1: c7 44 24 04 00 00 00 00 movl $0, 4(%rsp) > > 9: 48 8d 7c 24 04 leaq 4(%rsp), %rdi > > e: e8 00 00 00 00 callq 0x13 > <_Z7examplev+0x13> > > 13: 31 ff xorl %edi, %edi > > 15: be 01 00 00 00 movl $1, %esi > > 1a: ba 02 00 00 00 movl $2, %edx > > 1f: b9 03 00 00 00 movl $3, %ecx > > 24: 41 b8 04 00 00 00 movl $4, %r8d > > 2a: 41 b9 05 00 00 00 movl $5, %r9d > > 30: 6a 09 pushq $9 > > 32: 6a 08 pushq $8 > > 34: 6a 07 pushq $7 > > 36: 6a 06 pushq $6 > > 38: e8 00 00 00 00 callq 0x3d > <_Z7examplev+0x3d> > > 3d: 48 83 c4 20 addq $32, %rsp > > 41: 8b 44 24 04 movl 4(%rsp), %eax > > 45: 83 c0 02 addl $2, %eax > > 48: 59 popq %rcx > > 49: c3 retq > > > > $ llvm-dwarfdump test.o --name local > > test.o: file format elf64-x86-64 > > 0x00000047: DW_TAG_variable > > DW_AT_location (0x00000000: > > [0x0000000000000001, 0x0000000000000009): DW_OP_consts > +0, DW_OP_stack_value > > [0x0000000000000009, 0x0000000000000032): DW_OP_breg7 > RSP+4 > > [0x0000000000000045, 0x000000000000004a): DW_OP_reg0 RAX) > > DW_AT_name ("local") > > DW_AT_decl_file > ("/home/och/dev/bugs/scratch/test.cpp") > > DW_AT_decl_line (4) > > DW_AT_type (0x000000ad "int") > > > > The variable 'local' is not given a location over the interval [32, 45) > even though we > > know where it is (RSP+8, RSP+12, ..., back to RSP+4 after the stack > adjustment following the > > call). It seems unfortunate to lose variable locations in this way, > especially around call sites. Is > > this a deliberate omission, perhaps made in order to save space? Jeremy > mentioned that we do > > something similar in prologues/epilogues to avoid generating large > location lists. > > Many thanks, > > Orlando > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210507/c189fbc4/attachment.html>