This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 2/2] OpenMP: Search ancestor threads for variables
- From: Kevin Buettner <kevinb at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 29 Nov 2017 21:55:19 -0700
- Subject: Re: [PATCH 2/2] OpenMP: Search ancestor threads for variables
- Authentication-results: sourceware.org; auth=none
- References: <20171129215103.093cc881@pinnacle.lan>
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);