From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 62F27385AC3F for ; Thu, 15 Jul 2021 19:31:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 62F27385AC3F Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 16FJVUhO004860 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 15 Jul 2021 15:31:35 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 16FJVUhO004860 Received: from [10.0.0.11] (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id B70FD1E4A3; Thu, 15 Jul 2021 15:31:30 -0400 (EDT) Subject: Re: [PATCH v3 3/3] gdb: follow-fork: push target and add thread in target_follow_fork To: Pedro Alves , gdb-patches@sourceware.org References: <20210610143305.2018627-1-simon.marchi@polymtl.ca> <20210610143305.2018627-4-simon.marchi@polymtl.ca> From: Simon Marchi Message-ID: Date: Thu, 15 Jul 2021 15:31:30 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Thu, 15 Jul 2021 19:31:31 +0000 X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Jul 2021 19:31:40 -0000 >> Now, I am not sure nowadays all targets that support following forks >> handle debugging both parent and child at the same time and then detaching >> one of them correctly. This is what we need to look out for. >> >> Fortunately, we have muuuuuuch fewer targets than back in the day, >> and only a few support following forks: >> >> linux-nat.c, obsd-nat.c, remote.c, fbsd-nat.c >> >> - linux-nat.c and remote.c surely handle this fine. >> >> - fbsd-nat.c probably does too, since it explicitly handles detach_fork. >> >> - obsd-nat.c does not handle "set detach-on-fork off" though. I think >> this one deserves a double check. > > Ok, thanks for the heads up. What could make OpenBSD not support it, if > a process on that OS wasn't capable of ptrace-ing two processes at the > same time? Or it would be something in our code? > > There is an OpenBSD machine on the compile farm, I'll give it a try. I built GDB on the OpenBSD machine, but it fails to start any program. I tracked it down to x86_dr_low.get_status being nullptr here: * thread #1, stop reason = step over frame #0: 0x00000a116f00255d gdb`x86_dr_stopped_data_address(state=0x00000a13e5bdd790, addr_p=0x00007f7ffffe3ff8) at x86-dregs.c:610:12 607 registers. */ 608 printf("1\n"); 609 printf(" %p\n", x86_dr_low.get_status); -> 610 status = x86_dr_low_get_status (); ^ 611 612 printf("2\n"); 613 ALL_DEBUG_ADDRESS_REGISTERS (i) (lldb) print x86_dr_low.get_status (unsigned long (*)()) $0 = 0x0000000000000000 (lldb) bt * thread #1, stop reason = step over * frame #0: 0x00000a116f00255d gdb`x86_dr_stopped_data_address(state=0x00000a13e5bdd790, addr_p=0x00007f7ffffe3ff8) at x86-dregs.c:610:12 frame #1: 0x00000a116f00274e gdb`x86_dr_stopped_by_watchpoint(state=0x00000a13e5bdd790) at x86-dregs.c:661:10 frame #2: 0x00000a116f331f99 gdb`x86_stopped_by_watchpoint() at x86-nat.c:209:10 frame #3: 0x00000a116eac3f4f gdb`x86_nat_target::stopped_by_watchpoint(this=0x00000a116f6de860) at x86-nat.h:102:11 frame #4: 0x00000a116f1cbefc gdb`target_stopped_by_watchpoint() at target.c:473:50 frame #5: 0x00000a116eb26fa5 gdb`watchpoints_triggered(ws=0x00007f7ffffe4bc8) at breakpoint.c:4791:32 frame #6: 0x00000a116ef17bdd gdb`handle_signal_stop(ecs=0x00007f7ffffe4ba0) at infrun.c:6084:29 frame #7: 0x00000a116ef0a357 gdb`handle_inferior_event(ecs=0x00007f7ffffe4ba0) at infrun.c:5694:7 frame #8: 0x00000a116ef08150 gdb`fetch_inferior_event() at infrun.c:4090:5 frame #9: 0x00000a116eedd8d1 gdb`inferior_event_handler(event_type=INF_REG_EVENT) at inf-loop.c:41:7 frame #10: 0x00000a116ef0e779 gdb`infrun_async_inferior_event_handler(data=0x0000000000000000) at infrun.c:9402:3 frame #11: 0x00000a116eae7cdf gdb`check_async_event_handlers() at async-event.c:335:4 frame #12: 0x00000a116f4fc947 gdb`gdb_do_one_event() at event-loop.cc:216:10 frame #13: 0x00000a116ef7ce51 gdb`start_event_loop() at main.c:421:13 frame #14: 0x00000a116ef7bf3a gdb`captured_command_loop() at main.c:481:3 frame #15: 0x00000a116ef79662 gdb`captured_main(data=0x00007f7ffffe4e70) at main.c:1353:4 frame #16: 0x00000a116ef79592 gdb`gdb_main(args=0x00007f7ffffe4e70) at main.c:1368:7 frame #17: 0x00000a116ea29707 gdb`main(argc=5, argv=0x00007f7ffffe4f18) at gdb.c:32:10 frame #18: 0x00000a116ea294a1 gdb`___start + 321 Indeed, _initialize_x86_bsd_nat sets it only when HAVE_PT_GETDBREGS is defined, which it isn't on OpenBSD. I made the quick fix pasted below (which I think would be a good fix to have in master), which allowed it to go further, and hit: (gdb) r Starting program: /home/simark/build/binutils-gdb/gdb/a.out Child process unexpectedly missing: No child processes. /home/simark/src/binutils-gdb/gdb/inferior.c:303: internal-error: struct inferior *find_inferior_pid(process_stratum_target *, int): Assertion `pid != 0' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) Process 69075 stopped * thread #1, stop reason = signal SIGSTOP frame #0: 0x000004c42ebf2e5a libc.so.96.0`_thread_sys_poll at -:3 (lldb) bt * thread #1, stop reason = signal SIGSTOP * frame #0: 0x000004c42ebf2e5a libc.so.96.0`_thread_sys_poll at -:3 frame #1: 0x000004c42ec6867e libc.so.96.0`_libc_poll_cancel(fds=, nfds=, timeout=) at w_poll.c:27:8 frame #2: 0x000004c165907bb5 gdb`gdb_wait_for_event(block=1) at event-loop.cc:613:19 frame #3: 0x000004c1659079f8 gdb`gdb_do_one_event() at event-loop.cc:237:7 frame #4: 0x000004c165616565 gdb`gdb_readline_wrapper(prompt="/home/simark/src/binutils-gdb/gdb/inferior.c:303: internal-error: struct inferior *find_inferior_pid(process_stratum_target *, int): Assertion `pid != 0' failed.\nA problem internal to GDB has been detected,\nfurther debugging may prove unreliable.\nQuit this debugging session? (y or n) ") at top.c:1122:10 frame #5: 0x000004c1656efb35 gdb`defaulted_query(ctlstr="%s\nQuit this debugging session? ", defchar='\0', args=0x00007f7ffffe06e0) at utils.c:889:18 frame #6: 0x000004c1656f007b gdb`query(ctlstr="%s\nQuit this debugging session? ") at utils.c:981:9 frame #7: 0x000004c1656ee7b5 gdb`internal_vproblem(problem=0x000004c165aed310, file="/home/simark/src/binutils-gdb/gdb/inferior.c", line=303, fmt="%s: Assertion `%s' failed.", ap=0x00007f7ffffe0a00) at utils.c:373:11 frame #8: 0x000004c1656ee402 gdb`internal_verror(file="/home/simark/src/binutils-gdb/gdb/inferior.c", line=303, fmt="%s: Assertion `%s' failed.", ap=0x00007f7ffffe0a00) at utils.c:439:3 frame #9: 0x000004c165907740 gdb`internal_error(file="/home/simark/src/binutils-gdb/gdb/inferior.c", line=303, fmt="%s: Assertion `%s' failed.") at errors.cc:55:3 frame #10: 0x000004c165301be3 gdb`find_inferior_pid(targ=0x000004c165ae98a0, pid=0) at inferior.c:303:3 frame #11: 0x000004c165301cd8 gdb`find_inferior_ptid(targ=0x000004c165ae98a0, ptid=(m_pid = 0, m_lwp = 0, m_tid = 0)) at inferior.c:317:10 frame #12: 0x000004c165605e43 gdb`find_thread_ptid(targ=0x000004c165ae98a0, ptid=(m_pid = 0, m_lwp = 0, m_tid = 0)) at thread.c:487:19 frame #13: 0x000004c165314556 gdb`handle_inferior_event(ecs=0x00007f7ffffe12c0) at infrun.c:5380:21 frame #14: 0x000004c1653131a0 gdb`fetch_inferior_event() at infrun.c:4090:5 frame #15: 0x000004c1652e8921 gdb`inferior_event_handler(event_type=INF_REG_EVENT) at inf-loop.c:41:7 obsd_nat_target::wait hits the error case (and prints the "Child process unexpectedly missing" message) and returns the value of inferior_ptid, which is null_ptid. So, there seems to be a bit too much bit-rot for me to actually test anything. Simon >From e4314c31f9e804e4803d36286f6785e8d120cfc3 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 15 Jul 2021 15:12:50 -0400 Subject: [PATCH] fix Change-Id: Ibbf6ec02469c80c1a7ab34e71d503779c9ae840c --- gdb/nat/x86-dregs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gdb/nat/x86-dregs.c b/gdb/nat/x86-dregs.c index cf8e517eb0..b61a551f81 100644 --- a/gdb/nat/x86-dregs.c +++ b/gdb/nat/x86-dregs.c @@ -82,6 +82,12 @@ x86_dr_low_get_control () return x86_dr_low.get_control (); } +static bool +x86_dr_low_can_get_status () +{ + return x86_dr_low.get_status != nullptr; +} + /* Return the value of the inferior's DR6 debug status register. */ static unsigned long @@ -604,6 +610,9 @@ int x86_dr_stopped_data_address (struct x86_debug_reg_state *state, CORE_ADDR *addr_p) { + if (!x86_dr_low_can_get_status ()) + return 0; + CORE_ADDR addr = 0; int i; int rc = 0; @@ -693,6 +702,9 @@ x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state) int x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state) { + if (!x86_dr_low_can_get_status ()) + return 0; + CORE_ADDR addr = 0; int i; int rc = 0; -- 2.26.2