From: Hannes Domani Date: Tue, 12 Dec 2023 14:53:12 +0000 (+0100) Subject: Support dynamically computed convenience variables in get_internalvar_integer X-Git-Tag: binutils-2_42~618 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=52e0b52e6f2dc1dc5a7b95740d22fd616241db67;p=thirdparty%2Fbinutils-gdb.git Support dynamically computed convenience variables in get_internalvar_integer When using $_thread in info threads to showonly the current thread, you get this error: ``` (gdb) info thread $_thread Convenience variable must have integer value. Args must be numbers or '$' variables. ``` It's because $_thread is a dynamically computed convenience variable, which isn't supported yet by get_internalvar_integer. Now the output looks like this: ``` (gdb) info threads $_thread Id Target Id Frame * 1 Thread 10640.0x2680 main () at C:/src/repos/binutils-gdb.git/gdb/testsuite/gdb.base/gdbvars.c:21 ``` Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17600 Approved-By: Tom Tromey --- diff --git a/gdb/testsuite/gdb.base/gdbvars.exp b/gdb/testsuite/gdb.base/gdbvars.exp index cb6656c176f..d4b2860de7f 100644 --- a/gdb/testsuite/gdb.base/gdbvars.exp +++ b/gdb/testsuite/gdb.base/gdbvars.exp @@ -158,6 +158,11 @@ proc test_with_program {} { "Set a new convenience variable to a program variable" gdb_test "print /x \$prog_var" " = $hex" \ "Print contents of new convenience variable of program variable" + + # Test $_thread/$_inferior convenience variables in various commands. + gdb_test "info threads \$_thread" "\\* 1 .* main.*" + gdb_test "info inferiors \$_inferior" "\\* 1 .* process.*" + gdb_test "break foo_int thread \$_thread" "Breakpoint \[0-9\]*.*" } gdb_test_no_output "set print sevenbit-strings" diff --git a/gdb/thread.c b/gdb/thread.c index c0ed64e5f8b..85bdbaa6cd8 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1129,6 +1129,10 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, for (thread_info *tp : all_threads ()) { + /* In case REQUESTED_THREADS contains $_thread. */ + if (current_thread != nullptr) + switch_to_thread (current_thread); + if (!should_print_thread (requested_threads, default_inf_num, global_ids, pid, tp)) continue; @@ -1176,6 +1180,10 @@ print_thread_info_1 (struct ui_out *uiout, const char *requested_threads, if (tp == current_thread && tp->state == THREAD_EXITED) current_exited = true; + /* In case REQUESTED_THREADS contains $_thread. */ + if (current_thread != nullptr) + switch_to_thread (current_thread); + if (!should_print_thread (requested_threads, default_inf_num, global_ids, pid, tp)) continue; diff --git a/gdb/value.c b/gdb/value.c index 1a3985582ba..e9308b04f93 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2119,6 +2119,21 @@ get_internalvar_integer (struct internalvar *var, LONGEST *result) } } + if (var->kind == INTERNALVAR_MAKE_VALUE) + { + struct gdbarch *gdbarch = get_current_arch (); + struct value *val + = (*var->u.make_value.functions->make_value) (gdbarch, var, + var->u.make_value.data); + struct type *type = check_typedef (val->type ()); + + if (type->code () == TYPE_CODE_INT) + { + *result = value_as_long (val); + return 1; + } + } + return 0; }