From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 96811 invoked by alias); 29 May 2015 11:31:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 96798 invoked by uid 89); 29 May 2015 11:31:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 29 May 2015 11:31:07 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 7F3DCB8BBE; Fri, 29 May 2015 11:31:06 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-53.ams2.redhat.com [10.36.116.53]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4TBV2jx001273 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 29 May 2015 07:31:04 -0400 Date: Fri, 29 May 2015 11:31:00 -0000 From: Jan Kratochvil To: Yao Qi Cc: Andreas Schwab , gdb-patches@sourceware.org Subject: Re: [PATCH] Fix wrong assertions Message-ID: <20150529113101.GA15460@host1.jankratochvil.net> References: <87vbg1eg08.fsf@igel.home> <20150513140106.GB3023@host1.jankratochvil.net> <86bnh3pw61.fsf@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <86bnh3pw61.fsf@gmail.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes X-SW-Source: 2015-05/txt/msg00713.txt.bz2 On Fri, 29 May 2015 11:31:18 +0200, Yao Qi wrote: > spend some > time investigating it, but still unable to fully understand the code. I admit the code comments are not too great, I did not notice that when writing them. > (gdb) set debug entry-values 1 > (gdb) bt > tailcall: initial: 0x40052e(a) > tailcall: compare: 0x400527(a) 0x40052e(a) > tailcall: reduced: | 0x40052e(a) > gdb/git/gdb/dwarf2loc.c:834: internal-error: chain_candidate: Assertion `result->callers + result->callees < result->length' failed. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Quit this debugging session? (y or n) y > > I don't know why we need do intersection in chain_candidate, as the > comments say: > > /* Intersect RESULTP with CHAIN to keep RESULTP unambiguous, keep in RESULTP > only top callers and bottom callees which are present in both. GDBARCH is > used only for ENTRY_VALUES_DEBUG. RESULTP is NULL after return if there are > no remaining possibilities to provide unambiguous non-trivial result. > RESULTP should point to NULL on the first (initialization) call. Caller is > responsible for xfree of any RESULTP data. */ > > What do you mean by "ambiguous" here? Is it ambiguous if we can get > more than one call chain path from caller_pc to callee_pc? Yes. > For example, > main tail calls a, a tail call b and c, b and c tail call d, when GDB > unwinds from d, there are two chains, main -> a -> b -> d, and main -> a > -> c -> d. Are they ambiguous by your definition? Those two chains are ambigous as it could be also the other chain. Chain intersecting those two chains is: main -> a -> -> d > Further, what is "partially ambiguous result" in the comments below? The terminology seems bogus there. "partially ambiguous" was meant the chain: main -> a -> -> d An intersection of all possible chains. > /* Determined tail calls for constructing virtual tail call frames. */ > > struct call_site_chain > { > /* Initially CALLERS == CALLEES == LENGTH. For partially ambiguous result > CALLERS + CALLEES < LENGTH. */ > int callers, callees, length; > > /* Variably sized array with LENGTH elements. Later [0..CALLERS-1] contain > top (GDB "prev") sites and [LENGTH-CALLEES..LENGTH-1] contain bottom > (GDB "next") sites. One is interested primarily in the PC field. */ > struct call_site *call_site[1]; > }; > > I am confused by the usage of the variable-sized array call_site, > elements from 0 to CALLERS-1 are top sites, and elements from > LENGTH-CALLEES to LENGTH-1 are bottom sites, so I conclude that > CALLERS-1 < LENGTH-CALLEES, then CALLERS + CALLEES < LENGTH + 1, > then CALLERS + CALLEES =< LENGTH. Is it right? Yes, that is right. 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. Originally the patchset tried to display the "ambiguous" part in backtrace creating a bogus frame there but GDB had too many problems with such a frame. So currently no such frame is created although still backtrace could annotate it somehow there are "ambiguous" frames between these two frames. Jan