[llvm-bugs] [Bug 39752] New: [DebugInfo] Location list entries expressed in caller-saved registers are incompatible for unwinding with GDB
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Nov 22 04:57:55 PST 2018
https://bugs.llvm.org/show_bug.cgi?id=39752
Bug ID: 39752
Summary: [DebugInfo] Location list entries expressed in
caller-saved registers are incompatible for unwinding
with GDB
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: DebugInfo
Assignee: unassignedbugs at nondot.org
Reporter: david.stenberg at ericsson.com
CC: jdevlieghere at apple.com, keith.walker at arm.com,
llvm-bugs at lists.llvm.org,
paul_robinson at playstation.sony.com
(This might be a known issue.)
Consider the following example:
int global;
__attribute__((noinline)) void fn3(int p3) {
global = p3;
/* Thrash parameter register. */
__asm volatile ("movl $999, %%edi" : : : "%edi");
}
__attribute__((noinline)) int fn2(int p2) {
global = p2;
fn3(p2);
return 0;
}
__attribute__((noinline)) int fn1(int p1) {
global = p1;
fn2(p1);
return 0;
}
int main() {
return fn1(111);
}
compiled using:
clang -target x86_64 -O3 -g test.c -o test.out
For fn2 we emit the following assembly:
(gdb) disas fn2
Dump of assembler code for function fn2:
0x0000000000400500 <+0>: push %rbp
0x0000000000400501 <+1>: mov %rsp,%rbp
0x0000000000400504 <+4>: mov %edi,0x200b2a(%rip) #
0x601034 <global>
0x000000000040050a <+10>: callq 0x4004e0 <fn3>
0x000000000040050f <+15>: xor %eax,%eax
0x0000000000400511 <+17>: pop %rbp
0x0000000000400512 <+18>: retq
End of assembler dump.
and the following location list for p2:
(gdb) info addr p2
Symbol "p2" is multi-location:
Range 0x400500-0x40050f: a variable in $rdi
As seen, we say that p2 is valid during the call. The same situation holds for
fn1 and p1.
When unwinding with GDB, which (at least for x86-64) relies on the DWARF
information to tell if a register is caller-saved, we will print invalid values
for the unwound p1 and p2 variables after we have thrashed $edi in fn3:
(gdb) disas
Dump of assembler code for function fn3:
0x00000000004004e0 <+0>: push %rbp
0x00000000004004e1 <+1>: mov %rsp,%rbp
0x00000000004004e4 <+4>: mov %edi,0x200b4a(%rip) #
0x601034 <global>
0x00000000004004ea <+10>: mov $0x3e7,%edi
=> 0x00000000004004ef <+15>: pop %rbp
0x00000000004004f0 <+16>: retq
End of assembler dump.
(gdb) bt
#0 fn3 (p3=<optimized out>) at test.c:11
#1 0x000000000040050f in fn2 (p2=999) at test.c:15
#2 0x000000000040052f in fn1 (p1=999) at test.c:21
#3 0x000000000040054e in main () at test.c:26
This is not an issue with LLDB, as it is ABI-aware, and does not print out any
caller-saved registers in outer frames.
When unwinding, GDB and LLDB assume that the address is (return_address - 1)
when printing variables, etc. GCC seems to utilize this fact to get the
location expression correct for the caller-saved described variable, by ending
the location list entry right before that:
GCC 5.4.0 output:
(gdb) disas fn2
Dump of assembler code for function fn2:
0x0000000000400500 <+0>: mov %edi,0x200b2e(%rip) #
0x601034 <global>
0x0000000000400506 <+6>: callq 0x4004f0 <fn3>
0x000000000040050b <+11>: xor %eax,%eax
0x000000000040050d <+13>: retq
End of assembler dump.
(gdb) info addr p2
Symbol "p2" is multi-location:
Range 0x400500-0x40050a: a variable in $rdi
Range 0x40050a-0x40050e: a complex DWARF expression:
0: DW_OP_GNU_entry_value
2: DW_OP_reg5 [$rdi]
3: DW_OP_stack_value
As seen, the first address after the call is 0x40050b, but the (exclusive)
ending address for p2 in the location list entry is 0x40050a.
Would it make sense to adapt LLVM to this behavior to be GDB compatible? Or is
it an acceptable incompatibility?
If we instead want to go the CFI route, maybe the compiler could emit
DW_CFA_undefined for caller-saved registers when they are clobbered?
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181122/efe65f3d/attachment.html>
More information about the llvm-bugs
mailing list