From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 89509 invoked by alias); 9 Mar 2015 15:39:25 -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 89441 invoked by uid 89); 9 Mar 2015 15:39:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham 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; Mon, 09 Mar 2015 15:39:23 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t29FccmX020501 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 9 Mar 2015 11:38:38 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t29Fca4R019445; Mon, 9 Mar 2015 11:38:37 -0400 Message-ID: <54FDBE7B.9070405@redhat.com> Date: Mon, 09 Mar 2015 15:39:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: Andy Wingo , gdb-patches , Alexander Smundak CC: Doug Evans Subject: Re: Frame sniffers in Python/Guile/* References: <87d24r4jgx.fsf@igalia.com> In-Reply-To: <87d24r4jgx.fsf@igalia.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2015-03/txt/msg00221.txt.bz2 Hi Andy, On 03/02/2015 01:28 PM, Andy Wingo wrote: > (Why a new object type? Because all objects have a > frame_id, and this one does not, and it turns out it's a deep invariant > that frames have identifiers.) Yeah. > The list of unwinders is run in order over the ephemeral frame, and the > first one that calls (set-ephemeral-frame-id! frame sp [ip [special]]) > on the frame takes responsibility of unwinding the frame. You can read > registers with ephemeral-frame-read-register, and set their unwound > values with ephemeral-frame-write-register!. Simple stuff, and I'll > post later once I get the V8 unwinder working. > > Unfortunately, the unwind callback is really squirrely -- you can't do > much there. You mean the "unwind->sniffer" callback, right? If so, that's (so far) by design. The sniffer callback is only supposed to identify whether the unwinder can unwind, not do any unwinding at all. :-/ See here for example: https://www.sourceware.org/ml/gdb-patches/2013-11/msg00602.html > * You can't call the Guile lookup-symbol function within an unwind > handler, because the Guile wrapper wants to default the "block" > argument from the selected frame, and there is no selected frame. There can certainly be a selected frame already when something tries to unwind past the most-unwound-already frame. That will be the normal case of "up" past the innermost frame, even. But imagine the case of: #0 frame0 <<<< current #1 frame1 <<<< selected #2 frame2 And the user has frame 1 selected. And now the user runs some guile or python code that does frame-older a couple times, which results in GDB trying to unwind past frame #2. So what context does make sense for symbol look ups at that point? With your current hack, because there's a selected frame (frame #1), symbols will be looked up starting from there. But it seems to me that whatever was the selected frame shouldn't influence the sniffer's decisions. Isn't the correct answer that the sniffer should pass in an explicit block to lookup-symbol? > > * You can't value-call, which is not unexpected in general, but the > reason is unexpected: because call_function_by_hand calls > get_current_arch and that doesn't work Where is that? I think you meant that the guile wrapper calls get_current_arch, not call_function_by_hand. > * You can't call get_current_arch, directly or indirectly, because it > causes unbounded recursion: > > #3 0x00000000006a65f2 in frame_unwind_try_unwinder (this_frame=this_frame@entry=0x5f6af10, this_cache=this_cache@entry=0x5f6af28, unwinder=0x409fe30) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame-unwind.c:126 > #4 0x00000000006a696f in frame_unwind_find_by_frame (this_frame=this_frame@entry=0x5f6af10, this_cache=this_cache@entry=0x5f6af28) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame-unwind.c:157 > #5 0x00000000006a32cb in get_prev_frame_if_no_cycle (fi=0x5f6af10) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:454 > #6 0x00000000006a32cb in get_prev_frame_if_no_cycle (this_frame=this_frame@entry=0x5f6ae40) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1780 > #7 0x00000000006a53a9 in get_prev_frame_always (this_frame=0x5f6ae40) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1954 > #8 0x00000000006a53a9 in get_prev_frame_always (this_frame=this_frame@entry=0x5f6ae40) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1971 > #9 0x00000000006a5ab1 in get_prev_frame (this_frame=this_frame@entry=0x5f6ae40) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:2212 > #10 0x00000000006a5d8c in unwind_to_current_frame (ui_out=, args=args@entry=0x5f6ae40) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1447 > #11 0x00000000005cf63c in catch_exceptions_with_msg (func_uiout=, func=func@entry=0x6a5d80 , func_args=func_args@entry=0x5f6ae40, gdberrmsg=gdberrmsg@entry=0x0, mask=mask@entry=RETURN_MASK_ERROR) > at /home/wingo/src/binutils-gdb/+2.2/../gdb/exceptions.c:189 > #12 0x00000000005cf75a in catch_exceptions (uiout=, func=func@entry=0x6a5d80 , func_args=func_args@entry=0x5f6ae40, mask=mask@entry=RETURN_MASK_ERROR) at /home/wingo/src/binutils-gdb/+2.2/../gdb/exceptions.c:169 > #13 0x00000000006a33e0 in get_current_frame () at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1486 > #14 0x00000000006a3fe7 in get_selected_frame (message=message@entry=0x0) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1541 > #15 0x00000000005e7a27 in get_current_arch () at /home/wingo/src/binutils-gdb/+2.2/../gdb/arch-utils.c:784 > > Perhaps this is only the case for the most inner frame? Anyway this > is the reason that many other things fail. > > * You can't read user regs from an ephemeral frame for some reason: > > /home/wingo/src/binutils-gdb/+2.2/../gdb/regcache.c:779: internal-error: regcache_cooked_read_value: Assertion `regnum < regcache->descr->nr_cooked_registers' failed. > #9 0x00000000005732b5 in regcache_cooked_read_value (regcache=0xd25cc0, regnum=221) at /home/wingo/src/binutils-gdb/+2.2/../gdb/regcache.c:779 > #10 0x0000000000684c28 in sentinel_frame_prev_register (this_frame=0x6c7c350, this_prologue_cache=, regnum=) at /home/wingo/src/binutils-gdb/+2.2/../gdb/sentinel-frame.c:52 > #11 0x00000000006a4408 in frame_unwind_register_value (frame=0x6c7c350, regnum=221) at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1111 > #12 0x00000000006a468f in frame_register_unwind (frame=, regnum=, optimizedp=0x7fffffffcde8, unavailablep=0x7fffffffcdec, lvalp=0x7fffffffcdf0, addrp=0x7fffffffcdf8, realnump=0x7fffffffcdf4, bufferp=0x7fffffffce40 "l\305\001\367\377\177") at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1016 > #13 0x00000000006a4892 in frame_register (frame=, regnum=, optimizedp=, unavailablep=, lvalp=, addrp=, realnump=, bufferp=) > at /home/wingo/src/binutils-gdb/+2.2/../gdb/frame.c:1057 > Why would the unwinder want to access user / pseudo registers? Shouldn't it be working only with raw registers? > And so on. From what I can tell, all of this is because there is no > selected frame. I recognize that this situation reflects reality in > some way -- we're still building the selected frame -- but is there any > way that we could have GDB be in a more "normal" state while the unwind > callback is running? Thanks, Pedro Alves