From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2049 invoked by alias); 24 Sep 2013 12:56:41 -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 2038 invoked by uid 89); 24 Sep 2013 12:56:41 -0000 Received: from mms2.broadcom.com (HELO mms2.broadcom.com) (216.31.210.18) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 24 Sep 2013 12:56:41 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL,BAYES_00,RDNS_NONE autolearn=no version=3.3.2 X-HELO: mms2.broadcom.com Received: from [10.9.208.57] by mms2.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.5)); Tue, 24 Sep 2013 05:50:02 -0700 X-Server-Uuid: 4500596E-606A-40F9-852D-14843D8201B2 Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS08.corp.ad.broadcom.com (10.9.208.57) with Microsoft SMTP Server (TLS) id 14.1.438.0; Tue, 24 Sep 2013 05:56:29 -0700 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.1.438.0; Tue, 24 Sep 2013 05:56:29 -0700 Received: from [10.177.73.74] (unknown [10.177.73.74]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 5F0AB246A4; Tue, 24 Sep 2013 05:56:28 -0700 (PDT) Message-ID: <52418BFA.6030405@broadcom.com> Date: Tue, 24 Sep 2013 12:56:00 -0000 From: "Andrew Burgess" User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20130801 Thunderbird/17.0.8 MIME-Version: 1.0 To: "Pedro Alves" cc: gdb-patches@sourceware.org, "Eli Zaretskii" , "Mark Kettenis" Subject: Re: [PATCH] Always print call-clobbered registers in outer frames. References: <5200F55E.2050308@broadcom.com> <201308061318.r76DIMdd016369@glazunov.sibelius.xs4all.nl> <5200FECF.7030304@broadcom.com> <201308061541.r76FfYQN022875@glazunov.sibelius.xs4all.nl> <520142D9.4030304@redhat.com> <5208E3C8.7060107@broadcom.com> <5208E938.3080305@redhat.com> <201308122001.r7CK1862007934@glazunov.sibelius.xs4all.nl> <520E7255.7080206@redhat.com> <5211F25A.5070907@broadcom.com> <5228B15F.7060108@redhat.com> <5228B2D8.7060604@broadcom.com> <5237567C.8050406@redhat.com> <5239B2D8.4030403@broadcom.com> <5239CCB3.605@redhat.com> <83zjram6sw.fsf@gnu.org> <201309182047.r8IKlOGA010471@glazunov.sibelius.xs4all.nl> <83fvt1mems.fsf@gnu.org> <523B2D39.8060303@redhat.com> <523B4D48.3050206@redhat.com> <523C2B6F.4000007@broadcom.com> <5241805D.3020800@redhat.com> In-Reply-To: <5241805D.3020800@redhat.com> Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2013-09/txt/msg00850.txt.bz2 On 24/09/2013 1:06 PM, Pedro Alves wrote: > On 09/20/2013 12:03 PM, Andrew Burgess wrote: >> On 19/09/2013 8:15 PM, Pedro Alves wrote: >>> Like this... >>> >>> -------------- >>> Subject: [PATCH] Always print call-clobbered registers in outer frames. >>> >>> With older GCCs, when some variable lived on a call-clobbered register >>> just before a call, GCC would mark such register as undefined across >>> the function call, with DW_CFA_undefined. This is interpreted by the >>> debugger as meaning the variable is optimized out at that point. That >>> is, if the user does "up", and tries to print the variable. >>> >>> Newer GCCs stopped doing that. They now just don't emit a location >>> for the variable, resulting in GDB printing "" all the >>> same. (See .) >>> >>> The difference is that with binaries produced by those older GCCs, GDB >>> will also print the registers themselves (info registers / p $reg) as >>> "". This is confusing. >> >> I agree with you 100% on this, however, I feel we're merging two >> arguments together here. The reason gdb prints is >> really because values only support 3 states: available, unavailable, and >> optimized-out, we use optimized-out for the DW_CFA_undefined state. >> >> What we really need is a new state, lets call it not-saved, we don't >> necessarily need to have extra state inside the value object to model >> this, we might (as in your original patch) be able to derive this state, >> but this is a state that a register can be in. > > Luckily, I already have a patch that does that. :-) > >>> This patch makes GDB always follow this rule (which is what the >>> heuristic unwinders usually do by default): >>> >>> The values of call-clobbered registers in the outer frame, if not >>> saved by the caller, are defined as being the values the registers >>> would have if the inner frame was to return immediately. >> >> You're right that most targets seem to follow this rule, which seems odd >> to me, however I think that the rs600, s390, sh, and tic6x targets >> don't, they set the call-clobbered registers to DW_CFA_undefined in >> their dwarf2_frame_set_init_reg functions, this seems much more sensible >> to me, assuming that call-clobbered registers have not been used seems >> .... odd. > > Okay. Reading more code, and investigating the history behind it > convinced me that that is indeed the direction GDB was currently > heading. > >> >>> >>> The documentation is updated to more clearly explain this. >>> >>> IOW, ignore DW_CFA_undefined _when printing frame registers_, but >>> not when printing variables. This translates to, if value of a frame >>> register, comes out as optimized out (that's what "not saved" >>> lval_register values end up as), fetch it from the next frame. >> >> I really think this is going to confuse users, we're basically saying >> that call-clobbered registers are assumed to never be clobbered .... we >> might get away with this from very shallow call-stacks, but for very >> deep stacks this seems very unlikely, in which case, a user switches to >> some outer stack and does "info registers", how does he know which >> registers gdb has carefully retrieved and are correct, and which are >> just random values fetched from some inner frame? > > I had toyed with something like Doug suggested. See my > other reply to Mark. > >> My question then is, what makes you believe the inner, possibly >> call-clobbered value is right? > > Nothing, of course. It's just a choice -- either assume it's right, > and somehow warn the user it may not be right through some other means; > or, assume it's not right, and hide the value from the user. If > GDB is wrong, the user can still fetch the value, though it'll take > more steps (up+p $reg+down, etc.). It might still be a good idea to > provide an easier way to "flatten" the not-saved registers as > convenience for that, not sure). I guess the thing I'm struggling with is why would we /ever/ assume the value in an inner frame is correct? Sure, for very shallow stacks on machines with a non-small register set there's a reasonable chance the value is correct, but in any other case I seriously don't see how taking the value from an inner frame is any better than picking a random number. > > (skipping answering some of the other points as I believe I've answered > them in my other reply to Mark). > >>> -However, @value{GDBN} must deduce where registers are saved, from the machine >>> -code generated by your compiler. If some registers are not saved, or if >>> -@value{GDBN} is unable to locate the saved registers, the selected stack >>> -frame makes no difference. >>> +Most ABIs reserve some registers as ``scratch'' registers that don't >>> +need to be saved by the caller (a.k.a. caller-saved or call-clobbered >>> +registers). It may therefore not be possible for @value{GDBN} to know >> >> I think here you should say "Most ABIs reserve some registers as >> ``scratch'' registers that don't need to be saved by the callee" >> (callee, not caller). > > Indeed. > >> >>> +the value a register had before the call (in other words, in the outer >>> +frame), if the register value has since been changed by the callee. >>> +@value{GDBN} tries to deduce where registers are saved, from the debug >>> +info, unwind info, or the machine code generated by your compiler. >> >> I don't think this is correct either, we try to figure out where callee >> saved registers are stored, but these are not the scratch registers, if >> the scratch registers are needed by the caller then the caller will save >> them, but the callee will just go ahead and use them. Similarly the >> DWARF only tells us about callee saved registers. The caller saved >> registers are now not mentioned in the DWARF as gcc has made sure that >> no variables are live in these registers. > > Hmm. You're right, but only if you see a sequence/connection between > the sentences. They're different paragraphs -- the second sentence is > mostly preexisting, and I didn't mean to imply the GDB tries to figure > out where caller-saved/scratch registers are. I'll rephrase it (in > this or the patch, whatever we end up with. Thanks. > >> >>> If >>> +some register is not saved, or if @value{GDBN} is unable to locate the >>> +saved register, @value{GDBN} will assume the register in the outer >>> +frame had the same location and value it has in the inner frame. In >>> +other words, the values of call-clobbered registers in the outer >>> +frame, if not saved by the caller, are defined as being the values the >>> +registers would have if the inner frame was to return immediately. >>> +This is usually harmless, but note however that if you change a >>> +register in the outer frame, you may also be affecting the inner >>> +frame. >> >> I'd just like to pick up on the "harmless" here, I agree that it would >> be "harmless" in the sense that if we did a return in gdb it would be >> harmless; the register is callee clobbered, the caller either does not >> care what is in the register after the call, or has code to restore the >> value that it does care about. > > Right, that's what I was thinking. It'd be better to write that out > explicitly. > >> From a debugging point of few though, I >> suspect showing the wrong value might be far from harmless, > > No sure why. I think that if you print it "they" (users) will use it, assuming it's correct. Given that I don't think it's correct I think we're likely to be giving users miss-information. Are there any other examples within gdb that you can think of (I can't) where we print information that we know is very likely wrong? (Obviously I mean deliberately here rather than being mislead by invalid debug information). > >> and if this >> patch is merged we need to draw attention to the fact that the more >> "outer" the frame it you're looking at, the more likely call-clobbered >> registers are to be wrong. > > Blah, what a rat hole. :-P :-) > > Please guys, re-confirm to me the direction you prefer seeing > GDB follow, even after my reasoning further explained (I'm okay > with either approach), and I'll update the corresponding patch's > documentation bits with the suggestions you've sent. I think the original "" patch was great and a good improvement on where we are right now, I'd much rather see that merged than the "values-from-inner-frame" patch. Thanks for your continued effort :) Andrew