From e0619de699ae6e86d8b93fa96a7668aef2e9636a Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Mon, 1 Jun 2015 14:02:34 +0200 Subject: PR symtab/18392 Initially there is some chain (let's say the longest one but that doe snot matter). Consequently its elements from the middle are being removed and there remains only some few unambiguous top and bottom ones. The original idea why the comparison should be sharp ("<") was that if there are multiple chains like (0xaddr show jmp instruction address): main(0x100) -> a(0x200) -> d(0x400) main(0x100) -> a(0x200) -> c(0x300) -> d(0x400) then - such situation cannot exist - if two jmp instructions in "a" have the same address they must also jump to the same address (*). (*) jump to a computed address would be never considered for the DWARF tail-call records. So there could be: main(0x100) -> a(0x200) -> d(0x400) main(0x100) -> a(0x270) -> c(0x300) -> d(0x400) But then "a" frame itself is ambiguous and it must not be displayed. I did not realize that there can be self-tail-call: main(0x100) -> a(0x200) -> d(0x400) main(0x100) -> a(0x280) -> a(0x200) -> d(0x400) which intersects to: main(0x100) -> ? -> a(0x200) -> d(0x400) And so if the first chain was chosen the main(0x100) -> a(0x200) -> d(0x400) then the final intersection has callers+callees==length. > for example, if CALLERS is 3 and > CALLEES is 2, what does the chain look like? main(0x100) -> x(0x150) -> y(0x200) -> ? -> a(0x200) -> d(0x400) And if LENGTH is 7 then: call_site[0] = main(0x100) call_site[1] = x(0x150) call_site[2] = y(0x200) call_site[3] = garbage call_site[4] = garbage call_site[5] = a(0x200) call_site[6] = d(0x400) gdb/ChangeLog 2015-06-01 Andreas Schwab Jan Kratochvil PR symtab/18392 * dwarf2-frame-tailcall.c (pretended_chain_levels): Correct assertion. * dwarf2loc.c (chain_candidate): Likewise. gdb/testsuite/ChangeLog 2015-06-01 Jan Kratochvil PR symtab/18392 * gdb.arch/amd64-tailcall-self.S: New file. * gdb.arch/amd64-tailcall-self.c: New file. * gdb.arch/amd64-tailcall-self.exp: New file. --- gdb/dwarf2-frame-tailcall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gdb/dwarf2-frame-tailcall.c') diff --git a/gdb/dwarf2-frame-tailcall.c b/gdb/dwarf2-frame-tailcall.c index b412a5b..f964ab2 100644 --- a/gdb/dwarf2-frame-tailcall.c +++ b/gdb/dwarf2-frame-tailcall.c @@ -197,7 +197,7 @@ pretended_chain_levels (struct call_site_chain *chain) return chain->length; chain_levels = chain->callers + chain->callees; - gdb_assert (chain_levels < chain->length); + gdb_assert (chain_levels <= chain->length); return chain_levels; } -- cgit v1.1