This patch adds a new parser_flags type and changes the parser APIs to
use it rather than a collection of 'int' and 'bool'. More flags will
be added in subsquent patches.
This changes field_is_static to be a method on struct field, and
updates all the callers. Most of this patch was written by script.
Regression tested on x86-64 Fedora 36.
binop_promote currently only handles integer sizes up to
builtin_long_long. However, this may not handle 128-bit types.
Simplify this code, unify the C and non-C (but not OpenCL, as I don't
know how to test this) cases, and handle 128-bit integers as well.
This still doesn't exactly follow C or C++ rules. This could be
implemented, but if so, I think it makes more sense as a C-specific
expression node.
This removes deprecated_lval_hack and the VALUE_LVAL macro, replacing
all uses with a call to value::lval.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This introduces the set_lval method on value, one step toward removing
deprecated_lval_hack. Ultimately I think the goal should be for some
of these set_* methods to be replaced with constructors; but I haven't
done this, as the series is already too long. Other 'deprecated'
methods can probably be handled the same way.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This patch turns a grab bag of value functions to methods of value.
These are done together because their implementations are
interrelated.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns value_from_xmethod, result_type_of_xmethod, and
call_xmethod to be methods of value. value_from_xmethod is a static
"constructor" now.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns the remaining value_contents functions -- value_contents,
value_contents_all, value_contents_for_printing, and
value_contents_for_printing_const -- into methods of value. It also
converts the static functions require_not_optimized_out and
require_available to be private methods.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes value_fetch_lazy to be a method of value. A few helper
functions are converted as well, to avoid problems in later patches
when the data members are all made private.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This turns value_contents_raw, value_contents_writeable, and
value_contents_all_raw into methods on value. The remaining functions
will be changed later in the series; they were a bit trickier and so I
didn't include them in this patch.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes the value_lazy and set_value_lazy functions to be methods
of value. Much of this patch was written by script.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes various offset-related functions to be methods of value.
Much of this patch was written by script.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This changes deprecated_set_value_type to be a method of value. Much
of this patch was written by script.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
PR c++/29503 points out that something like "b->Base::member" will
crash when 'b' does not have pointer type. This seems to be a simple
oversight in eval_op_member.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29503
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
Add the `length` and `set_length` methods on `struct type`, in order to remove
the `TYPE_LENGTH` macro. In this patch, the macro is changed to use the
getter, so all the call sites of the macro that are used as a setter are
changed to use the setter method directly. The next patch will remove the
macro completely.
Change-Id: Id1090244f15c9856969b9be5006aefe8d8897ca4
This updates the Ada expression parser to implement context-sensitive
field name completion. This is PR ada/28727.
This is somewhat complicated due to some choices in the Ada lexer --
it chooses to represent a sequence of "."-separated identifiers as a
single token, so the parser must partially recreate the completer's
logic to find the completion word boundaries.
Despite the minor warts in this patch, though, it is a decent
improvement. It's possible that the DWARF reader rewrite will help
fix the package completion problem pointed out in this patch as well.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28727
This refactors the gdb expression completion code to make it easier to
add more types of completers.
In the old approach, just two kinds of completers were supported:
field names for some sub-expression, or tag names (like "enum
something"). The data for each kind was combined in single structure,
"expr_completion_state", and handled explicitly by
complete_expression.
In the new approach, the parser state just holds an object that is
responsible for implementing completion. This way, new completion
types can be added by subclassing this base object.
The structop completer is moved into structop_base_operation, and new
objects are defined for use by the completion code. This moves much
of the logic of expression completion out of completer.c as well.
On x86 machines with xmm register, and with recent versions of
systemtap (and gcc?), it can occur that stap probe arguments will be
placed into xmm registers.
I notice this happening on a current Fedora Rawhide install with the
following package versions installed:
$ rpm -q glibc systemtap gcc
glibc-2.35.9000-10.fc37.x86_64
systemtap-4.7~pre16468670g9f253544-1.fc37.x86_64
gcc-12.0.1-0.12.fc37.x86_64
If I check the probe data in libc, I see this:
$ readelf -n /lib64/libc.so.6
...
stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors)
Provider: libc
Name: pthread_start
Location: 0x0000000000090ac3, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000
Arguments: 8@%xmm1 8@1600(%rbx) 8@1608(%rbx)
stapsdt 0x00000050 NT_STAPSDT (SystemTap probe descriptors)
Provider: libc
Name: pthread_create
Location: 0x00000000000912f1, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000
Arguments: 8@%xmm1 8@%r13 8@8(%rsp) 8@16(%rsp)
...
Notice that for both of these probes, the first argument is a uint64_t
stored in the xmm1 register.
Unfortunately, if I try to use this probe within GDB, then I can't
view the first argument. Here's an example session:
$ gdb $(which gdb)
(gdb) start
...
(gdb) info probes stap libc pthread_create
...
(gdb) break *0x00007ffff729e2f1 # Use address of probe.
(gdb) continue
...
(gdb) p $_probe_arg0
Invalid cast.
What's going wrong? If I re-run my session, but this time use 'set
debug stap-expression 1', this is what I see:
(gdb) set debug stap-expression 1
(gdb) p $_probe_arg0
Operation: UNOP_CAST
Operation: OP_REGISTER
String: xmm1
Type: uint64_t
Operation: UNOP_CAST
Operation: OP_REGISTER
String: r13
Type: uint64_t
Operation: UNOP_CAST
Operation: UNOP_IND
Operation: UNOP_CAST
Operation: BINOP_ADD
Operation: OP_LONG
Type: long
Constant: 0x0000000000000008
Operation: OP_REGISTER
String: rsp
Type: uint64_t *
Type: uint64_t
Operation: UNOP_CAST
Operation: UNOP_IND
Operation: UNOP_CAST
Operation: BINOP_ADD
Operation: OP_LONG
Type: long
Constant: 0x0000000000000010
Operation: OP_REGISTER
String: rsp
Type: uint64_t *
Type: uint64_t
Invalid cast.
(gdb)
The important bit is this:
Operation: UNOP_CAST
Operation: OP_REGISTER
String: xmm1
Type: uint64_t
Which is where we cast the xmm1 register to uint64_t. And the final
piece of the puzzle is:
(gdb) ptype $xmm1
type = union vec128 {
v8bf16 v8_bfloat16;
v4f v4_float;
v2d v2_double;
v16i8 v16_int8;
v8i16 v8_int16;
v4i32 v4_int32;
v2i64 v2_int64;
uint128_t uint128;
}
So, we are attempting to cast a union type to a scalar type, which is
not supporting in C/C++, and as a consequence GDB's expression
evaluator throws an error when we attempt to do this.
The first approach I considered for solving this problem was to try
and make use of gdbarch_stap_adjust_register. We already have a
gdbarch method (gdbarch_stap_adjust_register) that allows us to tweak
the name of the register that we access. Currently only x86
architectures use this to transform things like ax to eax in some
cases.
I wondered, what if we change gdbarch_stap_adjust_register to do more
than just change the register names? What if this method instead
became gdbarch_stap_read_register. This new method would return a
operation_up, and would take the register name, and the type we are
trying to read from the register, and return the operation that
actually reads the register.
The default implementation of this method would just use
user_reg_map_name_to_regnum, and then create a register_operation,
like we already do in stap_parse_register_operand. But, for x86
architectures this method would fist possibly adjust the register
name, then do the default action to read the register. Finally, for
x86 this method would spot when we were accessing an xmm register,
and, based on the type being pulled from the register, would extract
the correct field from the union.
The benefit of this approach is that it would work with the expression
types that GDB currently supports. The draw back would be that this
approach would not be very generic. We'd need code to handle each
sub-field size with an xmm register. If other architectures started
using vector registers for probe arguments, those architectures would
have to create their own gdbarch_stap_read_register method. And
finally, the type of the xmm registers comes from the type defined in
the target description, there's a risk that GDB might end up
hard-coding the names of type sub-fields, then if a target uses a
different target description, with different field names for xmm
registers, the stap probes would stop working.
And so, based on all the above draw backs, I rejected this first
approach.
My second plan involves adding a new expression type to GDB called
unop_extract_operation. This new expression takes a value and a type,
during evaluation the value contents are fetched, and then a new value
is extracted from the value contents (based on type). This is similar
to the following C expression:
result_value = *((output_type *) &input_value);
Obviously we can't actually build this expression in this case, as the
input_value is in a register, but hopefully the above makes it clearer
what I'm trying to do.
The benefit of the new expression approach is that this code can be
shared across all architectures, and it doesn't care about sub-field
names within the union type.
The draw-backs that I see are potential future problems if arguments
are not stored within the least significant bytes of the register.
However if/when that becomes an issue we can adapt the
gdbarch_stap_read_register approach to allow architectures to control
how a value is extracted.
For testing, I've extended the existing gdb.base/stap-probe.exp test
to include a function that tries to force an argument into an xmm
register. Obviously, that will only work on a x86 target, so I've
guarded the new function with an appropriate GCC define. In the exp
script we use readelf to check if the probe exists, and is using the
xmm register.
If the probe doesn't exist then the associated tests are skipped.
If the probe exists, put isn't using the xmm register (which will
depend on systemtap/gcc versions), then again, the tests are skipped.
Otherwise, we can run the test. I think the cost of running readelf
is pretty low, so I don't feel too bad making all the non-xmm targets
running this step.
I found that on a Fedora 35 install, with these packages installed, I
was able to run this test and have the probe argument be placed in an
xmm register:
$ rpm -q systemtap gcc glibc
systemtap-4.6-4.fc35.x86_64
gcc-11.2.1-9.fc35.x86_64
glibc-2.34-7.fc35.x86_64
Finally, as this patch adds a new operation type, then I need to
consider how to generate an agent expression for the new operation
type.
I have kicked the can down the road a bit on this. In the function
stap_parse_register_operand, I only create a unop_extract_operation in
the case where the register type is non-scalar, this means that in
most cases I don't need to worry about generating an agent expression
at all.
In the xmm register case, when an unop_extract_operation will be
created, I have sketched out how the agent expression could be
handled, however, this code is currently not reached. When we try to
generate the agent expression to place the xmm register on the stack,
GDB hits this error:
(gdb) trace -probe-stap test:xmmreg
Tracepoint 1 at 0x401166
(gdb) actions
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
>collect $_probe_arg0
Value not scalar: cannot be an rvalue.
This is because GDB doesn't currently support placing non-scalar types
on the agent expression evaluation stack. Solving this is clearly
related to the original problem, but feels a bit like a second
problem. I'd like to get feedback on whether my approach to solving
the original problem is acceptable or not before I start looking at
how to handle xmm registers within agent expressions.
eval_op_concat has code to search for an operator overload of
BINOP_CONCAT. However, the operator overloading code is specific to
C++, which does not have this operator. And,
binop_types_user_defined_p rejects this case right at the start, and
value_x_binop does not handle this case. I think this code has been
dead for a very long time. This patch removes it and hoists the
remaining call into concatenation::evaluate, removing eval_op_concat
entirely.
eval_op_string is only used in a single place -- the implementation of
string_operation. This patch turns it into the
string_operation::evaluate method, removing a bit of extraneous code.
Add a getter and a setter for a symbol's type. Remove the corresponding
macro and adjust all callers.
Change-Id: Ie1a137744c5bfe1df4d4f9ae5541c5299577c8de
I noticed that the AdaCore tree had a small divergence in eval.c -- it
had a fix for an indentation problem in binop_promote. I'm checking
in this small fix as obvious.
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.
For the avoidance of doubt, all changes in this commits were
performed by the script.
The bug fixed by this [1] patch was caused by an out-of-bounds access to
a value's content. The code gets the value's content (just a pointer)
and then indexes it with a non-sensical index.
This made me think of changing functions that return value contents to
return array_views instead of a plain pointer. This has the advantage
that when GDB is built with _GLIBCXX_DEBUG, accesses to the array_view
are checked, making bugs more apparent / easier to find.
This patch changes the return types of these functions, and updates
callers to call .data() on the result, meaning it's not changing
anything in practice. Additional work will be needed (which can be done
little by little) to make callers propagate the use of array_view and
reap the benefits.
[1] https://sourceware.org/pipermail/gdb-patches/2021-September/182306.html
Change-Id: I5151f888f169e1c36abe2cbc57620110673816f3
Remove the `TYPE_FIELD_NAME` and `FIELD_NAME` macros, changing all the
call sites to use field::name directly.
Change-Id: I6900ae4e1ffab1396e24fb3298e94bf123826ca6
I noticed that value_true is declared in language.h and defined in
language.c. However, as part of the value API, I think it would be
better in one of those files. And, because it is very short, I
changed it to be an inline function in value.h. I've also removed a
comment from the implementation, on the basis that it seems obsolete
-- if the change it suggests was needed, it probably would have been
done by now; and if it is needed in the future, odds are it would be
done differently anyway.
Finally, this patch also changes value_true and value_logical_not to
return a bool, and updates some uses.
I noticed that pointer_type is declared in language.h and defined in
language.c. However, it really has to do with types, so it should
have been in gdbtypes.h all along.
This patch changes it to be a method on struct type. And, I went
through uses of TYPE_IS_REFERENCE and updated many spots to use the
new method as well. (I didn't update ones that were in arch-specific
code, as I couldn't readily test that.)
Following on from the previous commit, this commit changes the API of
value_struct_elt to take gdb::optional<gdb::array_view<value *>>
instead of a pointer to the gdb::array_view.
This makes the optional nature of the array_view parameter explicit.
This commit is purely a refactoring commit, there should be no user
visible change after this commit.
I have deliberately kept this refactor separate from the previous two
commits as this is a more extensive change, and I'm not 100% sure that
using gdb::optional for the parameter type, instead of a pointer, is
going to be to everyone's taste. If there's push back on this patch
then this one can be dropped from the series.
gdb/ChangeLog:
* ada-lang.c (desc_bounds): Use '{}' instead of NULL to indicate
an empty gdb::optional when calling value_struct_elt.
(desc_data): Likewise.
(desc_one_bound): Likewise.
* eval.c (structop_base_operation::evaluate_funcall): Pass
gdb::array_view, not a gdb::array_view* to value_struct_elt.
(eval_op_structop_struct): Use '{}' instead of NULL to indicate
an empty gdb::optional when calling value_struct_elt.
(eval_op_structop_ptr): Likewise.
* f-lang.c (fortran_structop_operation::evaluate): Likewise.
* guile/scm-value.c (gdbscm_value_field): Likewise.
* m2-lang.c (eval_op_m2_high): Likewise.
(eval_op_m2_subscript): Likewise.
* opencl-lang.c (opencl_structop_operation::evaluate): Likewise.
* python/py-value.c (valpy_getitem): Likewise.
* rust-lang.c (rust_val_print_str): Likewise.
(rust_range): Likewise.
(rust_subscript): Likewise.
(eval_op_rust_structop): Likewise.
(rust_aggregate_operation::evaluate): Likewise.
* valarith.c (value_user_defined_op): Likewise.
* valops.c (search_struct_method): Change parameter type, update
function body accordingly, and update header comment.
(value_struct_elt): Change parameter type, update function body
accordingly.
* value.h (value_struct_elt): Update declaration.
After the previous commit, this commit updates the value_struct_elt
function to take an array_view rather than a NULL terminated array of
values.
The requirement for a NULL terminated array of values actually stems
from typecmp, so the change from an array to array_view needs to be
propagated through to this function.
While making this change I noticed that this fixes another bug, in
value_x_binop and value_x_unop GDB creates an array of values which
doesn't have a NULL at the end. An array_view of this array is passed
to value_user_defined_op, which then unpacks the array_view and passed
the raw array to value_struct_elt, but only if the language is not
C++.
As value_x_binop and value_x_unop can only request member functions
with the names of C++ operators, then most of the time, assuming the
inferior is not a C++ program, then GDB will not find a matching
member function with the call to value_struct_elt, and so typecmp will
never be called, and so, GDB will avoid undefined behaviour.
However, it is worth remembering that, when GDB's language is set to
"auto", the current language is selected based on the language of the
current compilation unit. As C++ programs usually link against libc,
which is written in C, then, if the inferior is stopped in libc GDB
will set the language to C. And so, it is possible that we will end
up using value_struct_elt to try and lookup, and match, a C++
operator. If this occurs then GDB will experience undefined
behaviour.
I have extended the test added in the previous commit to also cover
this case.
Finally, this commit changes the API from passing around a pointer to
an array to passing around a pointer to an array_view. The reason for
this is that we need to be able to distinguish between the cases where
we call value_struct_elt with no arguments, i.e. we are looking up a
struct member, but we either don't have the arguments we want to pass
yet, or we don't expect there to be any need for GDB to use the
argument types to resolve any overloading; and the second case where
we call value_struct_elt looking for a function that takes no
arguments, that is, the argument list is empty.
NOTE: While writing this I realise that if we pass an array_view at
all then it will always have at least one item in it, the `this'
pointer for the object we are planning to call the method on. So we
could, I guess, pass an empty array_view to indicate the case where we
don't know anything about the arguments, and when the array_view is
length 1 or more, it means we do have the arguments. However, though
we could do this, I don't think this would be better, the length 0 vs
length 1 difference seems a little too subtle, I think that there's a
better solution...
I think a better solution would be to wrap the array_view in a
gdb::optional, this would make the whole, do we have an array view or
not question explicit.
I haven't done this as part of this commit as making that change is
much more extensive, every user of value_struct_elt will need to be
updated, and as this commit already contains a bug fix, I wanted to
keep the large refactoring in a separate commit, so, check out the
next commit for the use of gdb::optional.
gdb/ChangeLog:
PR gdb/27994
* eval.c (structop_base_operation::evaluate_funcall): Pass
array_view instead of array to value_struct_elt.
* valarith.c (value_user_defined_op): Likewise.
* valops.c (typecmp): Change parameter type from array pointer to
array_view. Update header comment, and update body accordingly.
(search_struct_method): Likewise.
(value_struct_elt): Likewise.
* value.h (value_struct_elt): Update declaration.
gdb/testsuite/ChangeLog:
PR gdb/27994
* gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=,
change initial value of var member variable.
(main): Make use of foo_type's operator+=.
* gdb.cp/method-call-in-c.exp: Test use of operator+=.
This regression, as it is exposed by the test added in this commit,
first became noticable with this commit:
commit d182f27979
Date: Mon Mar 8 07:27:57 2021 -0700
Convert c-exp.y to use operations
But, this commit only added converted the C expression parser to make
use of code that was added in this commit:
commit a00b7254fb
Date: Mon Mar 8 07:27:57 2021 -0700
Implement function call operations
And it was this second commit that actually introduced the bugs (there
are two).
In structop_base_operation::evaluate_funcall we build up an argument
list in the vector vals. Later in this function the argument list
might be passed to value_struct_elt.
Prior to commit a00b7254fb the vals vector (or argvec as it used to
be called) stored the value for the function callee in the argvec at
index 0. This 'callee' value is what ends up being passed to
evaluate_subexp_do_call, and represents the function to be called, the
value contents are the address of the function, and the value type is
the function signature. The remaining items held in the argvec were
the values to pass to the function. For a non-static member function
the `this' pointer would be at index 1 in the array.
After commit a00b7254fb this callee value is now held in a separate
variable, not the vals array. So, for non-static member functions,
the `this' pointer is now at index 0, with any other arguments after
that.
What this means is that previous, when we called value_struct_elt we
would pass the address of argvec[1] as this was the first argument.
But now we should be passing the address of vals[0]. Unfortunately,
we are still passing vals[1], effectively skipping the first
argument.
The second issue is that, prior to commit a00b7254fb, the argvec
array was NULL terminated. This is required as value_struct_elt
calls search_struct_method, which calls typecmp, and typecmp requires
that the array have a NULL at the end.
After commit a00b7254fb this NULL has been lost, and we are
therefore violating the API requirements of typecmp.
This commit fixes both of these regressions. I also extended the
header comments on search_struct_method and value_struct_elt to make
it clearer that the array required a NULL marker at the end.
You will notice in the test attached to this commit that I test
calling a non-static member function, but not calling a static member
function. The reason for this is that calling static member functions
is currently broken due to a different bug. That will be fixed in a
later patch in this series, at which time I'll add a test for calling
a static member function.
gdb/ChangeLog:
PR gdb/27994
* eval.c (structop_base_operation::evaluate_funcall): Add a
nullptr to the end of the args array, which should not be included
in the argument array_view. Pass all the arguments through to
value_struct_elt.
* valops.c (search_struct_method): Update header comment.
(value_struct_elt): Likewise.
gdb/testsuite/ChangeLog:
PR gdb/27994
* gdb.cp/method-call-in-c.cc: New file.
* gdb.cp/method-call-in-c.exp: New file.
Evaluating expressions from within an inferior exit event handler can
cause a crash:
echo "int main() { return 0; }" > repro.c
gcc -g repro.c -o repro
./gdb -q --ex "set language c++" --ex "python gdb.events.exited.connect(lambda _: gdb.execute('set \$_a=0'))" --ex "run" repro
Reading symbols from repro...
Starting program: /home/mhov/repos/binutils-gdb-master/install-bad/bin/repro
[Inferior 1 (process 1974779) exited normally]
../../gdb/thread.c:72: internal-error: thread_info* inferior_thread(): Assertion `current_thread_ != nullptr' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) [answered Y; input not from terminal]
This is a bug, please report it. For instructions, see:
<https://www.gnu.org/software/gdb/bugs/>.
Backtrace
0 in internal_error of ../../gdbsupport/errors.cc:51
1 in inferior_thread of ../../gdb/thread.c:72
2 in expression::evaluate of ../../gdb/eval.c:98
3 in evaluate_expression of ../../gdb/eval.c:115
4 in set_command of ../../gdb/printcmd.c:1502
5 in do_const_cfunc of ../../gdb/cli/cli-decode.c:101
6 in cmd_func of ../../gdb/cli/cli-decode.c:2181
7 in execute_command of ../../gdb/top.c:670
...
22 in python_inferior_exit of ../../gdb/python/py-inferior.c:182
In `expression::evaluate (...)' there is a call to `inferior_thread
()' that is guarded by `target_has_execution ()':
struct value *
expression::evaluate (struct type *expect_type, enum noside noside)
{
gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
if (target_has_execution ()
&& language_defn->la_language == language_cplus
&& !thread_stack_temporaries_enabled_p (inferior_thread ()))
stack_temporaries.emplace (inferior_thread ());
The `target_has_execution ()' guard maps onto `inf->pid' and the
`inferior_thread ()' call assumes that `current_thread_' is set to
something meaningful:
struct thread_info*
inferior_thread (void)
{
gdb_assert (current_thread_ != nullptr);
return current_thread_;
}
In other words, it is assumed that if `inf->pid' is set then
`current_thread_' must also be set. This does not hold at the point
where inferior exit observers are notified:
- `generic_mourn_inferior (...)'
- `switch_to_no_thread ()'
- `current_thread_ = nullptr;'
- `exit_inferior (...)'
- `gdb::observers::inferior_exit.notify (...)'
- `inf->pid = 0'
The inferior exit notification means that a Python handler can get a
chance to run while `current_thread' has been cleared and the
`inf->pid' has not been cleared. Since the Python handler can call any
GDB command with `gdb.execute(...)' (in my case `gdb.execute("set
$_a=0")' we can end up evaluating expressions and asserting in
`evaluate_subexp (...)'.
This patch adds a test in `evaluate_subexp (...)' to check the global
`inferior_ptid' which is reset at the same time as `current_thread_'.
Checking `inferior_ptid' at the same time as `target_has_execution ()'
seems to be a common pattern:
$ git grep -n -e inferior_ptid --and -e target_has_execution
gdb/breakpoint.c:2998: && (inferior_ptid == null_ptid || !target_has_execution ()))
gdb/breakpoint.c:3054: && (inferior_ptid == null_ptid || !target_has_execution ()))
gdb/breakpoint.c:4587: if (inferior_ptid == null_ptid || !target_has_execution ())
gdb/infcmd.c:360: if (inferior_ptid != null_ptid && target_has_execution ())
gdb/infcmd.c:2380: /* FIXME: This should not really be inferior_ptid (or target_has_execution).
gdb/infrun.c:3438: if (!target_has_execution () || inferior_ptid == null_ptid)
gdb/remote.c:11961: if (!target_has_execution () || inferior_ptid == null_ptid)
gdb/solib.c:725: if (target_has_execution () && inferior_ptid != null_ptid)
The testsuite has been run on 5.4.0-59-generic x86_64 GNU/Linux:
- Ubuntu 20.04.1 LTS
- gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
- DejaGnu version 1.6.2
- Expect version 5.45.4
- Tcl version 8.6
- Native configuration: x86_64-pc-linux-gnu
- Target: unix
Results show a few XFAIL in
gdb.threads/attach-many-short-lived-threads.exp. The existing
py-events.exp tests are skipped for native-gdbserver and fail for
native-extended-gdbserver, but the new tests pass with
native-extended-gdbserver when run without the existing tests.
gdb/ChangeLog:
2021-06-03 Magne Hov <mhov@undo.io>
PR python/27841
* eval.c (expression::evaluate): Check inferior_ptid.
gdb/testsuite/ChangeLog:
2021-06-03 Magne Hov <mhov@undo.io>
PR python/27841
* gdb.python/py-events.exp: Extend inferior exit tests.
* gdb.python/py-events.py: Print inferior exit PID.
The current_top_target function is a hidden dependency on the current
inferior. Since I'd like to slowly move towards reducing our dependency
on the global current state, remove this function and make callers use
current_inferior ()->top_target ()
There is no expected change in behavior, but this one step towards
making those callers use the inferior from their context, rather than
refer to the global current inferior.
gdb/ChangeLog:
* target.h (current_top_target): Remove, make callers use the
current inferior instead.
* target.c (current_top_target): Remove.
Change-Id: Iccd457036f84466cdaa3865aa3f9339a24ea001d