From patchwork Thu Nov 30 04:55:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 24624 Received: (qmail 42484 invoked by alias); 30 Nov 2017 04:55:24 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 42469 invoked by uid 89); 30 Nov 2017 04:55:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, KB_WAM_FROM_NAME_SINGLEWORD, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=hosting, formerly X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 30 Nov 2017 04:55:22 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8E85C02738B for ; Thu, 30 Nov 2017 04:55:21 +0000 (UTC) Received: from pinnacle.lan (ovpn-121-48.rdu2.redhat.com [10.10.121.48]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3D4535D973 for ; Thu, 30 Nov 2017 04:55:21 +0000 (UTC) Date: Wed, 29 Nov 2017 21:55:19 -0700 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: Re: [PATCH 2/2] OpenMP: Search ancestor threads for variables Message-ID: <20171129215519.085ed0bb@pinnacle.lan> In-Reply-To: <20171129215103.093cc881@pinnacle.lan> References: <20171129215103.093cc881@pinnacle.lan> MIME-Version: 1.0 X-IsSubscribed: yes Consider this simple OpenMP program: void foo (int a1) {} int main (void) { static int s1 = -41; int i1 = 11, i2; for (i2 = 1; i2 <= 2; i2++) { int pass = i2; #pragma omp parallel num_threads (2) firstprivate (i1) { foo (i1); } foo(pass); } foo (s1); foo (i2); } When using a recent (development version) of GCC, GDB is now able to access variables i2, and pass in the master thread. (s1, due to being a static variable is accessible from either thread. Accessing i1 has been possible for a long while now.) This patch makes variables such as i2 and pass accessible in all other threads as well. (Well, it does so long as a suitable "thread parent" plugin is installed for libgomp.) gdb/ChangeLog: findvar.c (gdbthread.h): Include. (get_hosting_frame): Add new parameter, errorp. Delete code which generates an error and set errorp instead. (default_read_var_value): Call get_hosting_frame() for ancestor threads in addition to current thread. Print errors formerly printed by get_hosting_frame(). --- gdb/findvar.c | 55 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/gdb/findvar.c b/gdb/findvar.c index 2bc2095..81cac7d 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -33,6 +33,7 @@ #include "language.h" #include "dwarf2loc.h" #include "selftest.h" +#include "gdbthread.h" /* Basic byte-swapping routines. All 'extract' functions return a host-format integer from a target-format integer at ADDR which is @@ -474,10 +475,12 @@ follow_static_link (struct frame_info *frame, static struct frame_info * get_hosting_frame (struct symbol *var, const struct block *var_block, - struct frame_info *frame) + struct frame_info *frame, bool *errorp) { const struct block *frame_block = NULL; + *errorp = false; + if (!symbol_read_needs_frame (var)) return NULL; @@ -564,17 +567,7 @@ get_hosting_frame (struct symbol *var, const struct block *var_block, if (frame == NULL) { frame = block_innermost_frame (var_block); - if (frame == NULL) - { - if (BLOCK_FUNCTION (var_block) - && !block_inlined_p (var_block) - && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (var_block))) - error (_("No frame is currently executing in block %s."), - SYMBOL_PRINT_NAME (BLOCK_FUNCTION (var_block))); - else - error (_("No frame is currently executing in specified" - " block")); - } + *errorp = true; } return frame; @@ -605,8 +598,44 @@ default_read_var_value (struct symbol *var, const struct block *var_block, else if (sym_need == SYMBOL_NEEDS_REGISTERS && !target_has_registers) error (_("Cannot read `%s' without registers"), SYMBOL_PRINT_NAME (var)); + scoped_restore_current_thread restore_thread; + if (frame != NULL) - frame = get_hosting_frame (var, var_block, frame); + { + struct frame_info *frame0 = frame; + bool errorp; + + frame = get_hosting_frame (var, var_block, frame0, &errorp); + + /* If the hosting frame could not be determined for the current thread, + try again using ancestor threads. This allows GDB to find variables + in outlined OpenMP functions. */ + while (frame == NULL) + { + struct thread_info *thr_parent = thread_parent (inferior_thread ()); + + if (thr_parent == NULL) + break; + + switch_to_thread (thr_parent->ptid); + /* frame0 will not be on the stack after switching threads. So, + instead, search using the current frame. */ + frame0 = get_current_frame (); + frame = get_hosting_frame (var, var_block, frame0, &errorp); + } + + if (frame == NULL && errorp) + { + if (BLOCK_FUNCTION (var_block) + && !block_inlined_p (var_block) + && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (var_block))) + error (_("No frame is currently executing in block %s."), + SYMBOL_PRINT_NAME (BLOCK_FUNCTION (var_block))); + else + error (_("No frame is currently executing in specified" + " block")); + } + } if (SYMBOL_COMPUTED_OPS (var) != NULL) return SYMBOL_COMPUTED_OPS (var)->read_variable (var, frame);