Age | Commit message (Collapse) | Author | Files | Lines |
|
This adds a testcase that exercises detaching while GDB is stepping
over a breakpoint, in all combinations of:
- maint target non-stop off/on
- set non-stop on/off
- displaced stepping on/off
This exercises the bugs fixed in the previous 8 patches.
gdb/testsuite/ChangeLog:
* gdb.threads/detach-step-over.c: New file.
* gdb.threads/detach-step-over.exp: New file.
|
|
A following patch will add a testcase that has a number of threads
constantly stepping over a breakpoint, and then has GDB detach the
process, while threads are running. If we have more then one inferior
running, and we detach from just one of the inferiors, we expect that
the remaining inferior continues running. However, in all-stop, if
GDB needs to pause the target for the detach, nothing is re-resuming
the other inferiors after the detach. "info threads" shows the
threads as running, but they really aren't. This fixes it.
gdb/ChangeLog:
* infcmd.c (detach_command): Hold strong reference to target, and
if all-stop on entry, restart threads on exit.
* infrun.c (switch_back_to_stepped_thread): Factor out bits to ...
(restart_stepped_thread): ... this new function. Also handle
trap_expected.
(restart_after_all_stop_detach): New function.
* infrun.h (restart_after_all_stop_detach): Declare.
|
|
A following patch will add a testcase that has a number of threads
constantly stepping over a breakpoint, and then has GDB detach the
process. That testcase exercises both "set displaced-stepping
on/off". Testing with "set displaced-stepping off" reveals that GDB
does not handle the case of the user typing "detach" just while some
thread is in the middle of an in-line step over. If that thread
belongs to the inferior that is being detached, then the step-over
never finishes, and threads of other inferiors are never re-resumed.
This fixes it.
gdb/ChangeLog:
* infrun.c (struct step_over_info): Initialize fields.
(prepare_for_detach): Handle ongoing in-line step over.
|
|
A following patch will add a testcase that has a number of threads
constantly stepping over a breakpoint, and then has GDB detach the
process. That testcase sometimes fails with the inferior crashing
with SIGTRAP after the detach because of the bug fixed by this patch,
when tested with the native target.
The problem is that target_detach removes breakpoints from the target
immediately, and that does not work with the native GNU/Linux target
(and probably no other native target) currently. The test wouldn't
fail with this issue when testing against gdbserver, because gdbserver
does allow accessing memory while the current thread is running, by
transparently pausing all threads temporarily, without GDB noticing.
Implementing that in gdbserver was a lot of work, so I'm not looking
forward right now to do the same in the native target. Instead, I
came up with a simpler solution -- push the breakpoints removal down
to the targets. The Linux target conveniently already pauses all
threads before detaching them, since PTRACE_DETACH only works with
stopped threads, so we move removing breakpoints to after that. Only
the remote and GNU/Linux targets support support async execution, so
no other target should really need this.
gdb/ChangeLog:
* linux-nat.c (linux_nat_target::detach): Remove breakpoints
here...
* remote.c (remote_target::remote_detach_1): ... and here ...
* target.c (target_detach): ... instead of here.
|
|
I noticed that "detach" while a program was running sometimes resulted
in the process crashing. I tracked it down to this change to
prepare_for_detach in commit 187b041e ("gdb: move displaced stepping
logic to gdbarch, allow starting concurrent displaced steps"):
/* Is any thread of this process displaced stepping? If not,
there's nothing else to do. */
- if (displaced->step_thread == nullptr)
+ if (displaced_step_in_progress (inf))
return;
The problem above is that the condition was inadvertently flipped. It
should have been:
if (!displaced_step_in_progress (inf))
So I fixed it, and wrote a testcase to exercise it. The testcase has
a number of threads constantly stepping over a breakpoint, and then
GDB detaches the process, while threads are running and stepping over
the breakpoint. And then I was surprised that my testcase would hang
-- GDB would get stuck in an infinite loop in prepare_for_detach,
here:
while (displaced_step_in_progress (inf))
{
...
What is going on is that since we now have two displaced stepping
buffers, as one displaced step finishes, GDB starts another, and
there's another one already in progress, and on and on, so the
displaced_step_in_progress condition never turns false. This happens
because we go via the whole handle_inferior_event, which tries to
start new step overs when one finishes. And also because while we
remove breakpoints from the target before prepare_for_detach is
called, handle_inferior_event ends up calling insert_breakpoints via
e.g. keep_going.
Thinking through all this, I came to the conclusion that going through
the whole handle_inferior_event isn't ideal. A _lot_ is done by that
function, e.g., some thread may get a signal which is passed to the
inferior, and gdb decides to try to get over the signal handler, which
reinstalls breakpoints. Or some process may exit. We can end up
reporting these events via normal_stop while detaching, maybe end up
running some breakpoint commands, or maybe even something runs an
inferior function call. Etc. All this after the user has already
declared they don't want to debug the process anymore, by asking to
detach.
I came to the conclusion that it's better to do the minimal amount of
work possible, in a more controlled fashion, without going through
handle_inferior_event. So in the new approach implemented by this
patch, if there are threads of the inferior that we're detaching in
the middle of a displaced step, stop them, and cancel the displaced
step. This is basically what stop_all_threads already does, via
wait_one and (the now factored out) handle_one, so I'm reusing those.
gdb/ChangeLog:
* infrun.c (struct wait_one_event): Move higher up.
(prepare_for_detach): Abort in-progress displaced steps instead of
letting them complete.
(handle_one): If the inferior is detaching, don't add the thread
back to the global step-over chain.
(restart_threads): Don't restart threads if detaching.
(handle_signal_stop): Remove inferior::detaching reference.
|
|
After detaching from a process, the inf->detaching flag is
inadvertently left set to true. If you afterwards reuse the same
inferior to start a new process, GDB will mishave...
The problem is that prepare_for_detach discards the scoped_restore at
the end, while the intention is for the flag to be set only for the
duration of prepare_for_detach.
This was already a bug in the original commit that added
prepare_for_detach, commit 24291992dac3 ("PR gdb/11321"), by yours
truly. Back then, we still used cleanups, and the function called
discard_cleanups instead of do_cleanups, by mistake.
gdb/ChangeLog:
* infrun.c (prepare_for_detach): Don't release scoped_restore at
the end.
|
|
This moves the code handling an event out of wait_one to a separate
function, to be used in another context in a following patch.
gdb/ChangeLog:
* infrun.c (handle_one): New function, factored out from ...
(stop_all_threads): ... here.
|
|
A following patch will add a testcase that has two processes with
threads stepping over a breakpoint continuously, and then detaches
from one of the processes while threads are running. The other
process continues stepping over its breakpoint. And then the testcase
sends a SIGUSR1, expecting that GDB reports it. That would sometimes
hang against gdbserver, due to the bugs fixed here. Both bugs are
related, in that they're about remote protocol asynchronous Stop
notifications. There's a bug in GDB, and another in GDBserver.
The GDB bug:
- when we detach from a process, the remote target discards any
pending RSP notification related to that process, including the
in-flight, yet-unacked notification. Discarding the in-flight
notification is the problem. Until the in-flight notification is
acked with a vStopped packet, the server won't send another %Stop
notification. As a result, the debug session gets messed up. In
the new testcase's case, GDB would hang inside stop_all_threads,
waiting for a stop for one of the process'es threads, which never
arrived -- its stop reply was permanently stuck in the stop reply
queue, waiting for a vStopped packet that never arrived.
The GDBserver bug:
GDBserver has the opposite bug. It also discards notifications for
the process being detached. If that discards the head of the
notification queue, when gdb sends an ack, it ends up acking the
_next_ notification. Meaning, gdb loses one notification. In the
testcase, this results in a similar hang in stop_all_threads.
So we have two very similar bugs in GDB and GDBserver, both resulting
in a similar symptom. That's why I'm fixing them both at the same
time.
gdb/ChangeLog:
* remote.c (remote_notif_stop_ack): Don't error out on
TARGET_WAITKIND_IGNORE; instead, just ignore the notification.
(remote_target::discard_pending_stop_replies): Don't delete
in-flight notification; instead, clear its contents.
gdbserver/ChangeLog:
* server.cc (discard_queued_stop_replies): Don't ever discard the
notification at the head of the list.
|
|
This adds a testcase exercising attaching to a multi-threaded process,
in all combinations of:
- set non-stop on/off
- maint target non-stop off/on
- "attach" vs "attach &"
This exercises the bugs fixed in the two previous patches.
gdb/testsuite/ChangeLog:
* gdb.threads/attach-non-stop.c: New file.
* gdb.threads/attach-non-stop.exp: New file.
|
|
With "target extended-remote" + "maint set target-non-stop", attaching
hangs like so:
(gdb) attach 1244450
Attaching to process 1244450
[New Thread 1244450.1244450]
[New Thread 1244450.1244453]
[New Thread 1244450.1244454]
[New Thread 1244450.1244455]
[New Thread 1244450.1244456]
[New Thread 1244450.1244457]
[New Thread 1244450.1244458]
[New Thread 1244450.1244459]
[New Thread 1244450.1244461]
[New Thread 1244450.1244462]
[New Thread 1244450.1244463]
* hang *
Attaching to the hung GDB shows that GDB is busy in an infinite loop
in stop_all_threads:
(top-gdb) bt
#0 stop_all_threads () at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:4755
#1 0x000055555597b424 in stop_waiting (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:7738
#2 0x0000555555976fba in handle_signal_stop (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:5868
#3 0x0000555555975f6a in handle_inferior_event (ecs=0x7fffffffd930) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:5527
#4 0x0000555555971da4 in fetch_inferior_event () at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:3910
#5 0x00005555559540b2 in inferior_event_handler (event_type=INF_REG_EVENT) at /home/pedro/gdb/binutils-gdb/src/gdb/inf-loop.c:42
#6 0x000055555597e825 in infrun_async_inferior_event_handler (data=0x0) at /home/pedro/gdb/binutils-gdb/src/gdb/infrun.c:9162
#7 0x0000555555687d1d in check_async_event_handlers () at /home/pedro/gdb/binutils-gdb/src/gdb/async-event.c:328
#8 0x0000555555e48284 in gdb_do_one_event () at /home/pedro/gdb/binutils-gdb/src/gdbsupport/event-loop.cc:216
#9 0x00005555559e7512 in start_event_loop () at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:347
#10 0x00005555559e765d in captured_command_loop () at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:407
#11 0x00005555559e8f80 in captured_main (data=0x7fffffffdb70) at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:1239
#12 0x00005555559e8ff2 in gdb_main (args=0x7fffffffdb70) at /home/pedro/gdb/binutils-gdb/src/gdb/main.c:1254
#13 0x0000555555627c86 in main (argc=12, argv=0x7fffffffdc88) at /home/pedro/gdb/binutils-gdb/src/gdb/gdb.c:32
The problem is that the remote sends stops for all the threads:
Packet received: l/home/pedro/gdb/binutils-gdb/build/gdb/testsuite/outputs/gdb.threads/attach-non-stop/attach-non-stop
Sending packet: $vStopped#55...Packet received: T0006:f06e25edec7f0000;07:f06e25edec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd2f;core:15;
Sending packet: $vStopped#55...Packet received: T0006:f0dea5f0ec7f0000;07:f0dea5f0ec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd27;core:4;
Sending packet: $vStopped#55...Packet received: T0006:f0ee25f1ec7f0000;07:f0ee25f1ec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd26;core:5;
Sending packet: $vStopped#55...Packet received: T0006:f0bea5efec7f0000;07:f0bea5efec7f0000;10:f14190ccf4550000;thread:p12fd22.12fd29;core:1;
Sending packet: $vStopped#55...Packet received: T0006:f0ce25f0ec7f0000;07:f0ce25f0ec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd28;core:a;
Sending packet: $vStopped#55...Packet received: T0006:f07ea5edec7f0000;07:f07ea5edec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd2e;core:f;
Sending packet: $vStopped#55...Packet received: T0006:f0ae25efec7f0000;07:f0ae25efec7f0000;10:df4190ccf4550000;thread:p12fd22.12fd2a;core:6;
Sending packet: $vStopped#55...Packet received: T0006:0000000000000000;07:c0e8a381fe7f0000;10:bf43b4f1ec7f0000;thread:p12fd22.12fd22;core:2;
Sending packet: $vStopped#55...Packet received: T0006:f0fea5f1ec7f0000;07:f0fea5f1ec7f0000;10:df4190ccf4550000;thread:p12fd22.12fd25;core:8;
Sending packet: $vStopped#55...Packet received: T0006:f09ea5eeec7f0000;07:f09ea5eeec7f0000;10:e84190ccf4550000;thread:p12fd22.12fd2b;core:b;
Sending packet: $vStopped#55...Packet received: OK
But then wait_one never consumes them, always hitting this path:
4473 if (nfds == 0)
4474 {
4475 /* No waitable targets left. All must be stopped. */
4476 return {NULL, minus_one_ptid, {TARGET_WAITKIND_NO_RESUMED}};
4477 }
Resulting in GDB constanly calling target_stop to stop threads, but
the remote target never reporting back the stops to infrun.
That TARGET_WAITKIND_NO_RESUMED path shown above is always taken
because here, in wait_one too, just above:
4428 for (inferior *inf : all_inferiors ())
4429 {
4430 process_stratum_target *target = inf->process_target ();
4431 if (target == NULL
4432 || !target->is_async_p ()
^^^^^^^^^^^^^^^^^^^^^
4433 || !target->threads_executing)
4434 continue;
... the remote target is not async.
And in turn that happened because extended_remote_target::attach
misses enabling async in the target-non-stop path.
A testcase exercising this will be added in a following patch.
gdb/ChangeLog:
* remote.c (extended_remote_target::attach): Set target async in
the target-non-stop path too.
|
|
Attaching in non-stop mode currently misbehaves, like so:
(gdb) attach 1244450
Attaching to process 1244450
[New LWP 1244453]
[New LWP 1244454]
[New LWP 1244455]
[New LWP 1244456]
[New LWP 1244457]
[New LWP 1244458]
[New LWP 1244459]
[New LWP 1244461]
[New LWP 1244462]
[New LWP 1244463]
No unwaited-for children left.
At this point, GDB's stopped/running thread state is out of sync with
the inferior:
(gdb) info threads
Id Target Id Frame
* 1 LWP 1244450 "attach-non-stop" 0xf1b443bf in ?? ()
2 LWP 1244453 "attach-non-stop" (running)
3 LWP 1244454 "attach-non-stop" (running)
4 LWP 1244455 "attach-non-stop" (running)
5 LWP 1244456 "attach-non-stop" (running)
6 LWP 1244457 "attach-non-stop" (running)
7 LWP 1244458 "attach-non-stop" (running)
8 LWP 1244459 "attach-non-stop" (running)
9 LWP 1244461 "attach-non-stop" (running)
10 LWP 1244462 "attach-non-stop" (running)
11 LWP 1244463 "attach-non-stop" (running)
(gdb)
(gdb) interrupt -a
(gdb)
*nothing*
The problem is that attaching installs an inferior continuation,
called when the target reports the initial attach stop, here, in
inf-loop.c:inferior_event_handler:
/* Do all continuations associated with the whole inferior (not
a particular thread). */
if (inferior_ptid != null_ptid)
do_all_inferior_continuations (0);
However, currently in non-stop mode, inferior_ptid is still null_ptid
when we get here.
If you try to do "set debug infrun 1" to debug the problem, however,
then the attach completes correctly, with GDB reporting a stop for
each thread.
The bug is that we're missing a switch_to_thread/context_switch call
when handling the initial stop, here:
if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
&& (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_STOP
|| ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
|| ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_0))
{
stop_print_frame = true;
stop_waiting (ecs);
ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
return;
}
Note how the STOP_QUIETLY / STOP_QUIETLY_REMOTE case above that does
call context_switch.
And the reason "set debug infrun 1" "fixes" it, is that the debug path
has a switch_to_thread call.
This patch fixes it by moving the main context_switch call earlier.
A testcase exercising this will be added in a following patch.
gdb/ChangeLog:
* infrun.c (handle_signal_stop): Move main context_switch call
earlier, before STOP_QUIETLY_NO_SIGSTOP.
|
|
This allows gdb to quickly dump & process the memory map that the sim
knows about. This isn't fully accurate, but is largely limited by the
gdb memory map format. While the sim supports RWX bits, gdb can only
handle RW or RO regions.
|
|
An earlier patch to ada-lang.c:do_full_match introduced a subtle
change to the semantics. The previous code did:
- if (strncmp (sym_name, search_name, search_name_len) == 0
- && is_name_suffix (sym_name + search_name_len))
- return true;
-
- if (startswith (sym_name, "_ada_")
whereas the new code unconditionally skips a leading "_ada_".
The difference occurs if the lookup name itself starts with "_ada_".
In this case, the symbol won't match.
Normally this doesn't seem to be a problem. However, it caused a
regression on one particular (internal) test case on one particular
platform.
This patch changes the code to handle this case. I don't know how to
write a reliable test case for this, so no test is included.
2021-01-07 Tom Tromey <tromey@adacore.com>
* ada-lang.c (do_full_match): Conditionally skip "_ada_" prefix.
|
|
A recent upstream patch of mine caused a regression in aggregate
assignment. The bug was that add_component_interval didn't properly
update the array contents in one resize case.
I found furthermore that there was no test case that would provoke
this failure. This patch fixes the bug and introduces a test.
gdb/ChangeLog
2021-01-07 Tom Tromey <tromey@adacore.com>
* ada-lang.c (add_component_interval): Start loop using vector's
updated size.
gdb/testsuite/ChangeLog
2021-01-07 Tom Tromey <tromey@adacore.com>
* gdb.ada/assign_arr.exp: Add 'others' test.
|
|
Testing showed that gdb was not correctly handling some fixed-point
binary operations correctly.
Addition and subtraction worked by casting the result to the type of
left hand operand. So, "fixed+int" had a different type -- and
different value -- from "int+fixed".
Furthermore, for multiplication and division, it does not make sense
to first cast both sides to the fixed-point type. For example, this
can prevent "f * 1" from yielding "f", if 1 is not in the domain of
"f". Instead, this patch changes gdb to use the value. (This is
somewhat different from Ada semantics, as those can yield a "universal
fixed point".)
This includes a new test case. It is only run in "minimal" mode, as
the old-style fixed point works differently, and is obsolete, so I
have no plans to change it.
gdb/ChangeLog
2021-01-06 Tom Tromey <tromey@adacore.com>
* ada-lang.c (ada_evaluate_subexp) <BINOP_ADD, BINOP_SUB>:
Do not cast result.
* valarith.c (fixed_point_binop): Handle multiplication
and division specially.
* valops.c (value_to_gdb_mpq): New function.
(value_cast_to_fixed_point): Use it.
gdb/testsuite/ChangeLog
2021-01-06 Tom Tromey <tromey@adacore.com>
* gdb.ada/fixed_points/pck.ads (Delta4): New constant.
(FP4_Type): New type.
(FP4_Var): New variable.
* gdb.ada/fixed_points/fixed_points.adb: Update.
* gdb.ada/fixed_points.exp: Add tests for binary operators.
|
|
gdb.threads/signal-while-stepping-over-bp-other-thread.exp
Commit 3ec3145c5dd6 ("gdb: introduce scoped debug prints") updated some
tests using "set debug infrun" to handle the fact that a debug print is
now shown after the prompt, after an inferior stop. The same issue
happens in gdb.threads/signal-while-stepping-over-bp-other-thread.exp.
If I run it in a loop, it eventually fails like these other tests.
The problem is that the testsuite expects to see $gdb_prompt followed by
the end of the buffer. It happens that expect reads $gdb_prompt and the
debug print at the same time, in which case the regexp never matches and
we get a timeout.
The fix is the same as was done in 3ec3145c5dd6, make the testsuite
believe that the prompt is the standard GDB prompt followed by that
debug print.
Since that test uses gdb_test_sequence, and the expected prompt is in
gdb_test_sequence, add a -prompt switch to gdb_test_sequence to override
the prompt used for that call.
gdb/testsuite/ChangeLog:
* lib/gdb.exp (gdb_test_sequence): Accept -prompt switch.
* gdb.threads/signal-while-stepping-over-bp-other-thread.exp:
Pass prompt containing debug print to gdb_test_sequence.
Change-Id: I33161c53ddab45cdfeadfd50b964f8dc3caa9729
|
|
tui_win_info::refresh_window simply calls wrefresh, which internally
does a doupdate.
This redraws the source background window without the source pad.
Then prefresh of the source pad draws the actual source code on top,
which flickers.
By changing this to wnoutrefresh, the actual drawing on the screen is
only done once in the following prefresh, without flickering.
gdb/ChangeLog:
2021-01-05 Hannes Domani <ssbssa@yahoo.de>
* tui/tui-winsource.c (tui_source_window_base::refresh_window):
Call wnoutrefresh instead of tui_win_info::refresh_window.
|
|
There a 2 spaces between the numbers and source code, but only one of
them was redrawn.
So if you increase the source window height, the second space keeps the
character of the border rectangle.
With this both spaces are redrawn, so the border rectangle character is
overwritten.
gdb/ChangeLog:
2021-01-05 Hannes Domani <ssbssa@yahoo.de>
* tui/tui-source.c (tui_source_window::show_line_number):
Redraw second space after line number.
|
|
The smaxrow and smaxcol parameters of prefresh are the bottom right corner
of the text area inclusive, not exclusive.
And if the source window grows bigger in height, the pad has to grow as
well.
gdb/ChangeLog:
2021-01-05 Hannes Domani <ssbssa@yahoo.de>
PR tui/26927
* tui/tui-winsource.c (tui_source_window_base::refresh_window):
Fix source pad size in prefresh.
(tui_source_window_base::show_source_content): Grow source pad
if necessary.
|
|
|
|
While working on PR26935 I noticed that when running test-case
gdb.base/morestack.exp with target board unix/-m32/-fPIE/-pie and ld linker,
I get this linetable fragment for morestack.S using readelf -wL:
...
CU: ../../../../libgcc/config/i386/morestack.S:
Line number Starting address View Stmt
109 0xc9c x
...
838 0xe03 x
- 0xe04
636 0 x
637 0x3 x
- 0x4
...
but with "maint info line-table" I get:
...
INDEX LINE ADDRESS IS-STMT
0 END 0x00000004 Y
1 109 0x00000c9c Y
...
110 838 0x00000e03 Y
111 END 0x00000e04 Y
...
So, apparently the entries with addresses 0x0 and 0x3 are filtered out
because the addresses are out of range, but the same doesn't happen with the
end-of-seq terminator.
Fix this by filtering out end-of-seq terminators that do not actually
terminate anything.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-01-04 Tom de Vries <tdevries@suse.de>
* buildsym.c (buildsym_compunit::record_line): Filter out end-of-seq
terminators that do not terminate anything.
gdb/testsuite/ChangeLog:
2021-01-04 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/dw2-out-of-range-end-of-seq.exp: New file.
|
|
I spent a lot of time reading infrun debug logs recently, and I think
they could be made much more readable by being indented, to clearly see
what operation is done as part of what other operation. In the current
format, there are no visual cues to tell where things start and end,
it's just a big flat list. It's also difficult to understand what
caused a given operation (e.g. a call to resume_1) to be done.
To help with this, I propose to add the new scoped_debug_start_end
structure, along with a bunch of macros to make it convenient to use.
The idea of scoped_debug_start_end is simply to print a start and end
message at construction and destruction. It also increments/decrements
a depth counter in order to make debug statements printed during this
range use some indentation. Some care is taken to handle the fact that
debug can be turned on or off in the middle of such a range. For
example, a "set debug foo 1" command in a breakpoint command, or a
superior GDB manually changing the debug_foo variable.
Two macros are added in gdbsupport/common-debug.h, which are helpers to
define module-specific macros:
- scoped_debug_start_end: takes a message that is printed both at
construction / destruction, with "start: " and "end: " prefixes.
- scoped_debug_enter_exit: prints hard-coded "enter" and "exit"
messages, to denote the entry and exit of a function.
I added some examples in the infrun module to give an idea of how it can
be used and what the result looks like. The macros are in capital
letters (INFRUN_SCOPED_DEBUG_START_END and
INFRUN_SCOPED_DEBUG_ENTER_EXIT) to mimic the existing SCOPE_EXIT, but
that can be changed if you prefer something else.
Here's an excerpt of the debug
statements printed when doing "continue", where a displaced step is
started:
[infrun] proceed: enter
[infrun] proceed: addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT
[infrun] global_thread_step_over_chain_enqueue: enqueueing thread Thread 0x7ffff75a5640 (LWP 2289301) in global step over chain
[infrun] start_step_over: enter
[infrun] start_step_over: stealing global queue of threads to step, length = 1
[infrun] start_step_over: resuming [Thread 0x7ffff75a5640 (LWP 2289301)] for step-over
[infrun] resume_1: step=1, signal=GDB_SIGNAL_0, trap_expected=1, current thread [Thread 0x7ffff75a5640 (LWP 2289301)] at 0x5555555551bd
[displaced] displaced_step_prepare_throw: displaced-stepping Thread 0x7ffff75a5640 (LWP 2289301) now
[displaced] prepare: selected buffer at 0x5555555550c2
[displaced] prepare: saved 0x5555555550c2: 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 f0 50
[displaced] amd64_displaced_step_copy_insn: copy 0x5555555551bd->0x5555555550c2: c7 45 fc 00 00 00 00 eb 13 8b 05 d4 2e 00 00 83
[displaced] displaced_step_prepare_throw: prepared successfully thread=Thread 0x7ffff75a5640 (LWP 2289301), original_pc=0x5555555551bd, displaced_pc=0x5555555550c2
[displaced] resume_1: run 0x5555555550c2: c7 45 fc 00
[infrun] infrun_async: enable=1
[infrun] prepare_to_wait: prepare_to_wait
[infrun] start_step_over: [Thread 0x7ffff75a5640 (LWP 2289301)] was resumed.
[infrun] operator(): step-over queue now empty
[infrun] start_step_over: exit
[infrun] proceed: start: resuming threads, all-stop-on-top-of-non-stop
[infrun] proceed: resuming Thread 0x7ffff7da7740 (LWP 2289296)
[infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [Thread 0x7ffff7da7740 (LWP 2289296)] at 0x7ffff7f7d9b7
[infrun] prepare_to_wait: prepare_to_wait
[infrun] proceed: resuming Thread 0x7ffff7da6640 (LWP 2289300)
[infrun] resume_1: thread Thread 0x7ffff7da6640 (LWP 2289300) has pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP (currently_stepping=0).
[infrun] prepare_to_wait: prepare_to_wait
[infrun] proceed: [Thread 0x7ffff75a5640 (LWP 2289301)] resumed
[infrun] proceed: resuming Thread 0x7ffff6da4640 (LWP 2289302)
[infrun] resume_1: thread Thread 0x7ffff6da4640 (LWP 2289302) has pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP (currently_stepping=0).
[infrun] prepare_to_wait: prepare_to_wait
[infrun] proceed: end: resuming threads, all-stop-on-top-of-non-stop
[infrun] proceed: exit
We can easily see where the call to `proceed` starts and end. We can
also see why there are a bunch of resume_1 calls, it's because we are
resuming threads, emulating all-stop on top of a non-stop target.
We also see that debug statements nest well with other modules that have
been migrated to use the "new" debug statement helpers (because they all
use debug_prefixed_vprintf in the end. I think this is desirable, for
example we could see the debug statements about reading the DWARF info
of a library nested under the debug statements about loading that
library.
Of course, modules that haven't been migrated to use the "new" helpers
will still print without indentations. This will be one good reason to
migrate them.
I think the runtime cost (when debug statements are disabled) of this is
reasonable, given the improvement in readability. There is the cost of
the conditionals (like standard debug statements), one more condition
(if (m_must_decrement_print_depth)) and the cost of constructing a stack
object, which means copying a fews pointers.
Adding the print in fetch_inferior_event breaks some tests that use "set
debug infrun", because it prints a debug statement after the prompt. I
adapted these tests to cope with it, by using the "-prompt" switch of
gdb_test_multiple to as if this debug statement is part of the expected
prompt. It's unfortunate that we have to do this, but I think the debug
print is useful, and I don't want a few tests to get in the way of
adding good debug output.
gdbsupport/ChangeLog:
* common-debug.h (debug_print_depth): New.
(struct scoped_debug_start_end): New.
(scoped_debug_start_end): New.
(scoped_debug_enter_exit): New.
* common-debug.cc (debug_prefixed_vprintf): Print indentation.
gdb/ChangeLog:
* debug.c (debug_print_depth): New.
* infrun.h (INFRUN_SCOPED_DEBUG_START_END): New.
(INFRUN_SCOPED_DEBUG_ENTER_EXIT): New.
* infrun.c (start_step_over): Use
INFRUN_SCOPED_DEBUG_ENTER_EXIT.
(proceed): Use INFRUN_SCOPED_DEBUG_ENTER_EXIT and
INFRUN_SCOPED_DEBUG_START_END.
(fetch_inferior_event): Use INFRUN_SCOPED_DEBUG_ENTER_EXIT.
gdbserver/ChangeLog:
* debug.cc (debug_print_depth): New.
gdb/testsuite/ChangeLog:
* gdb.base/ui-redirect.exp: Expect infrun debug print after
prompt.
* gdb.threads/ia64-sigill.exp: Likewise.
* gdb.threads/watchthreads-reorder.exp: Likewise.
Change-Id: I7c3805e6487807aa63a1bae318876a0c69dce949
|
|
The code in print_target_wait_results uses a single call to debug_printf
in order to make sure a single timestamp is emitted, despite printing
multiple lines. The result is:
941502.043284 [infrun] target_wait (-1.0.0, status) =
[infrun] 649832.649832.0 [process 649832],
[infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP
I find this decision a bit counter productive, because it messes up the
alignment of the three lines. We don't care that three (slightly
different) timestamps are printed.
I suggest to change this function to use infrun_debug_printf, with this
result:
941601.425771 [infrun] print_target_wait_results: target_wait (-1.0.0 [process -1], status) =
941601.425824 [infrun] print_target_wait_results: 651481.651481.0 [process 651481],
941601.425867 [infrun] print_target_wait_results: status->kind = stopped, signal = GDB_SIGNAL_TRAP
Note that the current code only prints the waiton_ptid as a string
between square brackets if pid != -1. I don't think this complexity is
needed in a debug print. I made it so it's always printed, which I
think results in a much simpler function.
gdb/ChangeLog:
* infrun.c (print_target_wait_results): Use infrun_debug_printf.
Change-Id: I817bd10286b8e641a6c751ac3a1bd1ddf9b18ce0
|
|
New in v2:
- implement by modifying vprintf_unfiltered rather than
debug_prefixed_vprintf.
I tried enabling debug timestamps, and realized that it doesn't play
well with the revamp of the debug printouts I've been working on:
$ ./gdb -q -nx --data-directory=data-directory -ex "set debug infrun" -ex "set debug timestamp" a.out
Reading symbols from a.out...
(gdb) start
Temporary breakpoint 1 at 0x1131: file test.c, line 2.
Starting program: /home/smarchi/build/binutils-gdb-all-targets/gdb/a.out
939897.769338 [infrun] infrun_async:
939897.769383 enable=1
939897.769409
939897.915218 [infrun] proceed:
939897.915281 addr=0x7ffff7fd0100, signal=GDB_SIGNAL_0
939897.915315
939897.915417 [infrun] start_step_over:
939897.915464 stealing global queue of threads to step, length = 0
939897.915502
939897.915567 [infrun] operator():
939897.915601 step-over queue now empty
939897.915633
939897.915690 [infrun] proceed:
939897.915729 resuming process 636244
939897.915768
939897.915892 [infrun] resume_1:
939897.915954 step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [process 636244] at 0x7ffff7fd0100
939897.915991
939897.916119 [infrun] prepare_to_wait:
939897.916153 prepare_to_wait
939897.916201
939897.916661 [infrun] target_wait (-1.0.0, status) =
[infrun] 636244.636244.0 [process 636244],
[infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP
939897.916734 [infrun] handle_inferior_event:
939897.916768 status->kind = stopped, signal = GDB_SIGNAL_TRAP
939897.916799
This is due to debug_prefixed_vprintf being implemented as three
separate calls to debug_printf / debug_vprintf. Each call gets its own
timestamp and newline, curtesy of vprintf_unfiltered.
My first idea was to add a "line_start" parameter to debug_vprintf,
allowing the caller to say whether the print is the start of the line.
A debug timestamp would only be printed if line_start was true.
However, that was much more invasive than the simple fix implemented in
this patch.
My second idea was to make debug_prefixed_vprintf use string_printf and
issue a single call to debug_printf. That would however prevent future
use of styling in the debug messages.
What is implemented in this patch is the same as is implemented in
GDBserver: the timestamp-printing code in GDB tracks whether the last
debug output ended with a newline. If so, it prints a timestamp on the
next debug output.
After the fix, it looks like this:
$ ./gdb -q -nx --data-directory=data-directory -ex "set debug infrun" -ex "set debug timestamp" a.out
Reading symbols from a.out...
(gdb) start
Temporary breakpoint 1 at 0x1131: file test.c, line 2.
Starting program: /home/smarchi/build/binutils-gdb-all-targets/gdb/a.out
941112.135662 [infrun] infrun_async: enable=1
941112.279930 [infrun] proceed: addr=0x7ffff7fd0100, signal=GDB_SIGNAL_0
941112.280064 [infrun] start_step_over: stealing global queue of threads to step, length = 0
941112.280125 [infrun] operator(): step-over queue now empty
941112.280194 [infrun] proceed: resuming process 646228
941112.280332 [infrun] resume_1: step=0, signal=GDB_SIGNAL_0, trap_expected=0, current thread [process 646228] at 0x7ffff7fd0100
941112.280480 [infrun] prepare_to_wait: prepare_to_wait
941112.281004 [infrun] target_wait (-1.0.0, status) =
[infrun] 646228.646228.0 [process 646228],
[infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP
941112.281078 [infrun] handle_inferior_event: status->kind = stopped, signal = GDB_SIGNAL_TRAP
gdb/ChangeLog:
* utils.c (vfprintf_unfiltered): Print timestamp only when
previous debug output ended with a newline.
Change-Id: Idcfe3acc7e3d0f526a5f0a43a5e0884bf93c41ae
|
|
gdb.server/*.exp
When I run some tests in gdb.server (fox example
gdb.server/ext-attach.exp) on Ubuntu 20.04 with separate debug info for
glibc installed, they often time out. This is because GDB reads the
debug info through the remote protocol which is particularly slow:
attach 316937
Attaching to program: /home/smarchi/build/binutils-gdb-all-targets/gdb/testsuite/outputs/gdb.server/ext-attach/ext-attach, process 316937
Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading symbols from target:/lib/x86_64-linux-gnu/libc.so.6...
Reading /lib/x86_64-linux-gnu/libc-2.31.so from remote target...
Reading /lib/x86_64-linux-gnu/.debug/libc-2.31.so from remote target...
Reading /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.31.so from remote target...
FAIL: gdb.server/ext-attach.exp: attach to remote program 1 (timeout)
This is avoided in gdbserver boards by adding "set sysroot" to GDBFLAGS
(see boards/local-board.exp), which makes GDB read files from the local
filesystem. But gdb.server tests spawn GDBserver directly, so are ran
even when using the default unix board, where the "set sysroot" isn't
used.
Modify these tests to append "set sysroot" to the GDBFLAGS, a bit like
lib/local-board.exp does.
One special case is gdb.server/sysroot.exp, whose intent is to test
different "set sysroot" values. For this one, increase the timeout when
testing the "target:" sysroot.
gdb/testsuite/ChangeLog:
* gdb.server/abspath.exp: Append "set sysroot" to GDBFLAGS.
* gdb.server/connect-without-multi-process.exp: Likewise.
* gdb.server/exit-multiple-threads.exp: Likewise.
* gdb.server/ext-attach.exp: Likewise.
* gdb.server/ext-restart.exp: Likewise.
* gdb.server/ext-run.exp: Likewise.
* gdb.server/ext-wrapper.exp: Likewise.
* gdb.server/multi-ui-errors.exp: Likewise.
* gdb.server/no-thread-db.exp: Likewise.
* gdb.server/reconnect-ctrl-c.exp: Likewise.
* gdb.server/run-without-local-binary.exp: Likewise.
* gdb.server/server-kill.exp: Likewise.
* gdb.server/server-run.exp: Likewise.
* gdb.server/solib-list.exp: Likewise.
* gdb.server/stop-reply-no-thread.exp: Likewise.
* gdb.server/wrapper.exp: Likewise.
* gdb.server/sysroot.exp: Increase timeout when testing the
target: sysroot.
Change-Id: I7451bcc737f90e2cd0b977e9f09da3710774b0bf
|
|
I think this sequence of commands can be replaced with clean_restart.
gdb/testsuite/ChangeLog:
* gdb.server/server-run.exp: Use clean_restart.
Change-Id: If8c3eaa89f4ee58901282f5f1d5d4e1100ce7ac5
|
|
I think the sequence of commands here could be replaced with
clean_restart. The test starts with GDB not started, so it should not
be started when we reach gdb_skip_xml_test.
gdb/testsuite/ChangeLog:
* gdb.server/ext-run.exp: Use clean_restart.
Change-Id: I8c033bad6c52f3d58d6aa377b8355fc633c7aede
|
|
This test uses prepare_for_testing, then does a clean_restart for each
test configuration. prepare_for_testing does a build_executable plus a
clean_restart. So the clean_restart inside prepare_for_testing is done
for nothing.
Change prepare_for_testing to just build_executable to avoid the
unnecessary clean_restart.
gdb/testsuite/ChangeLog:
* gdb.server/stop-reply-no-thread.exp: Use build_executable
instead of prepare_for_testing.
Change-Id: I8b2a2e90353c57c39c49a3665083331b4882fdd0
|
|
I think this sequence of commands can be replaced by clean_restart,
despite what the comment says, as long as we don't use the `binfile`
argument to clean_restart.
gdb/testsuite/ChangeLog:
* gdb.server/solib-list.exp: Use clean_restart.
Change-Id: I4930564c50a1865cbffe0d660a4296c9d2158084
|
|
While working on PR26935 I noticed that the test-case requires the gold
linker, but doesn't really need it.
The -fuse-ld=gold was added to support the printf in the test-case, which
prints some information but is not otherwise needed for the test-case.
Fix this by removing the printf and the corresponding -fuse-ld=gold.
Tested on x86_64-linux.
Also checked that the test still fails when the fix from the commit that added
the test-case is reverted.
gdb/testsuite/ChangeLog:
2021-01-04 Tom de Vries <tdevries@suse.de>
* gdb.base/morestack.c: Remove printf.
* gdb.base/morestack.exp: Don't use -fuse-ld=gold.
|
|
The following patch drops the overloading going on with the trad_frame_saved_reg
struct and defines a new struct with a KIND enum and a union of different
fields.
The new struct looks like this:
struct trad_frame_saved_reg
{
setters/getters
...
private:
trad_frame_saved_reg_kind m_kind;
union {
LONGEST value;
int realreg;
LONGEST addr;
const gdb_byte *value_bytes;
} m_reg;
};
And the enums look like this:
/* Describes the kind of encoding a stored register has. */
enum class trad_frame_saved_reg_kind
{
/* Register value is unknown. */
UNKNOWN = 0,
/* Register value is a constant. */
VALUE,
/* Register value is in another register. */
REALREG,
/* Register value is at an address. */
ADDR,
/* Register value is a sequence of bytes. */
VALUE_BYTES
};
The patch also adds setters/getters and updates all the users of the old
struct.
It is worth mentioning that due to the previous overloaded nature of the
fields, some tdep files like to store negative offsets and indexes in the ADDR
field, so I kept the ADDR as LONGEST instead of CORE_ADDR. Those cases may
be better supported by a new enum entry.
I have not addressed those cases in this patch to prevent unwanted breakage,
given I have no way to test some of the targets. But it would be nice to
clean those up eventually.
The change to frame-unwind.* is to constify the parameter being passed to the
unwinding functions, given we now accept a "const gdb_byte *" for value bytes.
Tested on aarch64-linux/Ubuntu 20.04/18.04 and by building GDB with
--enable-targets=all.
gdb/ChangeLog:
2021-01-04 Luis Machado <luis.machado@linaro.org>
Update all users of trad_frame_saved_reg to use the new member
functions.
Remote all struct keywords from declarations of trad_frame_saved_reg
types, except on forward declarations.
* aarch64-tdep.c: Update.
* alpha-mdebug-tdep.c: Update.
* alpha-tdep.c: Update.
* arc-tdep.c: Update.
* arm-tdep.c: Update.
* avr-tdep.c: Update.
* cris-tdep.c: Update.
* csky-tdep.c: Update.
* frv-tdep.c: Update.
* hppa-linux-tdep.c: Update.
* hppa-tdep.c: Update.
* hppa-tdep.h: Update.
* lm32-tdep.c: Update.
* m32r-linux-tdep.c: Update.
* m32r-tdep.c: Update.
* m68hc11-tdep.c: Update.
* mips-tdep.c: Update.
* moxie-tdep.c: Update.
* riscv-tdep.c: Update.
* rs6000-tdep.c: Update.
* s390-linux-tdep.c: Update.
* s390-tdep.c: Update.
* score-tdep.c: Update.
* sparc-netbsd-tdep.c: Update.
* sparc-sol2-tdep.c: Update.
* sparc64-fbsd-tdep.c: Update.
* sparc64-netbsd-tdep.c: Update.
* sparc64-obsd-tdep.c: Update.
* sparc64-sol2-tdep.c: Update.
* tilegx-tdep.c: Update.
* v850-tdep.c: Update.
* vax-tdep.c: Update.
* frame-unwind.c (frame_unwind_got_bytes): Make parameter const.
* frame-unwind.h (frame_unwind_got_bytes): Likewise.
* trad-frame.c: Update.
Remove TF_REG_* enum.
(trad_frame_alloc_saved_regs): Add a static assertion to check for
a trivially-constructible struct.
(trad_frame_reset_saved_regs): Adjust to use member function.
(trad_frame_value_p): Likewise.
(trad_frame_addr_p): Likewise.
(trad_frame_realreg_p): Likewise.
(trad_frame_value_bytes_p): Likewise.
(trad_frame_set_value): Likewise.
(trad_frame_set_realreg): Likewise.
(trad_frame_set_addr): Likewise.
(trad_frame_set_unknown): Likewise.
(trad_frame_set_value_bytes): Likewise.
(trad_frame_get_prev_register): Likewise.
* trad-frame.h: Update.
(trad_frame_saved_reg_kind): New enum.
(struct trad_frame_saved_reg) <addr, realreg, data>: Remove.
<m_kind, m_reg>: New member fields.
<set_value, set_realreg, set_addr, set_unknown, set_value_bytes>
<kind, value, realreg, addr, value_bytes, is_value, is_realreg>
<is_addr, is_unknown, is_value_bytes>: New member functions.
|
|
gdb/ChangeLog:
* target-float.c: Fix typos.
Change-Id: Ib65e90746d0a7c77c3fbead81139facb40b91977
|
|
In struct dynamic_prop the members kind and data were renamed to m_kind and
m_data.
And flag_upper_bound_is_count is actually in bounds directly, not in its
high member.
gdb/ChangeLog:
2021-01-02 Hannes Domani <ssbssa@yahoo.de>
* gdb-gdb.py.in: Fix main_type.flds_bnds.bounds pretty printer.
|
|
gdb/ChangeLog:
* gdbarch.sh: Update copyright year range.
gdb/doc/ChangeLog:
* gdb.texinfo, refcard.tex: Update copyright year range.
|
|
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.
|
|
This commit adjusts GDB's copyright.py script, following two past changes:
- gdb/gdbserver/ being move to the toplevel directory;
- gdb/common/ being renamed to gdbsupport/.
gdb/ChangeLog:
* copyright.py (get_update_list): Add "gdbserver" and "gdbsupport"
to the list of directories to update.
|
|
gdb/ChangeLog:
* top.c (print_gdb_version): Update copyright year.
gdbserver/ChangeLog:
* server.cc (gdbserver_version): Update copyright year.
* gdbreplay.cc (gdbreplay_version): Likewise.
|
|
As a results of the rotation, this introduces a new file which
needed to be added to DJGPP's fnchange.lst.
gdb/ChangeLog
* config/djgpp/fnchange.lst: Add entry for gdb/ChangeLog-2020.
|
|
Rust 1.49 was released today, and it includes some library changes
which caused some gdb.rust tests to fail. This patch adapts the test
suite to the new output. I also verified that this continues to work
with Rust 1.48.
gdb/testsuite/ChangeLog
2020-12-31 Tom Tromey <tom@tromey.com>
* gdb.rust/simple.exp: Update output for Rust 1.49.
|
|
Fix a bug in the test where we were missing "additional_flags=",
causing -gstatement-frontiers not to be passed to the compiler.
The issue was introduced in
eb24648c453c28f2898fb599311ba004394a8b41 ("Fix gdb.cp/step-and-next-inline.exp with Clang").
gdb/testsuite:
2020-12-31 Bernd Edlinger <bernd.edlinger@hotmail.de>
* gdb.cp/step-and-next-inline.exp: Fix test case.
|
|
Use with_test_prefix to de-duplicate test names.
gdb/testsuite/ChangeLog:
* gdb.python/py-frame-args.exp: De-duplicate test names.
Change-Id: I5cc8bee692a0d071cb78258aca80ea642e00e7a8
|
|
The objects returned by FrameDecorator.frame_args need to implement a
method named symbol, not argument.
gdb/doc/ChangeLog:
2020-12-29 Hannes Domani <ssbssa@yahoo.de>
* python.texi (Frame Decorator API): Fix method name.
|
|
The MULTI_SUBSCRIPT code in evaluate_subexp_standard has a comment
saying that perhaps the EVAL_SKIP handling is incorrect. This patch
simplifies this code. In particular, it precomputes all the indices
in a separate loop and removes some complicated flow-control.
Tested using the gdb.modula2 and gdb.dlang test suites, as these are
the only parsers that emit MULTI_SUBSCRIPT.
gdb/ChangeLog
2020-12-27 Tom Tromey <tom@tromey.com>
* eval.c (evaluate_subexp_standard) <case MULTI_SUBSCRIPT>:
Simplify.
|
|
In PR gdb/27059 an issue was discovered where GDB would sometimes
trigger undefined behaviour in the form of signed integer overflow.
The problem here is that GDB was reading random garbage from the
inferior memory space, assuming this data was valid, and performing
arithmetic on it.
This bug raises an interesting general problem with GDB's DWARF
expression evaluator, which is this:
We currently assume that the DWARF expressions being evaluated are
well formed, and well behaving. As an example, this is the expression
that the bug was running into problems on, this was used as the
expression for a DW_AT_byte_stride of a DW_TAG_subrange_type:
DW_OP_push_object_address;
DW_OP_plus_uconst: 88;
DW_OP_deref;
DW_OP_push_object_address;
DW_OP_plus_uconst: 32;
DW_OP_deref;
DW_OP_mul
Two values are read from the inferior and multiplied together. GDB
should not assume that any value read from the inferior is in any way
sane, as such the implementation of DW_OP_mul should be guarding
against overflow and doing something semi-sane here.
However, it turns out that the original bug PR gdb/27059, is hitting a
more specific case, which doesn't require changes to the DWARF
expression evaluator, so I'm going to leave the above issue for
another day.
In the test mentioned in the bug GDB is actually trying to resolve the
dynamic type of a Fortran array that is NOT allocated. A
non-allocated Fortran array is one that does not have any data
allocated for it yet, and even the upper and lower bounds of the array
are not yet known.
It turns out that, at least for gfortran compiled code, the data
fields that describe the byte-stride are not initialised until the
array is allocated.
This leads me to the following conclusion: GDB should not try to
resolve the bounds, or stride information for an array that is not
allocated (or not associated, a similar, but slightly different
Fortran feature). Instead, each of these properties should be set to
undefined if the array is not allocated (or associated).
That is what this commit does. There's a new flag that is passed
around during the dynamic array resolution. When this flag is true
the dynamic properties are resolved using the DWARF expressions as
they currently are, but when this flag is false the expressions are
not evaluated, and instead the properties are set to undefined.
gdb/ChangeLog:
PR gdb/27059
* eval.c (evaluate_subexp_for_sizeof): Handle not allocated and
not associated arrays.
* f-lang.c (fortran_adjust_dynamic_array_base_address_hack): Don't
adjust arrays that are not allocated/associated.
* gdbtypes.c (resolve_dynamic_range): Update header comment. Add
new parameter which is used to sometimes set dynamic properties to
undefined.
(resolve_dynamic_array_or_string): Update header comment. Add new
parameter which is used to guard evaluating dynamic properties.
Resolve allocated/associated properties first.
gdb/testsuite/ChangeLog:
PR gdb/27059
* gdb.dwarf2/dyn-type-unallocated.c: New file.
* gdb.dwarf2/dyn-type-unallocated.exp: New file.
|
|
Adds the allocated and associated dynamic properties into the output
of the 'maintenance print type' command.
gdb/ChangeLog:
* gdbtypes (recursive_dump_type): Include allocated and associated
properties.
|
|
When called with an array type of unknown dimensions,
is_scalar_type_recursive ended up comparing uninitialized values.
This was picked up by the following compiler warning:
CXX gdbtypes.o
/binutils-gdb/gdb/gdbtypes.c: In function int is_scalar_type_recursive(type*):
/binutils-gdb/gdb/gdbtypes.c:3670:38: warning: high_bound may be used uninitialized in this function [-Wmaybe-uninitialized]
3670 | return high_bound == low_bound && is_scalar_type_recursive (elt_type);
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/binutils-gdb/gdb/gdbtypes.c:3670:38: warning: low_bound may be used uninitialized in this function [-Wmaybe-uninitialized]
This patch makes sure that when dealing with an array of unknown size
(or an array of more than 1 element), is_scalar_type_recursive returns
false.
gdb/ChangeLog:
* gdbtypes.c (is_scalar_type_recursive): Prevent comparison
between uninitialized values.
Change-Id: Ifc005ced166aa7a065fef3e652977bae67625bf4
|
|
Both QEMU and kgdb make the assumption that the '?' packet is only
sent during the initial setup of a gdbstub connection. Both use that
knowledge to reset breakpoints and ensure the gdbstub is in a
clean-state on a resumed connection. This can cause confusion for
others implementing clients that speak to gdbstub devices. To avoid
that make the language clearer that this is a start-up query packet
that you only expect to see once.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
gdb/doc/ChangeLog:
* gdb.texinfo (Packets): Clarify language for ? packet.
Change-Id: Iae25d3110fe28b8d2467704962a6889e55224ca5
|
|
This commit removes some, but not all, uses of LA_PRINT_STRING. In
this commit I've removed those uses where there is an obvious language
object on which I can instead call the printstr method.
In the remaining 3 uses it is harder to know if the correct thing is
to call printstr on the current language, or on a specific language.
Currently obviously, we always call on the current language (as that's
what LA_PRINT_STRING does), and clearly this behaviour is good enough
right now, but is it "right"? I've left them for now and will give
them more thought in the future.
gdb/ChangeLog:
* expprint.c (print_subexp_standard): Replace uses of
LA_PRINT_STRING.
* f-valprint.c (f_language::value_print_inner): Likewise.
* guile/scm-pretty-print.c (ppscm_print_string_repr): Likewise.
* p-valprint.c (pascal_language::value_print_inner): Likewise.
* python/py-prettyprint.c (print_string_repr): Likewise.
|
|
Move the rust_language class declaration into the rust-lang.h header
file. This allows for the function implementations called directly in
rust-lang.c and rust-exp.y without the need for trampoline functions.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* rust-exp.y (rust_parse): Rename to...
(rust_language::parser): ...this.
* rust-lang.c (-rust_printstr): Rename to...
(rust_language::printstr): ...this.
(rust_value_print_inner): Delete declaration.
(val_print_struct): Rename to...
(rust_language::val_print_struct): ...this. Update calls to
member functions.
(rust_print_enum): Rename to...
(rust_language::print_enum): ...this. Update calls to member
functions.
(rust_value_print_inner): Rename to...
(rust_language::value_print_inner): ...this. Update calls to
member functions.
(exp_descriptor_rust): Rename to...
(rust_language::exp_descriptor_tab): ...this.
(class rust_language): Move to rust-lang.h.
(rust_language::language_arch_info): Implementation moved to here
from class declaration.
(rust_language::print_type): Likewise.
(rust_language::emitchar): Likewise.
(rust_language::is_string_type_p): Likewise.
* rust-lang.h: Add 'demangle.h', 'language.h', 'value.h', and
'c-lang.h' includes.
(rust_parse): Delete declaration.
(class rust_language): Class declaration moved here from
rust-lang.c.
|
|
In this commit:
commit b7c6e27dbbbbe678b2e2f0bf617605e055e1b378
Date: Tue Aug 4 17:07:59 2020 +0100
gdb: Convert language_data::la_op_print_tab to a method
A bug was introduced, the objc language now returns the wrong op_print
table. Fixed in this commit.
gdb/ChangeLog:
* objc-lang.c (objc_language::opcode_print_table): Return
objc_op_print_tab.
|