From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 78F3339C5018; Thu, 4 Mar 2021 16:07:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 78F3339C5018 From: "cvs-commit at gcc dot gnu.org" To: gdb-prs@sourceware.org Subject: [Bug backtrace/27147] [GNU/Linux, sparc64] GDB is unable to print full stack trace (got "previous frame inner to this frame" errors) Date: Thu, 04 Mar 2021 16:07:09 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: backtrace X-Bugzilla-Version: HEAD X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: 10.2 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gdb-prs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-prs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Mar 2021 16:07:09 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D27147 --- Comment #16 from cvs-commit at gcc dot gnu.org --- The master branch has been updated by Simon Marchi : https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dd1e93af64a6b= 74921cca9bca8a7043855f9da10d commit d1e93af64a6b74921cca9bca8a7043855f9da10d Author: Simon Marchi Date: Thu Mar 4 10:57:03 2021 -0500 gdb: set current thread in sparc_{fetch,collect}_inferior_registers (PR gdb/27147) PR 27147 shows that on sparc64, GDB is unable to properly unwind: Expected result (from GDB 9.2): #0 0x0000000000108de4 in puts () #1 0x0000000000100950 in hello () at gdb-test.c:4 #2 0x0000000000100968 in main () at gdb-test.c:8 Actual result (from GDB latest git): #0 0x0000000000108de4 in puts () #1 0x0000000000100950 in hello () at gdb-test.c:4 Backtrace stopped: previous frame inner to this frame (corrupt stac= k?) The first failing commit is 5b6d1e4fa4fc ("Multi-target support"). The cause of the change in behavior is due to (thanks for Andrew Burgess for find= ing this): - inferior_ptid is no longer set on entry of target_ops::wait, whereas it was set to something valid previously - deep down in linux_nat_target::wait (see stack trace below), we fetch the registers of the event thread - on sparc64, fetching registers involves reading memory (in sparc_supply_rwindow, see stack trace below) - reading memory (target_ops::xfer_partial) relies on inferior_ptid being set to the thread from which we want to read memory This is where things go wrong: #0 linux_nat_target::xfer_partial (this=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, annex=3D0x0, readbuf=3D0x7feffe3b000 "", writebuf=3D0x0, offset=3D8791798050744, len=3D8, xfered_len=3D0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/linux-nat.= c:3697 #1 0x00000100007f5b10 in raw_memory_xfer_partial (ops=3D0x10000fa2= c40 , readbuf=3D0x7feffe3b000 "", writebuf=3D0x0, memaddr=3D8791798050744, len=3D8, xfered_len=3D0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:912 #2 0x00000100007f60e8 in memory_xfer_partial_1 (ops=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, readbuf=3D0x7feffe3b000 "", writebuf=3D0x0, memaddr=3D8791798050744, len=3D= 8, xfered_len=3D0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1= 043 #3 0x00000100007f61b4 in memory_xfer_partial (ops=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, readbuf=3D0x7feffe3b000 "", writebuf=3D0x0, memaddr=3D8791798050744, len=3D= 8, xfered_len=3D0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1= 072 #4 0x00000100007f6538 in target_xfer_partial (ops=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, annex=3D0x0, readbuf=3D0x7feffe3b000 "", writebuf=3D0x0, offset=3D8791798050744, len=3D8, xfered_len=3D0x7feffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1= 129 #5 0x00000100007f7094 in target_read_partial (ops=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, annex=3D0x0, buf=3D0x7feffe3b000 "", offset=3D8791798050744, len=3D8, xfered_len=3D0x7fe= ffe3ae88) at /home/simark/src/binutils-gdb/gdb/target.c:1375 #6 0x00000100007f721c in target_read (ops=3D0x10000fa2c40 , object=3DTARGET_OBJECT_MEMORY, annex=3D0x0, buf=3D0x7feffe3b000 "", offset=3D8791798050744, len=3D8) at /home/simark/src/binutils-gdb/gdb/target.c:1415 #7 0x00000100007f69d4 in target_read_memory (memaddr=3D87917980507= 44, myaddr=3D0x7feffe3b000 "", len=3D8) at /home/simark/src/binutils-gdb/gdb/target.c:1218 #8 0x0000010000758520 in sparc_supply_rwindow (regcache=3D0x10000f= ea4f0, sp=3D8791798050736, regnum=3D-1) at /home/simark/src/binutils-gdb/gdb/sparc-tdep.c:1960 #9 0x000001000076208c in sparc64_supply_gregset (gregmap=3D0x10000= be3190 , regcache=3D0x10000fea4f0, regnum=3D-1, gregs=3D0x7feffe3b230) at /home/simark/src/binutils-gdb/gdb/sparc64-tdep.c:= 1974 #10 0x0000010000751b64 in sparc_fetch_inferior_registers (regcache=3D0x10000fea4f0, regnum=3D80) at /home/simark/src/binutils-gdb/gdb/sparc-nat.c:170 #11 0x0000010000759d68 in sparc64_linux_nat_target::fetch_registers (this=3D0x10000fa2c40 , regcache=3D0x10000fea= 4f0, regnum=3D80) at /home/simark/src/binutils-gdb/gdb/sparc64-linux-nat.c:38 #12 0x00000100008146ec in target_fetch_registers (regcache=3D0x10000fea4f0, regno=3D80) at /home/simark/src/binutils-gdb/gdb/target.c:3287 #13 0x00000100006a8c5c in regcache::raw_update (this=3D0x10000fea4f= 0, regnum=3D80) at /home/simark/src/binutils-gdb/gdb/regcache.c:584 #14 0x00000100006a8d94 in readable_regcache::raw_read (this=3D0x10000fea4f0, regnum=3D80, buf=3D0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:598 #15 0x00000100006a93b8 in readable_regcache::cooked_read (this=3D0x10000fea4f0, regnum=3D80, buf=3D0x7feffe3b7c0 "") at /home/simark/src/binutils-gdb/gdb/regcache.c:690 #16 0x00000100006b288c in readable_regcache::cooked_read (this=3D0x10000fea4f0, regnum=3D80, val=3D0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:777 #17 0x00000100006a9b44 in regcache_cooked_read_unsigned (regcache=3D0x10000fea4f0, regnum=3D80, val=3D0x7feffe3b948) at /home/simark/src/binutils-gdb/gdb/regcache.c:791 #18 0x00000100006abf3c in regcache_read_pc (regcache=3D0x10000fea4f= 0) at /home/simark/src/binutils-gdb/gdb/regcache.c:1295 #19 0x0000010000507920 in save_stop_reason (lp=3D0x10000fc5b10) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:2612 #20 0x00000100005095a4 in linux_nat_filter_event (lwpid=3D520983, status=3D1407) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3050 #21 0x0000010000509f9c in linux_nat_wait_1 (ptid=3D..., ourstatus=3D0x7feffe3c8f0, target_options=3D...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3194 #22 0x000001000050b1d0 in linux_nat_target::wait (this=3D0x10000fa2= c40 , ptid=3D..., ourstatus=3D0x7feffe3c8f0, target_options=3D...) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:3432 #23 0x00000100007f8ac0 in target_wait (ptid=3D..., status=3D0x7feff= e3c8f0, options=3D...) at /home/simark/src/binutils-gdb/gdb/target.c:2000 #24 0x00000100004ac17c in do_target_wait_1 (inf=3D0x1000116d280, ptid=3D..., status=3D0x7feffe3c8f0, options=3D...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3464 #25 0x00000100004ac3b8 in operator() (__closure=3D0x7feffe3c678, inf=3D0x1000116d280) at /home/simark/src/binutils-gdb/gdb/infrun.c:3527 #26 0x00000100004ac7cc in do_target_wait (wait_ptid=3D..., ecs=3D0x7feffe3c8c8, options=3D...) at /home/simark/src/binutils-gdb/gdb/infrun.c:3540 #27 0x00000100004ad8c4 in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:3880 #28 0x0000010000485568 in inferior_event_handler (event_type=3DINF_REG_EVENT) at /home/simark/src/binutils-gdb/gdb/inf-loop.= c:42 #29 0x000001000050d394 in handle_target_event (error=3D0, client_data=3D0x0) at /home/simark/src/binutils-gdb/gdb/linux-nat.c:4060 #30 0x0000010000ab5c8c in handle_file_event (file_ptr=3D0x100012072= 70, ready_mask=3D1) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:5= 75 #31 0x0000010000ab6334 in gdb_wait_for_event (block=3D0) at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:701 #32 0x0000010000ab487c in gdb_do_one_event () at /home/simark/src/binutils-gdb/gdbsupport/event-loop.cc:212 #33 0x0000010000542668 in start_event_loop () at /home/simark/src/binutils-gdb/gdb/main.c:348 #34 0x000001000054287c in captured_command_loop () at /home/simark/src/binutils-gdb/gdb/main.c:408 #35 0x0000010000544e84 in captured_main (data=3D0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1242 #36 0x0000010000544f2c in gdb_main (args=3D0x7feffe3d188) at /home/simark/src/binutils-gdb/gdb/main.c:1257 #37 0x00000100000c1f14 in main (argc=3D4, argv=3D0x7feffe3d548) at /home/simark/src/binutils-gdb/gdb/gdb.c:32 There is a target_read_memory call in sparc_supply_rwindow, whose return value is not checked. That call fails, because inferior_ptid does not contain a valid ptid, and uninitialized buffer contents is used. Ultimately it results in a corrupt stop_pc. target_ops::fetch_registers can be (and should remain, in my opinion) independent of inferior_ptid, because the ptid of the thread from which to fetch registers can be obtained from the regcache. In other words, implementations of target_ops::fetch_registers should not rely on inferior_ptid having a sensible value on entry. The sparc64_linux_nat_target::fetch_registers case is special, because = it calls a target method that is dependent on the inferior_ptid value (target_read_inferior, and ultimately target_ops::xfer_partial). So I would say it's the responsibility of sparc64_linux_nat_target::fetch_register= s to set up inferior_ptid correctly prior to calling target_read_inferior. This patch makes sparc64_linux_nat_target::fetch_registers (and store_registers, since it works the same) temporarily set inferior_ptid= .=20 If we ever make target_ops::xfer_partial independent of inferior_ptid, setting inferior_ptid won't be necessary, we'll simply pass down the ptid as a parameter in some way. I chose to set/restore inferior_ptid in sparc_fetch_inferior_registers, because I am not convinced that doing so in an inner location (in sparc_supply_rwindow for instance) would always be correct. We have access to the ptid in sparc_supply_rwindow (from the regcache), so we _could_ set inferior_pt= id there. However, I don't want to just set inferior_ptid, as that would = make it not desync'ed with `current_thread ()` and `current_inferior ()`. It's preferable to use switch_to_thread instead, as that switches all the gl= obal "current" stuff in a coherent way. But doing so requires a `thread_info *`, and getting a `thread_info *` from a ptid requires a `process_stratum_target *`. We could use `current_inferior()->process_target()` in sparc_supply_rwindow for this (using target_read_memory uses the current inferior's target stack anyway). However, sparc_supply_rwindow is also used in the context of BSD uthreads, where a thread stratum target defines thre= ads. I presume the ptid in the regcache would be the ptid of the uthread, defi= ned by the thread stratum target (bsd_uthread_target). Using `current_inferior()->process_target()` would look up a ptid defined by = the thread stratum target using the process stratum target. I don't think = it would give good results. So I prefer playing it safe and looking up the thre= ad earlier, in sparc_fetch_inferior_registers. I added some assertions (in sparc_supply_rwindow and others) to verify that the regcache's ptid matches inferior_ptid. That verifies that the caller has properly set the correct global context. This would have caught (though a failed assertion) the current problem. gdb/ChangeLog: PR gdb/27147 * sparc-nat.h (sparc_fetch_inferior_registers): Add process_stratum_target parameter, sparc_store_inferior_registers): update callers. * sparc-nat.c (sparc_fetch_inferior_registers, sparc_store_inferior_registers): Add process_stratum_target parameter. Switch current thread before calling sparc_supply_gregset / sparc_collect_rwindow. (sparc_store_inferior_registers): Likewise. * sparc-obsd-tdep.c (sparc32obsd_supply_uthread): Add assertion. (sparc32obsd_collect_uthread): Likewise. * sparc-tdep.c (sparc_supply_rwindow, sparc_collect_rwindow): Add assertion. * sparc64-obsd-tdep.c (sparc64obsd_collect_uthread, sparc64obsd_supply_uthread): Add assertion. Change-Id: I16c658cd70896cea604516714f7e2428fbaf4301 --=20 You are receiving this mail because: You are on the CC list for the bug.=