From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by sourceware.org (Postfix) with ESMTP id 56291395B0AE for ; Wed, 27 May 2020 14:48:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 56291395B0AE Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-76-cLqxZR_NM-G1eKnkEM0K4Q-1; Wed, 27 May 2020 10:48:11 -0400 X-MC-Unique: cLqxZR_NM-G1eKnkEM0K4Q-1 Received: by mail-wr1-f71.google.com with SMTP id y7so11317258wrd.12 for ; Wed, 27 May 2020 07:48:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=8Fc7Yat/mkJe2p8iCPJwhlqUqVHXaIFiaepef6IW9Q0=; b=FF2SFWuk8HtIHAeW6rzAPCVk4pNqLJ9iYWlJ3jyZxy0OLDtYS5yFgVY3boenL5j8Zw BiBUOChLCi/vkBUyEngseSwOC2JTchmN8qzS0P0jmYgNiGbfMIP50UMajijIwt/zf+4j OJHyYeDKrGXJ7glYWFS79SG+WPxCbM2s/ySK2yGSQzCKpk3/pj54gUwiSyQ8ckyN5EI3 nKQTskpAsL/XDsEw92WEz1dvF5TXNOMf7qLhfteD5lbh5HDShN0KMbMPBWz/jqErsIIq avaE58wT6r3doZpW4zZOgLPNQSDeN9Tpd95HXUXZ2DMF84zcmLCSTfNIh4bcjTu+Hjdc Solw== X-Gm-Message-State: AOAM530Jf15YJlmVjVJ7R6s+Qd03nwZdcFS3f43vFpAfdSJjN40TnITr ilEWLPKs6PQG0z3/UvfAjokmz5gp/jlCVxbo2OOxFxXANrHBLlE8CYZatTP7BVbU/USK1tUDLYh 0GFOHT4BDB0ui9izDzFb3nw== X-Received: by 2002:a5d:6144:: with SMTP id y4mr26228128wrt.185.1590590890115; Wed, 27 May 2020 07:48:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyu1pv7yZq2DoFfhpowNosbo6rdYPzCVRlv9mLQ1YJJS9Xb6ppNlTfxT21L6s5cqkm/0JrsaA== X-Received: by 2002:a5d:6144:: with SMTP id y4mr26228112wrt.185.1590590889877; Wed, 27 May 2020 07:48:09 -0700 (PDT) Received: from ?IPv6:2001:8a0:f909:7b00:56ee:75ff:fe8d:232b? ([2001:8a0:f909:7b00:56ee:75ff:fe8d:232b]) by smtp.gmail.com with ESMTPSA id j190sm3128378wmb.33.2020.05.27.07.48.08 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 27 May 2020 07:48:09 -0700 (PDT) Subject: Re: [PATCH 7/7] Reset Windows hardware breakpoints on executable's entry point To: Hannes Domani , gdb-patches@sourceware.org References: <20200525185659.59346-1-ssbssa@yahoo.de> <20200525185659.59346-8-ssbssa@yahoo.de> From: Pedro Alves Message-ID: <8e076c81-6e92-930f-c16d-1db73bde8a83@redhat.com> Date: Wed, 27 May 2020 15:48:08 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, 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: Wed, 27 May 2020 14:48:18 -0000 On 5/27/20 1:07 PM, Pedro Alves via Gdb-patches wrote: > On 5/25/20 7:56 PM, Hannes Domani via Gdb-patches wrote: >> Fixes these testsuite fails on Windows (actually more, but the others are >> cascading failures): >> FAIL: gdb.base/hbreak2.exp: hardware breakpoint insertion (the program exited) >> FAIL: gdb.base/hbreak2.exp: run until function breakpoint (the program exited) >> FAIL: gdb.base/hbreak2.exp: run to factorial(6) (the program exited) >> FAIL: gdb.base/hbreak2.exp: run until hardware function breakpoint, optimized file (the program exited) >> >> The problem happens if you only have hardware breakpoints active when >> (re-)starting the program: >> >> (gdb) start >> Temporary breakpoint 1 at 0x401650: file C:/src/repos/binutils-gdb.git/gdb/tests >> uite/gdb.base/break.c, line 43. >> Starting program: C:\gdb\build64\gdb-git\gdb\testsuite\outputs\gdb.base\hbreak2\ >> hbreak2.exe >> >> Temporary breakpoint 1, main (argc=1, argv=0x7e2120, envp=0x7e2900) >> at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.base/break.c:43 >> 43 if (argc == 12345) { /* an unlikely value < 2^16, in case uninited >> */ /* set breakpoint 6 here */ >> (gdb) hb factorial >> Hardware assisted breakpoint 2 at 0x401703: file C:/src/repos/binutils-gdb.git/g >> db/testsuite/gdb.base/break.c, line 63. >> (gdb) r >> The program being debugged has been started already. >> Start it from the beginning? (y or n) y >> Starting program: C:\gdb\build64\gdb-git\gdb\testsuite\outputs\gdb.base\hbreak2\ >> hbreak2.exe >> 720 >> [Inferior 1 (process 7836) exited normally] >> >> But if you stopped just once before reaching the hardware breakpoint, it >> works fine: >> >> (gdb) start >> Temporary breakpoint 3 at 0x401650: file C:/src/repos/binutils-gdb.git/gdb/tests >> uite/gdb.base/break.c, line 43. >> Starting program: C:\gdb\build64\gdb-git\gdb\testsuite\outputs\gdb.base\hbreak2\ >> hbreak2.exe >> >> Temporary breakpoint 3, main (argc=1, argv=0x322120, envp=0x322900) >> at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.base/break.c:43 >> 43 if (argc == 12345) { /* an unlikely value < 2^16, in case uninited >> */ /* set breakpoint 6 here */ >> (gdb) c >> Continuing. >> >> Breakpoint 2, factorial (value=6) >> at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.base/break.c:63 >> 63 if (value > 1) { /* set breakpoint 7 here */ >> >> I found out that cdb writes this error when trying to do the same: >> >> Unable to set breakpoint error >> The system resets thread contexts after the process >> breakpoint so hardware breakpoints cannot be set. >> Go to the executable's entry point and set it then. >> >> So all the hardware breakpoints that were set before (or rather, their >> debug register information) are practically lost when the process entry >> point is reached. >> >> This patch creates an internal breakpoint on the process entry point, which >> when it is reached, resets all active hardware breakpoints, and continues >> execution. > > Eh, I always assumed that the initial breakpoint the Windows debug API emits > during process initialization _was_ the entry point. Where does the PC > point at when the initial breakpoint is reached? > > You can use "starti" to check that. "starti" spawns the process with > target_create_inferior, and then just does not run any other instruction, > It presents the stop where target_create_inferior left the process, which > is supposedly the process's entry point. > > If Windows indeed resets the thread context after the initial > process breakpoint, then it sounds like we also lose any change to > the registers you make after "starti". > > E.g., if you do "starti" + "p $rax = 0xabc" + "stepi", or something like > that. > > It it sounding to me like we should be running to the entry point > in the initialization loop, from within do_initial_windows_stuff? The answer at , seems to confirm it: "If you debugger sets some registry values right now, those changes would not matter, because OS will override all register values while starting executing process. " Interestingly, it also says: "Workaround is simple -- first make a single step using t instruction, then you can use hardware breakpoints as you like." Which makes it sounds like a single-step is all it takes to get to the entry point. That may make it easier to implement this inside do_initial_windows_stuff, including doing the same thing in gdbserver. Thanks, Pedro Alves