From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 917773857C55 for ; Fri, 18 Sep 2020 15:48:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 917773857C55 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=simark.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=simark@simark.ca Received: from [172.16.0.95] (192-222-181-218.qc.cable.ebox.net [192.222.181.218]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id BF9881E009; Fri, 18 Sep 2020 11:48:56 -0400 (EDT) Subject: Re: [PATCH] Fix ctrl-c when debugging WOW64 processes To: Hannes Domani , Hannes Domani via Gdb-patches , Tom Tromey References: <20200917180337.1984-1-ssbssa.ref@yahoo.de> <20200917180337.1984-1-ssbssa@yahoo.de> <871rj06tub.fsf@tromey.com> <334596674.1355343.1600376198632@mail.yahoo.com> <725154490.1784012.1600439240290@mail.yahoo.com> From: Simon Marchi Message-ID: <4f1a700a-e704-56f6-02fd-f0d9579102e3@simark.ca> Date: Fri, 18 Sep 2020 11:48:56 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <725154490.1784012.1600439240290@mail.yahoo.com> Content-Type: text/plain; charset=utf-8 Content-Language: tl Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, NICE_REPLY_A, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Fri, 18 Sep 2020 15:48:59 -0000 On 2020-09-18 10:27 a.m., Hannes Domani wrote: > I did some experiments. > > Seems like GenerateConsoleCtrlEvent() only works if the target process was > created without CREATE_NEW_CONSOLE. > And what's worse, it seems to always return TRUE, so it never reaches > DebugBreakProcess(), even if the target process doesn't have a console at all. > > I also tried the "last resort", with soft_interrupt_requested=1, but this > immediatly crashed gdbserver. > > I fixed this crash with: > > --- a/gdbserver/win32-low.cc > +++ b/gdbserver/win32-low.cc > @@ -1339,6 +1335,7 @@ fake_breakpoint_event (void) > faked_breakpoint = 1; > > memset (¤t_event, 0, sizeof (current_event)); > + current_event.dwProcessId = current_process_id; > current_event.dwThreadId = main_thread_id; > current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT; > current_event.u.Exception.ExceptionRecord.ExceptionCode > > But this didn't work either, I think it's because gdb checks if the current > instruction is int3, and continues if not. > > I'm wondering why this last resort was added, was this done for pre-XP where > DebugBreakProcess() didn't exist? I digged a little bit. It was introduced by this commit by a young Pedro :) https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=4d5d1aaa19ea The corresponding mailing list post is: https://sourceware.org/legacy-ml/gdb-patches/2007-11/msg00217.html It doesn't explain the rationale though, it just implicitly refers to a previous thread. It's probably this one, which gives a bit more context: https://sourceware.org/legacy-ml/gdb-patches/2007-11/msg00035.html >From what I understand, this was for WinCE, which lacked GenerateConsoleCtrlEvent and DebugBreakProcess. Since we removed support for WinCE, I think that code could very well be GC'ed. > > So right now ctrl-c doesn't really work that well with gdbserver, and not > at all when debugging a program without console (WOW64 or not doesn't matter). > > > And the WOW64 fix for DbgUiRemoteBreakin() probably can't be used in > gdbserver, because find_minimal_symbol_address() is not available. Using the qSymbol packet, there is a window during which GDBserver can as GDB to look up minimal symbol values. On the GDBserver side, this is done through process_stratum_target::look_up_symbols, you would just need to implement it for win32_process_target. > Meanwhile I came up with a possible alternative for DbgUiRemoteBreakin(): > > --- a/gdb/nat/windows-nat.c > +++ b/gdb/nat/windows-nat.c > @@ -240,6 +241,13 @@ handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions) > case EXCEPTION_BREAKPOINT: > #ifdef __x86_64__ > if (ignore_first_breakpoint) > { > /* For WOW64 processes, there are always 2 breakpoint exceptions > on startup, first a BREAKPOINT for the 64bit ntdll.dll, > then a WX86_BREAKPOINT for the 32bit ntdll.dll. > Here we only care about the WX86_BREAKPOINT's. */ > ourstatus->kind = TARGET_WAITKIND_SPURIOUS; > ignore_first_breakpoint = false; > } > + else if (wow64_process) > + { > + DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT"); > + rec->ExceptionCode = DBG_CONTROL_C; > + ourstatus->value.sig = GDB_SIGNAL_INT; > + break; > + } > #endif > /* FALLTHROUGH */ > case STATUS_WX86_BREAKPOINT: > > This transforms the (64bit) breakpoint from DebugBreakProcess() into > SIGINT, then the check for the int3 instruction is not done, and gdb stops > the target process in any case. That sounds simple (which is good). Would this replace completely spawning the remote thread (which you added in the previous patch)? Simon