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 8B03239574C0 for ; Wed, 13 May 2020 20:53:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8B03239574C0 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-230-_ygzt9xHPaq8LeHAkLXShA-1; Wed, 13 May 2020 16:53:41 -0400 X-MC-Unique: _ygzt9xHPaq8LeHAkLXShA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 045C1801504 for ; Wed, 13 May 2020 20:53:41 +0000 (UTC) Received: from cascais.Home (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8EE5661538 for ; Wed, 13 May 2020 20:53:40 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH v8 1/6] gdb: protect some 'regcache_read_pc' calls Date: Wed, 13 May 2020 21:53:33 +0100 Message-Id: <20200513205338.14233-2-palves@redhat.com> In-Reply-To: <20200513205338.14233-1-palves@redhat.com> References: <20200513205338.14233-1-palves@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-17.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, 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, 13 May 2020 20:53:44 -0000 From: Tankut Baris Aktemur It possible that a thread whose PC we attempt to read is already dead. In this case, 'regcache_read_pc' errors out. This impacts the "proceed" execution flow, where GDB quits early before having a chance to check if there exists a pending event. To remedy, keep going with a 0 value for the PC if 'regcache_read_pc' fails. Because the value of PC before resuming a thread is mostly used for storing and checking the next time the thread stops, this tolerance is expected to be harmless for a dead thread/process. gdb/ChangeLog: 2020-04-03 Tankut Baris Aktemur * regcache.c (regcache_read_pc_protected): New function implementation that returns 0 if the PC cannot read via 'regcache_read_pc'. * infrun.c (proceed): Call 'regcache_read_pc_protected' instead of 'regcache_read_pc'. (keep_going_pass_signal): Ditto. gdbsupport/ChangeLog: 2020-04-03 Tankut Baris Aktemur * common-regcache.h (regcache_read_pc_protected): New function declaration. --- gdb/infrun.c | 7 ++++--- gdb/regcache.c | 18 ++++++++++++++++++ gdbsupport/common-regcache.h | 5 +++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 3c6b201a9fc..5e01336ab09 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2995,7 +2995,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) gdbarch = regcache->arch (); const address_space *aspace = regcache->aspace (); - pc = regcache_read_pc (regcache); + pc = regcache_read_pc_protected (regcache); + thread_info *cur_thr = inferior_thread (); /* Fill in with reasonable starting values. */ @@ -3122,7 +3123,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) advanced. Must do this before resuming any thread, as in all-stop/remote, once we resume we can't send any other packet until the target stops again. */ - cur_thr->prev_pc = regcache_read_pc (regcache); + cur_thr->prev_pc = regcache_read_pc_protected (regcache); { scoped_restore save_defer_tc = make_scoped_defer_target_commit_resume (); @@ -7929,7 +7930,7 @@ keep_going_pass_signal (struct execution_control_state *ecs) /* Save the pc before execution, to compare with pc after stop. */ ecs->event_thread->prev_pc - = regcache_read_pc (get_thread_regcache (ecs->event_thread)); + = regcache_read_pc_protected (get_thread_regcache (ecs->event_thread)); if (ecs->event_thread->control.trap_expected) { diff --git a/gdb/regcache.c b/gdb/regcache.c index 4f079c91a7f..1be794520ec 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1220,6 +1220,24 @@ regcache_read_pc (struct regcache *regcache) return pc_val; } +/* See gdbsupport/common-regcache.h. */ + +CORE_ADDR +regcache_read_pc_protected (regcache *regcache) +{ + CORE_ADDR pc; + try + { + pc = regcache_read_pc (regcache); + } + catch (const gdb_exception_error &ex) + { + pc = 0; + } + + return pc; +} + void regcache_write_pc (struct regcache *regcache, CORE_ADDR pc) { diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h index 18446ff8416..650536e8a88 100644 --- a/gdbsupport/common-regcache.h +++ b/gdbsupport/common-regcache.h @@ -56,6 +56,11 @@ extern int regcache_register_size (const struct regcache *regcache, int n); extern CORE_ADDR regcache_read_pc (struct regcache *regcache); +/* Read the PC register. If PC cannot be read, return 0. + This is a wrapper around 'regcache_read_pc'. */ + +extern CORE_ADDR regcache_read_pc_protected (regcache *regcache); + /* Read a raw register into a unsigned integer. */ extern enum register_status regcache_raw_read_unsigned (struct regcache *regcache, int regnum, ULONGEST *val); -- 2.14.5