Age | Commit message (Collapse) | Author | Files | Lines |
|
In the following commit I ran into a problem. The next commit aims to
improve GDB's handling of the main executable being a file on a remote
target (i.e. one with a 'target:' prefix).
To do this I have replaced a system 'stat' call with a bfd_stat call.
However, doing this caused a regression in gdb.base/attach.exp.
The problem is that the bfd library caches open FILE* handles for bfd
objects that it has accessed, which is great for short-lived, non
interactive programs (e.g. the assembler, or objcopy, etc), however,
for GDB this caching causes us a problem.
If we open the main executable as a bfd then the bfd library will
cache the open FILE*. If some time passes, maybe just sat at the GDB
prompt, or with the inferior running, and then later we use bfd_stat
to check if the underlying, on-disk file has changed, then the bfd
library will actually use fstat on the underlying file descriptor.
This is of course slightly different than using system stat on with
the on-disk file name.
If the on-disk file has changed then system stat will give results for
the current on-disk file. But, if the bfd cache is still holding open
the file descriptor for the original on-disk file (from before the
change) then fstat will return a result based on the original file,
and so show no change as having happened.
This is a known problem in GDB, and so far this has been solved by
scattering bfd_cache_close_all() calls throughout GDB. But, as I
said, in the next commit I've made a change and run into a
problem (gdb.base/attach.exp) where we are apparently missing a
bfd_cache_close_all() call.
Now I could solve this problem by adding a bfd_cache_close_all() call
before the bfd_stat call that I plan to add in the next commit, that
would for sure solve the problem, but feels a little crude.
Better I think would be to track down where the bfd is being opened
and add a corresponding bfd_cache_close_all() call elsewhere in GDB
once we've finished doing whatever it is that caused us to open the
bfd in the first place.
This second solution felt like the better choice, so I tracked the
problem down to elf_locate_base and fixed that. But that just exposed
another problem in gdb_bfd_map_section which was also re-opening the
bfd, so I fixed this (with another bfd_cache_close_all() call), and
that exposed another issue in gdbarch_lookup_osabi... and at this
point I wondered if I was approaching this problem the wrong way...
.... And so, I wonder, is there a _better_ way to handle these
bfd_cache_close_all() calls?
I see two problems with the current approach:
1. It's fragile. Folk aren't always aware that they need to clear
the bfd cache, and this feels like something that is easy to
overlook in review. So adding new code to GDB can innocently touch
a bfd, which populates the cache, which will then be a bug that can
lie hidden until an on-disk file just happens to change at the wrong
time ... and GDB fails to spot the change. Additionally,
2. It's in efficient. The caching is intended to stop the bfd
library from continually having to re-open the on-disk file. If we
have a function that touches a bfd then often that function is the
obvious place to call bfd_cache_close_all. But if a single GDB
command calls multiple functions, each of which touch the bfd, then
we will end up opening and closing the same on-disk file multiple
times. It feels like we would be better postponing the
bfd_cache_close_all call until some later point, then we can benefit
from the bfd cache.
So, in this commit I propose a new approach. We now clear the bfd
cache in two places:
(a) Just before we display a GDB prompt. We display a prompt after
completing a command, and GDB is about to enter an idle state
waiting for further input from the user (or in async mode, for an
inferior event). If while we are in this idle state the user
changes the on-disk file(s) then we would like GDB to notice this
the next time it leaves its idle state, e.g. the next time the user
executes a command, or when an inferior event arrives,
(b) When we resume the inferior. In synchronous mode, resuming the
inferior is another time when GDB is blocked and sitting idle, but
in this case we don't display a prompt. As with (a) above, when an
inferior event arrives we want GDB to notice any changes to on-disk
files.
It turns out that there are existing observers for both of these
cases (before_prompt and target_resumed respectively), so my initial
thought was that I should attach to these observers in gdb_bfd.c, and
in both cases call bfd_cache_close_all().
And this does indeed solve the gdb.base/attach.exp problem that I see
with the following commit.
However, I see a problem with this solution.
Both of the observers I'm using are exposed through the Python API as
events that a user can hook into. The user can potentially run any
GDB command (using gdb.execute), so Python code might end up causing
some bfds to be reopened, and inserted into the cache.
To solve this one solution would be to add a bfd_cache_close_all()
call into gdbpy_enter::~gdbpy_enter(). Unfortunately, there's no
similar enter/exit object for Guile, though right now Guile doesn't
offer the same event API, so maybe we could just ignore that
problem... but this doesn't feel great.
So instead, I think a better solution might be to not use observers
for the bfd_cache_close_all() calls. Instead, I'll call
bfd_cache_close_all() directly from core GDB after we've notified the
before_prompt and target_resumed observers, this was we can be sure
that the cache is cleared after the observers have run, and before GDB
enters an idle state.
This commit also removes all of the other bfd_cache_close_all() calls
from GDB. My claim is that these are no longer needed.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Remove get_current_regcache, inlining the call to get_thread_regcache in
callers. When possible, pass the right thread_info object known from
the local context. Otherwise, fall back to passing `inferior_thread ()`.
This makes the reference to global context bubble up one level, a small
step towards the long term goal of reducing the number of references to
global context (or rather, moving those references as close as possible
to the top of the call tree).
No behavior change expected.
Change-Id: Ifa6980c88825d803ea586546b6b4c633c33be8d6
|
|
This function is just a wrapper around the current inferior's gdbarch.
I find that having that wrapper just obscures where the arch is coming
from, and that it's often used as "I don't know which arch to use so
I'll use this magical target_gdbarch function that gets me an arch" when
the arch should in fact come from something in the context (a thread,
objfile, symbol, etc). I think that removing it and inlining
`current_inferior ()->arch ()` everywhere will make it a bit clearer
where that arch comes from and will trigger people into reflecting
whether this is the right place to get the arch or not.
Change-Id: I79f14b4e4934c88f91ca3a3155f5fc3ea2fadf6b
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
This commit extends the breakpoint mechanism to allow for inferior
specific breakpoints (but not watchpoints in this commit).
As GDB gains better support for multiple connections, and so for
running multiple (possibly unrelated) inferiors, then it is not hard
to imagine that a user might wish to create breakpoints that apply to
any thread in a single inferior. To achieve this currently, the user
would need to create a condition possibly making use of the $_inferior
convenience variable, which, though functional, isn't the most user
friendly.
This commit adds a new 'inferior' keyword that allows for the creation
of inferior specific breakpoints.
Inferior specific breakpoints are automatically deleted when the
associated inferior is removed from GDB, this is similar to how
thread-specific breakpoints are deleted when the associated thread is
deleted.
Watchpoints are already per-program-space, which in most cases mean
watchpoints are already inferior specific. There is a small window
where inferior-specific watchpoints might make sense, which is after a
vfork, when two processes are sharing the same address space.
However, I'm leaving that as an exercise for another day. For now,
attempting to use the inferior keyword with a watchpoint will give an
error, like this:
(gdb) watch a8 inferior 1
Cannot use 'inferior' keyword with watchpoints
A final note on the implementation: currently, inferior specific
breakpoints, like thread-specific breakpoints, are inserted into every
inferior, GDB then checks once the inferior stops if we are in the
correct thread or inferior, and resumes automatically if we stopped in
the wrong thread/inferior.
An obvious optimisation here is to only insert breakpoint locations
into the specific program space (which mostly means inferior) that
contains either the inferior or thread we are interested in. This
would reduce the number times GDB has to stop and then resume again in
a multi-inferior setup.
I have a series on the mailing list[1] that implements this
optimisation for thread-specific breakpoints. Once this series has
landed I'll update that series to also handle inferior specific
breakpoints in the same way. For now, inferior specific breakpoints
are just slightly less optimal, but this is no different to
thread-specific breakpoints in a multi-inferior debug session, so I
don't see this as a huge problem.
[1] https://inbox.sourceware.org/gdb-patches/cover.1685479504.git.aburgess@redhat.com/
|
|
Fixes the issue where jump failed if multiple inferiors run the same
source.
See the below example
$ gdb -q ./simple
Reading symbols from ./simple...
(gdb) break 2
Breakpoint 1 at 0x114e: file simple.c, line 2.
(gdb) run
Starting program: /temp/simple
Breakpoint 1, main () at simple.c:2
2 int a = 42;
(gdb) add-inferior
[New inferior 2]
Added inferior 2 on connection 1 (native)
(gdb) inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
(gdb) info inferiors
Num Description Connection Executable
1 process 6250 1 (native) /temp/simple
* 2 <null> 1 (native)
(gdb) file ./simple
Reading symbols from ./simple...
(gdb) run
Starting program: /temp/simple
Thread 2.1 "simple" hit Breakpoint 1, main () at simple.c:2
2 int a = 42;
(gdb) info inferiors
Num Description Connection Executable
1 process 6250 1 (native) /temp/simple
* 2 process 6705 1 (native) /temp/simple
(gdb) jump 3
Unreasonable jump request
(gdb)
In this example, jump fails because the debugger finds two different
locations, one for each inferior.
Solution is to limit the search to the current program space.
This is done by having the jump_command function use
decode_line_with_current_source rather than
decode_line_with_last_displayed, which makes sense,
the *_current_source function always looks up a location based on the
current thread's location -- if a user is asking the current thread to
jump, then surely their destination should be relative to where the
current thread is located.
Then, inside decode_line_with_current_source, the call to
decode_line_1 is updated to pass through the current program_space,
which will limit the returned locations to those in the current
program space.
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
If a header file defining a static function is included in multiple source
files, each calling the function, and GDB is asked to jump to a line inside
that function, there would be multiple locations matching the target. The
solution in this commit is to select the location in the current symtab.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
When stopped inside an inline function, trying to jump to a different line
of the same function currently results in a warning about jumping to another
function. Fix this by taking inline functions into account.
Before:
Breakpoint 1, function_inline (x=510) at jump-inline.cpp:22
22 a = a + x; /* inline-funct */
(gdb) j 21
Line 21 is not in `function_inline(int)'. Jump anyway? (y or n)
After:
Breakpoint 2, function_inline (x=510) at jump-inline.cpp:22
22 a = a + x; /* inline-funct */
(gdb) j 21
Continuing at 0x400679.
Breakpoint 1, function_inline (x=510) at jump-inline.cpp:21
21 a += 1020 + a; /* increment-funct */
This was regression-tested on X86-64 Linux.
Co-Authored-by: Cristian Sandu <cristian.sandu@intel.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
The show_args_command uses gdb_printf without specifying the ui_file.
This means that it prints to gdb_stdout instead of the stream given as
an argument to the function.
This commit fixes this.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
I'd like to move some things so they become methods on struct ui. But
first, I think that struct ui and the related things are big enough to
deserve their own file, instead of being scattered through top.{c,h} and
event-top.c.
Change-Id: I15594269ace61fd76ef80a7b58f51ff3ab6979bc
|
|
This patch turns set_inferior_args_vector into an overload of
inferior::set_args.
Regression tested on x86-64 Fedora 36.
|
|
Like the previous two commits, this commit fixes set/show inferior-tty
to work with $_gdb_setting_str.
Instead of using a scratch variable which is then pushed into the
current inferior from a set callback, move to the API that allows for
getters and setters, and store the value directly within the current
inferior.
Update an existing test to check the inferior-tty setting.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
The previous commit fixed set/show args when used with
$_gdb_setting_str, this commit fixes set/show cwd.
Instead of using a scratch variable which is then pushed into the
current inferior from a set callback, move to the API that allows for
getters and setters, and store the value directly within the current
inferior.
Update the existing test to check the cwd setting.
|
|
I noticed that $_gdb_setting_str was not working with 'args', e.g.:
$ gdb -q --args /tmp/hello.x arg1 arg2 arg3
Reading symbols from /tmp/hello.x...
(gdb) show args
Argument list to give program being debugged when it is started is "arg1 arg2 arg3".
(gdb) print $_gdb_setting_str("args")
$1 = ""
This is because the 'args' setting is implemented using a scratch
variable ('inferior_args_scratch') which is updated when the user does
'set args ...'. There is then a function 'set_args_command' which is
responsible for copying the scratch area into the current inferior.
However, when the user sets the arguments via the command line the
scratch variable is not updated, instead the arguments are pushed
straight into the current inferior.
There is a second problem, when the current inferior changes the
scratch area is not updated, which means that the value returned will
only ever reflect the last call to 'set args ...' regardless of which
inferior is currently selected.
Luckily, the fix is pretty easy, set/show variables have an
alternative API which requires we provide some getter and setter
functions. With this done the scratch variable can be removed and the
value returned will now always reflect the current inferior.
While working on set/show args I also rewrote show_args_command to
remove the use of deprecated_show_value_hack.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
In infcmd.c, in order to add command completion to some of the 'set'
commands, we are currently creating the command, then looking up the
command by calling lookup_cmd.
This is no longer necessary, we already return the relevant
cmd_list_element object when the set/show command is created, and we
can use that to set the command completion callback.
I don't know if there's actually any tests for completion of these
commands, but I manually checked, and each command still appears to
offer the expected filename completion.
There should be no user visible changes after this commit.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
Make find_thread_ptid (the overload that takes a process_stratum_target)
a method of process_stratum_target.
Change-Id: Ib190a925a83c6b93e9c585dc7c6ab65efbdd8629
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
The ERROR_NO_INFERIOR macro is already called at the beginning of the
function continue_command. Since target/inferior are not switched in-between,
the second call to it is redundant.
Co-Authored-By: Christina Schimpe <christina.schimpe@intel.com>
|
|
The recent commit:
commit 2a8339b71f37f2d02f5b2194929c9d702ef27223
Author: Carl Love <cel@us.ibm.com>
Date: Thu Mar 9 16:10:18 2023 -0500
PowerPC: fix for gdb.reverse/finish-precsave.exp and gdb.reverse/finish-reverse.exp
PPC64 multiple entry points, a normal entry point and an alternate entry
point. The alternate entry point is to setup the Table of Contents (TOC)
register before continuing at the normal entry point. When the TOC is
already valid, the normal entry point is used, this is typically the case.
The alternate entry point is typically referred to as the global entry
point (GEP) in IBM. The normal entry point is typically referred to as
the local entry point (LEP).
.....
Is causing regression failures on on PowerPC platforms. The regression
failures are in tests:
gdb.reverse/finish-precsave.exp
gdb.btrace/tailcall.exp
gdb.mi/mi-reverse.exp
gdb.btrace/step.exp
gdb.reverse/until-precsave.exp
gdb.reverse/finish-reverse.exp
gdb.btrace/tailcall-only.exp
The issue is in gdb/infcmd.c, function finish_command. The value of the
two new variables ALT_ENTRY_POINT and ENTRY_POINT are being initializezed
to SAL.PC. However, SAL has just been declared. The value of SAL.PC is
zero at this point. The intialization of ALT_ENTRY_POINT and ENTRY_POINT
needs to be after the initialization of SAL.
This patch moves the initialization of ALT_ENTRY_POINT and ENTRY_POINT
variables to fix the regression failures.
The patch has been tested on Power10 and on X86.
|
|
gdb.reverse/finish-reverse.exp
PPC64 multiple entry points, a normal entry point and an alternate entry
point. The alternate entry point is to setup the Table of Contents (TOC)
register before continuing at the normal entry point. When the TOC is
already valid, the normal entry point is used, this is typically the case.
The alternate entry point is typically referred to as the global entry
point (GEP) in IBM. The normal entry point is typically referred to as
the local entry point (LEP).
When GDB is executing the finish command in reverse, the function
finish_backward currently sets the break point at the alternate entry point.
This issue is if the function, when executing in the forward direction,
entered the function via the normal entry point, execution in the reverse
direction will never sees the break point at the alternate entry point. In
this case, the reverse execution continues until the next break point is
encountered thus stopping at the wrong place.
This patch adds a new address to struct execution_control_state to hold the
address of the alternate entry point (GEP). The finish_backwards function
is updated, if the stopping point is between the normal entry point (LEP)
and the end of the function, a breakpoint is set at the normal entry point.
If the stopping point is between the entry points, a breakpoint is set at
the alternate entry point. This ensures that GDB will always stop at the
normal entry point. If the function did enter via the alternate entry
point, GDB will detect that and continue to execute backwards in the
function until the alternate entry point is reached.
The patch fixes the behavior of the reverse-finish command on PowerPC to
match the behavior of the command on other platforms, specifically X86.
The patch does not change the behavior of the command on X86.
A new test is added to verify the reverse-finish command on PowerPC
correctly stops at the instruction where the function call is made.
The patch fixes 11 regression errors in test gdb.reverse/finish-precsave.exp
and 11 regression errors in test gdb.reverse/finish-reverse.exp.
The patch has been tested on Power 10 and X86 processor with no new
regression failures.
|
|
As described in the previous commit for this series, I became
concerned that there might be instances in which a QUIT (due to either
a SIGINT or SIGTERM) might not cause execution to return to the top
level. In some (though very few) instances, it is okay to not
propagate the exception for a Ctrl-C / SIGINT, but I don't think that
it is ever okay to swallow the exception caused by a SIGTERM.
Allowing that to happen would definitely be a deviation from the
current behavior in which GDB exits upon receipt of a SIGTERM.
I looked at all cases where an exception handler catches a
gdb_exception. Handlers which did NOT need modification were those
which satisifed one or more of the following conditions:
1) There is no call path to maybe_quit() in the try block. I used a
static analysis tool to help make this determination. In
instances where the tool didn't provide an answer of "yes, this
call path can result in maybe_quit() being called", I reviewed it
by hand.
2) The catch block contains a throw for conditions that it
doesn't want to handle; these "not handled" conditions
must include the quit exception and the new "forced quit" exception.
3) There was (also) a catch for gdb_exception_quit.
Any try/catch blocks not meeting the above conditions could
potentially swallow a QUIT exception.
My first thought was to add catch blocks for gdb_exception_quit and
then rethrow the exception. But Pedro pointed out that this can be
handled without adding additional code by simply catching
gdb_exception_error instead. That's what this patch series does.
There are some oddball cases which needed to be handled differently,
plus the extension languages, but those are handled in later patches.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
Tested-by: Tom de Vries <tdevries@suse.de>
Approved-by: Pedro Alves <pedro@palves.net>
|
|
With gdb.base/catch-follow-exec.exp, we currently see:
~~~~~~~~~~~~~~~
(gdb)
continue
Continuing.
process 693251 is executing new program: /usr/bin/ls
[New inferior 2]
[New process 693251]
[Switching to process 693251]
Thread 2.1 "ls" hit Catchpoint 2 (exec'd /usr/bin/ls), 0x00007ffff7fd0100 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb)
info prog
No selected thread.
~~~~~~~~~~~~~~~
Note the "No selected thread" output. That is totally bogus, because
there _is_ a selected thread. What GDB really means, is that it can't
find the thread that had the latest (user-visible) stop. And that
happens because "info program" gets that info from
get_last_target_status, and the last target status has been cleared.
However, GDB also checks if there is a selected thread, here:
if (ptid == null_ptid || ptid == minus_one_ptid)
error (_("No selected thread."));
.. the null_ptid part. That is also bogus, because what matters is
the thread that last reported a stop, not the current thread:
- in all-stop mode, "info program" displays info about the last stop.
That may have happened on a thread different from the selected
thread.
- in non-stop mode, because all threads are controlled individually,
"info program" shows info about the last stop of the selected
thread.
The current code already behaves this way, though in a poor way. This
patch reimplements it, such that the all-stop version now finds the
thread that last reported an event via the 'previous_thread' strong
reference. Being a strong reference means that if that thread has
exited since the event was reported, 'previous_thread' will still
point to it, so we can say that the thread exited meanwhile.
The patch also extends "info program" output a little, to let the user
know which thread we are printing info for. For example, for the
gdb.base/catch-follow-exec.exp case we shown above, we now get:
(gdb) info prog
Last stopped for thread 2.1 (process 710867).
Using the running image of child process 710867.
Program stopped at 0x7ffff7fd0100.
It stopped at breakpoint 2.
Type "info stack" or "info registers" for more information.
(gdb)
while in non-stop mode, we get:
(gdb) info prog
Selected thread 2.1 (process 710867).
Using the running image of child process 710867.
Program stopped at 0x7ffff7fd0100.
It stopped at breakpoint 2.
Type "info stack" or "info registers" for more information.
(gdb)
In both cases, the first line of output is new.
The existing code considered these running/exited cases as an error,
but I think that that's incorrect, since this is IMO just plain
execution info as well. So the patch makes those cases regular
prints, not errors.
If the thread is running, we get, in non-stop mode:
(gdb) info prog
Selected thread 2.1 (process 710867).
Selected thread is running.
... and in all-stop:
(gdb) info prog
Last stopped for thread 2.1 (process 710867).
Thread is now running.
If the thread has exited, we get, in non-stop mode:
(gdb) info prog
Selected thread 2.1 (process 710867).
Selected thread has exited.
... and in all-stop:
(gdb) info prog
Last stopped for thread 2.1 (process 710867).
Thread has since exited.
The gdb.base/info-program.exp testcase was much extended to test
all-stop/non-stop and single-threaded/multi-threaded.
Change-Id: I51d9d445f772d872af3eead3449ad4aa445781b1
|
|
I originally wrote this patch, because while working on some other
patch, I spotted a regression in the
gdb.multi/multi-target-no-resumed.exp.exp testcase. Debugging the
issue, I realized that the problem was related to how I was using
previous_inferior_ptid to look up the thread the user had last
selected. The problem is that previous_inferior_ptid alone doesn't
tell you which target that ptid is from, and I was just always using
the current target, which was incorrect. Two different targets may
have threads with the same ptid.
I decided to fix this by replacing previous_inferior_ptid with a
strong reference to the thread, called previous_thread.
I have since found a new motivation for this change -- I would like to
tweak "info program" to not rely on get_last_target_status returning a
ptid that still exists in the thread list. With both the follow_fork
changes later in this series, and the step-over-thread-exit changes,
that can happen, as we'll delete threads and not clear the last
waitstatus.
A new update_previous_thread function is added that can be used to
update previous_thread from inferior_ptid. This must be called in
several places that really want to get rid of previous_thread thread,
and reset the thread id counter, otherwise we get regressions like
these:
(gdb) info threads -gid
Id GId Target Id Frame
- * 1 1 Thread 2974541.2974541 "tids-gid-reset" main () at src/gdb/testsuite/gdb.multi/tids-gid-reset.c:21
- (gdb) PASS: gdb.multi/tids-gid-reset.exp: single-inferior: after restart: info threads -gid
+ * 1 2 Thread 2958361.2958361 "tids-gid-reset" main () at src/gdb/testsuite/gdb.multi/tids-gid-reset.c:21
+ (gdb) FAIL: gdb.multi/tids-gid-reset.exp: single-inferior: after restart: info threads -gid
and:
Core was generated by `build/gdb/testsuite/outputs/gdb.reverse/sigall-precsave/si'.
Program terminated with signal SIGTRAP, Trace/breakpoint trap.
#0 gen_ABRT () at src/gdb/testsuite/gdb.reverse/sigall-reverse.c:398
398 kill (getpid (), SIGABRT);
+[Current thread is 1 (LWP 2662066)]
Restored records from core file build/gdb/testsuite/outputs/gdb.reverse/sigall-precsave/sigall.precsave.
#0 gen_ABRT () at src/gdb/testsuite/gdb.reverse/sigall-reverse.c:398
398 kill (getpid (), SIGABRT);
continue
Continuing.
-Program received signal SIGABRT, Aborted.
+Thread 1 received signal SIGABRT, Aborted.
0x00007ffff7dfd55b in kill () at ../sysdeps/unix/syscall-template.S:78
78 ../sysdeps/unix/syscall-template.S: No such file or directory.
-(gdb) PASS: gdb.reverse/sigall-precsave.exp: sig-test-1: get signal ABRT
+(gdb) FAIL: gdb.reverse/sigall-precsave.exp: sig-test-1: get signal ABRT
I.e., GDB was failing to restart the thread counter back to 1, because
the previous_thread thread was being help due to the strong reference.
Tested on GNU/Linux native, gdbserver and gdbserver + "maint set
target-non-stop on".
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
* infcmd.c (kill_command, detach_command, disconnect_command):
Call update_previous_thread.
* infrun.c (previous_inferior_ptid): Delete.
(previous_thread): New.
(update_previous_thread): New.
(proceed, init_wait_for_inferior): Call update_previous_thread.
(normal_stop): Adjust to compare previous_thread and
inferior_thread. Call update_previous_thread.
* infrun.h (update_previous_thread): Declare.
* target.c (target_pre_inferior, target_preopen): Call
update_previous_thread.
Change-Id: I42779a1ee51a996fa1e8f6e1525c6605dbfd42c7
|
|
record_latest_value now access some internals of struct value, so turn
it into a method.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
This turns many functions that are related to optimized-out or
availability-checking to be methods of value. The static function
value_entirely_covered_by_range_vector is also converted to be a
private method.
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_type to be a method of value. Much of this patch
was written by script.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Nearly every call to fixup_symbol_section in gdb is incorrect, and if
any such call has an effect, it's purely by happenstance.
fixup_section has a long comment explaining that the call should only
be made before runtime section offsets are applied. And, the loop in
this code (the fallback loop -- the minsym lookup code is "ok") is
careful to remove these offsets before comparing addresses.
However, aside from a single call in dwarf2/read.c, every call in gdb
is actually done after section offsets have been applied. So, these
calls are incorrect.
Now, these calls could be made when the symbol is created. I
considered this approach, but I reasoned that the code has been this
way for many years, seemingly without ill effect. So, instead I chose
to simply remove the offending calls.
|
|
This is the second step of making frame_info_ptr automatic, reinflate on
demand whenever trying to obtain the wrapper frame_info pointer, either
through the get method or operator->. Make the reinflate method
private, it is used as a convenience method in those two.
Add an "is_null" method, because it is often needed to know whether the
frame_info_ptr wraps an frame_info or is empty.
Make m_ptr mutable, so that it's possible to reinflate const
frame_info_ptr objects. Whether m_ptr is nullptr or not does not change
the logical state of the object, because we re-create it on demand. I
believe this is the right use case for mutable.
Change-Id: Icb0552d0035e227f81eb3c121d8a9bb2f9d25794
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
|
|
This is the first step of making frame_info_ptr automatic. Remove the
frame_info_ptr::prepare_reinflate method, move that code to the
constructor.
Change-Id: I85cdae3ab1c043c70e2702e7fb38e9a4a8a675d8
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
|
|
This reverts commit b22548ddb30bfb167708e82d3bb932461c1b703a.
This patch is being reverted since the patch series is causing regressions.
|
|
gdb.reverse/finish-reverse.exp"
This reverts commit 92e07580db6a5572573d5177ca23933064158f89.
Reverting patch as the patch series is causing regressions.
|
|
gdb.reverse/finish-reverse.exp
PR record/29927 - reverse-finish requires two reverse next instructions to
reach previous source line
PowerPC uses two entry points called the local entry point (LEP) and the
global entry point (GEP). Normally the LEP is used when calling a
function. However, if the table of contents (TOC) value in register 2 is
not valid the GEP is called to setup the TOC before execution continues at
the LEP. When executing in reverse, the function finish_backward sets the
break point at the alternate entry point (GEP). However if the forward
execution enters via the normal entry point (LEP), the reverse execution
never sees the break point at the GEP of the function. Reverse execution
continues until the next break point is encountered or the end of the
recorded log is reached causing gdb to stop at the wrong place.
This patch adds a new address to struct execution_control_state to hold the
address of the alternate function start address, known as the GEP on
PowerPC. The finish_backwards function is updated. If the stopping point
is between the two entry points (the LEP and GEP on PowerPC), the stepping
range is set to execute back to the alternate entry point (GEP on PowerPC).
Otherwise, a breakpoint is inserted at the normal entry point (LEP on
PowerPC).
Function process_event_stop_test checks uses a stepping range to stop
execution in the caller at the first instruction of the source code line.
Note, on systems that only support one entry point, the address of the two
entry points are the same.
Test finish-reverse-next.exp is updated to include tests for the
reverse-finish command when the function is entered via the normal entry
point (i.e. the LEP) and the alternate entry point (i.e. the GEP).
The patch has been tested on X86 and PowerPC with no regressions.
|
|
PR record/29927 - reverse-finish requires two reverse next instructions to
reach previous source line
Currently on X86, when executing the finish command in reverse, gdb does a
single step from the first instruction in the callee to get back to the
caller. GDB stops on the last instruction in the source code line where
the call was made. When stopped at the last instruction of the source code
line, a reverse next or step command will stop at the first instruction
of the same source code line thus requiring two step/next commands to
reach the previous source code line. It should only require one step/next
command to reach the previous source code line.
By contrast, a reverse next or step command from the first line in a
function stops at the first instruction in the source code line where the
call was made.
This patch fixes the reverse finish command so it will stop at the first
instruction of the source line where the function call was made. The
behavior on X86 for the reverse-finish command now matches doing a
reverse-next from the beginning of the function.
The proceed_to_finish flag in struct thread_control_state is no longer
used. This patch removes the declaration, initialization and setting of
the flag.
This patch requires a number of regression tests to be updated. Test
gdb.mi/mi-reverse.exp no longer needs to execute two steps to get to the
previous line. The gdb output for tests gdb.reverse/until-precsave.exp
and gdb.reverse/until-reverse.exp changed slightly. The expected result in
tests gdb.reverse/amd64-failcall-reverse.exp and
gdb.reverse/singlejmp-reverse.exp are updated to the correct expected
result.
This patch adds a new test gdb.reverse/finish-reverse-next.exp to test the
reverse-finish command when returning from the entry point and from the
body of the function.
The step_until proceedure in test gdb.reverse/step-indirect-call-thunk.exp
was moved to lib/gdb.exp and renamed cmd_until.
The patch has been tested on X86 and PowerPC to verify no additional
regression failures occured.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29927
|
|
Change the return type of normal_stop (infrun.c) from int to bool.
Update callers.
I've also converted the (void) to () in the function declaration and
definition, given I was changing those lines anyway.
There should be no user visible changes after this commit.
|
|
The gdbarch "return_value" can't correctly handle variably-sized
types. The problem here is that the TYPE_LENGTH of such a type is 0,
until the type is resolved, which requires reading memory. However,
gdbarch_return_value only accepts a buffer as an out parameter.
Fixing this requires letting the implementation of the gdbarch method
resolve the type and return a value -- that is, both the contents and
the new type.
After an attempt at this, I realized I wouldn't be able to correctly
update all implementations (there are ~80) of this method. So,
instead, this patch adds a new method that falls back to the current
method, and it updates gdb to only call the new method. This way it's
possible to incrementally convert the architectures that I am able to
test.
|
|
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 the uses of value_print_options to use 'true' and 'false'
rather than integers.
|
|
Some class members were changed to bool, but there was
still some assignments or comparisons using 0/1.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
The GDB coding standard specifies that nullptr should be used instead of
NULL. There are numerous uses of NULL and nullptr in files infcmd.c and
infrun.c. This patch replaces the various uses of NULL with nullptr in
the source files. The use of NULL in the comments was not changed.
The patch does not introduce any functional changes.
The patch has been tested on PowerPC and Intel X86_64 with no new unexpected
test failures, unresolved tests, new core files etc.
|
|
The recent commit:
commit a0eda3df5b750ae32576a9be092b361281a41787
Author: Carl Love <cel@us.ibm.com>
Date: Mon Nov 14 16:22:37 2022 -0500
PowerPC, fix support for printing the function return value for non-trivial values.
Is generating a segmentation fault on x86_64-linux.
segfault:
...
PASS: gdb.asm/asm-source.exp: info source asmsrc1.s
ERROR: GDB process no longer exists
UNRESOLVED: gdb.asm/asm-source.exp: finish from foo3
...
Reproduced on command line:
...
$ gdb -q -batch -x outputs/gdb.asm/asm-source/gdb.in.1
...
The problem seems to be that:
...
Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
0x000000000043de7a in symbol::type (this=0x0) at
.../gdb_versions/devel/src/gdb/symtab.h:1287
1287 return m_type;
...
because:
...
(gdb) up
#1 0x0000000000852d94 in finish_command (arg=0x0, from_tty=0)
at .../gdb_versions/devel/src/gdb/infcmd.c:1887
1887 = check_typedef (sm->function->type ()->target_type ());
(gdb) p sm->function
$1 = (symbol *) 0x0
The code is not checking if sm->function is NULL. If sm->function is NULL
the check for the return buffer should be skipped.
|
|
values.
Currently, a non-trivial return value from a function cannot currently be
reliably determined on PowerPC. This is due to the fact that the PowerPC
ABI uses register r3 to store the address of the buffer containing the
non-trivial return value when the function is called. The PowerPC ABI
does not guarantee the value in register r3 is not modified in the
function. Thus the value in r3 cannot be reliably used to obtain the
return addreses on exit from the function.
This patch adds a new gdbarch method to allow PowerPC to access the value
of r3 on entry to a function. On PowerPC, the new gdbarch method attempts
to use the DW_OP_entry_value for the DWARF entries, when exiting the
function, to determine the value of r3 on entry to the function. This
requires the use of the -fvar-tracking compiler option to compile the
user application thus generating the DW_OP_entry_value in the binary. The
DW_OP_entry_value entries in the binary file allows GDB to resolve the
DW_TAG_call_site entries. This new gdbarch method is used to get the
return buffer address, in the case of a function returning a nontrivial
data type, on exit from the function. The GDB function should_stop checks
to see if RETURN_BUF is non-zero. By default, RETURN_BUF will be set to
zero by the new gdbarch method call for all architectures except PowerPC.
The get_return_value function will be used to obtain the return value on
all other architectures as is currently being done if RETURN_BUF is zero.
On PowerPC, the new gdbarch method will return a nonzero address in
RETURN_BUF if the value can be determined. The value_at function uses the
return buffer address to get the return value.
This patch fixes five testcase failures in gdb.cp/non-trivial-retval.exp.
The correct function return values are now reported.
Note this patch is dependent on patch: "PowerPC, function
ppc64_sysv_abi_return_value add missing return value convention".
This patch has been tested on Power 10 and x86-64 with no regressions.
|
|
Commit 0be837be9fb4 ("gdb: make "start" breakpoint inferior-specific")
regresses gdb.ada/start.exp:
(gdb) start
Error in expression, near `1'.
(gdb) UNTESTED: gdb.ada/start.exp: start failed to land inside the right procedure
This is because in Ada, the equality operator is =, not ==.
I checked the other languages supported by GDB, these other languages
use = for equality:
- Pascal: tests like gdb.pascal/hello.exp are affected too
- Modula-2: I tried building a Modula-2 hello world using gm2, but it
seems like the generated DWARF doesn't specify the Modula-2 language
in the CUs, it's C++ and C, so the selected language isn't
"modula-2". But if I manually do "set language modula-2" on a dummy
program and then "start", I get the same error.
Other languages all use ==.
So, a short term fix would be to use = or == in the expression, based on
the current language. If this was meant to be permanent, I would
suggest adding something like an "equality_operator" method to
language_defn, that returns the right equality operator for the
language. But the goal is to replace all this with proper
inferior-specific breakpoints, so I hope all this is temporary.
Approved-By: Tom de Vries <tdevries@suse.de>
Change-Id: Id4d38e14a80e6bbbb1ad2b2277f974dd55192969
|
|
I saw this failure on a CI:
(gdb) add-inferior
[New inferior 2]
Added inferior 2
(gdb) PASS: gdb.threads/vfork-multi-inferior.exp: method=non-stop: add-inferior
inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
(gdb) PASS: gdb.threads/vfork-multi-inferior.exp: method=non-stop: inferior 2
kill
The program is not being run.
(gdb) file /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior-sleep
Reading symbols from /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior-sleep...
(gdb) run &
Starting program: /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior-sleep
(gdb) PASS: gdb.threads/vfork-multi-inferior.exp: method=non-stop: run inferior 2
inferior 1
[Switching to inferior 1 [<null>] (<noexec>)]
(gdb) PASS: gdb.threads/vfork-multi-inferior.exp: method=non-stop: inferior 1
kill
The program is not being run.
(gdb) file /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior
Reading symbols from /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior...
(gdb) break should_break_here
Breakpoint 1 at 0x11b1: file /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/src/binutils-gdb/gdb/testsuite/gdb.threads/vfork-multi-inferior.c, line 25.
(gdb) PASS: gdb.threads/vfork-multi-inferior.exp: method=non-stop: break should_break_here
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
start
Temporary breakpoint 2 at 0x11c0: -qualified main. (2 locations)
Starting program: /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/tmp/tmp.GYATAXR8Ku/gdb/testsuite/outputs/gdb.threads/vfork-multi-inferior/vfork-multi-inferior
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Thread 2.1 "vfork-multi-inf" hit Temporary breakpoint 2, main () at /home/jenkins/workspace/binutils-gdb_master_linuxbuild/platform/jammy-amd64/target_board/unix/src/binutils-gdb/gdb/testsuite/gdb.threads/vfork-multi-inferior-sleep.c:23
23 sleep (30);
(gdb) FAIL: gdb.threads/vfork-multi-inferior.exp: method=non-stop: start inferior 1
What happens is:
1. We start inferior 2 with "run&", it runs very slowly, takes time to
get to main
2. We switch to inferior 1, and run "start"
3. The temporary breakpoint inserted by "start" applies to all inferiors
4. Inferior 2 hits that breakpoint and GDB reports that hit
To avoid this, breakpoints inserted by "start" should be
inferior-specific. However, we don't have a nice way to make
inferior-specific breakpoints yet. It's possible to make
pspace-specific breakpoints (for example how the internal_breakpoint
constructor does) by creating a symtab_and_line manually. However,
inferiors can share program spaces (usually on particular embedded
targets), so we could have a situation where two inferiors run the same
code in the same program space. In that case, it would just not be
possible to insert a breakpoint in one inferior but not the other.
A simple solution that should work all the time is to add a condition to
the breakpoint inserted by "start", to check the inferior reporting the
hit is the expected one. This is what this patch implements.
Add a test that does:
- start in background inferior 1 that sleeps before reaching its main
function (using a sleep in a global C++ object's constructor)
- start inferior 2 with the "start" command, which also sleeps before
reaching its main function
- validate that we hit the breakpoint in inferior 2
Without the fix, we hit the breakpoint in inferior 1 pretty much all the
time. There could be some unfortunate scheduling causing the test not
to catch the bug, for instance if the scheduler decides not to schedule
inferior 1 for a long time, but it would be really rare. If the bug is
re-introduced, the test will catch it much more often than not, so it
will be noticed.
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
Approved-By: Pedro Alves <pedro@palves.net>
Change-Id: Ib0148498a476bfa634ed62353c95f163623c686a
|
|
Currently, every internal_error call must be passed __FILE__/__LINE__
explicitly, like:
internal_error (__FILE__, __LINE__, "foo %d", var);
The need to pass in explicit __FILE__/__LINE__ is there probably
because the function predates widespread and portable variadic macros
availability. We can use variadic macros nowadays, and in fact, we
already use them in several places, including the related
gdb_assert_not_reached.
So this patch renames the internal_error function to something else,
and then reimplements internal_error as a variadic macro that expands
__FILE__/__LINE__ itself.
The result is that we now should call internal_error like so:
internal_error ("foo %d", var);
Likewise for internal_warning.
The patch adjusts all calls sites. 99% of the adjustments were done
with a perl/sed script.
The non-mechanical changes are in gdbsupport/errors.h,
gdbsupport/gdb_assert.h, and gdb/gdbarch.py.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
|
|
Currently, despite having a smart pointer for frame_infos, GDB may
attempt to use an invalidated frame_info_ptr, which would cause internal
errors to happen. One such example has been documented as PR
python/28856, that happened when printing frame arguments calls an
inferior function.
To avoid failures, the smart wrapper was changed to also cache the frame
id, so the pointer can be reinflated later. For this to work, the
frame-id stuff had to be moved to their own .h file, which is included
by frame-info.h.
Frame_id caching is done explicitly using the prepare_reinflate method.
Caching is done manually so that only the pointers that need to be saved
will be, and reinflating has to be done manually using the reinflate
method because the get method and the -> operator must not change
the internals of the class. Finally, attempting to reinflate when the
pointer is being invalidated causes the following assertion errors:
check_ptrace_stopped_lwp_gone: assertion `lp->stopped` failed.
get_frame_pc: Assertion `frame->next != NULL` failed.
As for performance concerns, my personal testing with `time make
chec-perf GDB_PERFTEST_MODE=run` showed an actual reduction of around
10% of time running.
This commit also adds a testcase that exercises the python/28856 bug with
7 different triggers, run, continue, step, backtrace, finish, up and down.
Some of them can seem to be testing the same thing twice, but since this
test relies on stale pointers, there is always a chance that GDB got lucky
when testing, so better to test extra.
Regression tested on x86_64, using both gcc and clang.
Approved-by: Tom Tomey <tom@tromey.com>
|
|
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>
|
|
After the previous few commit, gdbarch_register_name no longer returns
nullptr. This commit audits all the calls to gdbarch_register_name
and removes any code that checks the result against nullptr.
There should be no visible change after this commit.
|
|
Remove the macro, replace all uses with calls to type::length.
Change-Id: Ib9bdc954576860b21190886534c99103d6a47afb
|
|
Remove the macro, replace all uses by calls to type::target_type.
Change-Id: Ie51d3e1e22f94130176d6abd723255282bb6d1ed
|
|
This changes the parameter of target_ops::async from int to bool.
Regression tested on x86-64 Fedora 34.
|
|
'finish_print' does not really belong in value_print_options -- this
is consulted only when deciding whether or not to print a value, and
never during the course of printing. This patch removes it from the
structure and makes it a static global in infcmd.c instead.
Tested on x86-64 Fedora 34.
|