Age | Commit message (Collapse) | Author | Files | Lines |
|
There was an earlier thread about adding new methods to
pretty-printers:
https://sourceware.org/pipermail/gdb-patches/2023-June/200503.html
We've known about the need for printer extensibility for a while, but
have been hampered by backward-compatibilty concerns: gdb never
documented that printers might acquire new methods, and so existing
printers may have attribute name clashes.
To solve this problem, this patch adds a new pretty-printer tag class
that signals to gdb that the printer follows new extensibility rules.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30816
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
With any gdb.dap test and python 3.6 I run into:
...
Error occurred in Python: 'code' object has no attribute 'co_posonlyargcount'
ERROR: eof reading json header
...
The attribute is not supported before python 3.8, which introduced the
"Positional−only Parameters" concept.
Fix this by using try/except AttributeError.
Tested on x86_64-linux:
- openSUSE Leap 15.4 with python 3.6, and
- openSUSE Tumbleweed with python 3.11.5.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
The buildbot pointed out that the last DAP series I checked in had an
issue. Looking into it, it seems there is a stray trailing "," in
breakpoint.py. This patch removes it.
This seems to point out a test suite deficiency. I will look into
fixing that.
|
|
I noticed a comment by an include and remembered that I think these
don't really provide much value -- sometimes they are just editorial,
and sometimes they are obsolete. I think it's better to just remove
them. Tested by rebuilding.
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
According to the DAP specification if the "sourceReference" field is
included in a Source object, then the DAP client _must_ make a "source"
request to the debugger to retrieve file contents, even if the Source
object also includes path information.
If the Source's path field is a valid path that the DAP client is able
to read from the filesystem, having to make another request to the
debugger to get the file contents is wasteful and leads to incorrect
results (DAP clients will try to get the contents from the server and
display those contents as a file with the name in "source.path", but
this will conflict with the _acutal_ existing file at "source.path").
Instead, only set "sourceReference" if the source file path does not
exist.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
If the breakpoint has a fullname, use that as the source path when
resolving the breakpoint source information. This is consistent with
other callers of make_source which also use "fullname" if it exists (see
e.g. DAPFrameDecorator which returns the symtab's fullname).
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Some DAP clients may send additional parameters in the stepOut command
(e.g. "granularity") which are not used by GDB, but should nonetheless
be accepted without error.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Not all breakpoints have a source location. For example, a breakpoint
set on a raw address will have only the "address" field populated, but
"source" will be None, which leads to a RuntimeError when attempting to
unpack the filename and line number.
Before attempting to unpack the filename and line number from the
breakpoint, ensure that the source information is not None. Also
populate the source and line information separately from the
"instructionReference" field, so that breakpoints that include only an
address are still included.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
The buildbot pointed out that I neglected to re-run 'black' after
making some changes. This patch fixes the oversight.
|
|
A user pointed out that the current DAP variable code does not let the
client deference a pointer. Oops!
Fixing this oversight is simple enough -- adding a new no-op
pretty-printer for pointers and references is quite simple.
However, doing this naive caused a regession in scopes.exp, which
expected there to be no children of a 'const char *' variable. This
problem was fixed by the preceding patches in the series, which ensure
that a C type of this kind is recognized as a string.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30821
|
|
This changes main_type to hold a language, and updates the debug
readers to set this field. This is done by adding the language to the
type-allocator object.
Note that the non-DWARF readers are changed on a "best effort" basis.
This patch also reimplements type::is_array_like to use the type's
language, and it adds a new type::is_string_like as well. This in
turn lets us change the Python implementation of these methods to
simply defer to the type.
|
|
This replaces some casts to 'watchpoint *' with checked_static_cast.
In one spot, an unnecessary block is also removed.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
A user pointed out that if a DAP setBreakpoints request has a 'source'
field in a SourceBreakpoint object, then the gdb DAP implementation
will throw an exception.
While SourceBreakpoint does not allow 'source' in the spec, it seems
better to me to accept it. I don't think we should fully go down the
"Postel's Law" path -- after all, we have the type-checker -- but at
the same time, if we do send errors, they should be intentional and
not artifacts of the implementation.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30820
|
|
When running test-case gdb.python/py-symbol.exp with target board
cc-with-dwz-m, we run into:
...
(gdb) python print (len (gdb.lookup_static_symbols ('rr')))^M
4^M
(gdb) FAIL: gdb.python/py-symbol.exp: \
print (len (gdb.lookup_static_symbols ('rr')))
...
while with target board unix we have instead:
...
(gdb) python print (len (gdb.lookup_static_symbols ('rr')))^M
2^M
(gdb) PASS: gdb.python/py-symbol.exp: \
print (len (gdb.lookup_static_symbols ('rr')))
...
The problem is that the loop in gdbpy_lookup_static_symbols loops over compunits
representing both CUs and PUs:
...
for (compunit_symtab *cust : objfile->compunits ())
...
When doing a lookup on a PU, the user link is followed until we end up at a CU,
and the lookup is done in that CU.
In other words, when doing a lookup in the loop for a PU we duplicate the
lookup for a CU that is already handled by the loop.
Fix this by skipping PUs in the loop in gdb.lookup_static_symbols.
Tested on x86_64-linux.
PR symtab/25261
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25261
|
|
This changes the no-op pretty printers -- used by DAP -- to handle
array- and string-like objects known by the gdb core. Two new tests
are added, one for Ada and one for Rust.
|
|
gdb's language code may know how to display values specially. For
example, the Rust code understands that &str is a string-like type, or
Ada knows how to handle unconstrained arrays. This knowledge is
exposed via val-print, and via varobj -- but currently not via DAP.
This patch adds some support code to let DAP also handle these cases,
though in a somewhat more generic way.
Type.is_array_like and Value.to_array are added to make Python aware
of the cases where gdb knows that a structure type is really
"array-like".
Type.is_string_like is added to make Python aware of cases where gdb's
language code knows that a type is string-like.
Unlike Value.string, these cases are handled by the type's language,
rather than the current language.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
Right now, if a program uses multiple languages, DAP value formatting
will always use the language of the innermost frame. However, it is
better to use the variable's defining frame instead. This patch does
this by selecting the frame first.
This also fixes a possibly latent bug in the "stepOut" command --
"finish" is sensitive to the selected frame, but the DAP code may
already select other frames when convenient. The DAP stepOut request
only works on the newest frame, so be sure to select it before
invoking "finish".
|
|
Ada has a few complexities when it comes to array handling. Currently
these are all handled in Ada-specific code -- but unfortunately that
means they aren't really accessible to Python.
This patch changes the Python code to defer to Ada when given an Ada
array. In order to make this work, one spot in ada-lang.c had to be
updated to set the "GNAT-specific" flag on an array type.
The test case for this will come in a later patch.
|
|
Replace with type::field + field::bitsize.
Change-Id: I2a24755a33683e4a2775a6d2a7b7a9ae7362e43a
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Replace with type::field + field::is_artificial.
Change-Id: Ie3bacae49d9bd02e83e504c1ce01470aba56a081
Approved-By: Tom Tromey <tom@tromey.com>
|
|
In remote_target::thread_info_to_thread_handle we return a copy:
...
gdb::byte_vector
remote_target::thread_info_to_thread_handle (struct thread_info *tp)
{
remote_thread_info *priv = get_remote_thread_info (tp);
return priv->thread_handle;
}
...
Fix this by returning a gdb::array_view instead:
...
gdb::array_view<const gdb_byte>
remote_target::thread_info_to_thread_handle (struct thread_info *tp)
...
Tested on x86_64-linux.
This fixes the build when building with -std=c++20.
Approved-By: Pedro Alves <pedro@palves.net>
|
|
Currently, each target backend is responsible for printing "[Thread
...exited]" before deleting a thread. This leads to unnecessary
differences between targets, like e.g. with the remote target, we
never print such messages, even though we do print "[New Thread ...]".
E.g., debugging the gdb.threads/attach-many-short-lived-threads.exp
with gdbserver, letting it run for a bit, and then pressing Ctrl-C, we
currently see:
(gdb) c
Continuing.
^C[New Thread 3850398.3887449]
[New Thread 3850398.3887500]
[New Thread 3850398.3887551]
[New Thread 3850398.3887602]
[New Thread 3850398.3887653]
...
Thread 1 "attach-many-sho" received signal SIGINT, Interrupt.
0x00007ffff7e6a23f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffda80, rem=rem@entry=0x7fffffffda80)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78 in ../sysdeps/unix/sysv/linux/clock_nanosleep.c
(gdb)
Above, we only see "New Thread" notifications, even though threads
were deleted.
After this patch, we'll see:
(gdb) c
Continuing.
^C[Thread 3558643.3577053 exited]
[Thread 3558643.3577104 exited]
[Thread 3558643.3577155 exited]
[Thread 3558643.3579603 exited]
...
[New Thread 3558643.3597415]
[New Thread 3558643.3600015]
[New Thread 3558643.3599965]
...
Thread 1 "attach-many-sho" received signal SIGINT, Interrupt.
0x00007ffff7e6a23f in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fffffffda80, rem=rem@entry=0x7fffffffda80)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78 in ../sysdeps/unix/sysv/linux/clock_nanosleep.c
(gdb) q
This commit fixes this by moving the thread exit printing to common
code instead, triggered from within delete_thread (or rather,
set_thread_exited).
There's one wrinkle, though. While most targest want to print:
[Thread ... exited]
the Windows target wants to print:
[Thread ... exited with code <exit_code>]
... and sometimes wants to suppress the notification for the main
thread. To address that, this commits adds a delete_thread_with_code
function, only used by that target (so far).
This fix was originally posted as part of a larger series:
https://inbox.sourceware.org/gdb-patches/20221212203101.1034916-1-pedro@palves.net/
But didn't really need to be part of that series. In order to get
this fix merged sooner, I (Andrew Burgess) have rebased this commit
outside of the original series. Any bugs introduced while splitting
this patch out and rebasing, are entirely my own.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30129
Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
|
|
Remove the static mi_parse::make functions, and instead use the
mi_parse constructor.
This is a partial revert of the commit:
commit fde3f93adb50c9937cd2e1c93561aea2fd167156
Date: Mon Mar 20 10:56:55 2023 -0600
Introduce "static constructor" for mi_parse
which introduced the mi_parse::make functions, though after discussion
on the list the reasons for seem to have been lost[1]. Given there
are no test regressions when moving back to using the constructors, I
propose we should do that for now.
There should be no user visible changes after this commit.
[1] https://inbox.sourceware.org/gdb-patches/20230404-dap-loaded-sources-v2-5-93f229095e03@adacore.com/
Approved-By: Tom Tromey <tom@tromey.com>
|
|
While GDB is still C++11, lets add a gdb::make_unique template
function that can be used to create std::unique_ptr objects, just like
the C++14 std::make_unique.
If GDB is being compiled with a C++14 compiler then the new
gdb::make_unique function will delegate to the std::make_unique. I
checked with gcc, and at -O1 and above gdb::make_unique will be
optimised away completely in this case.
If C++14 (or later) becomes our minimum, then it will be easy enough
to go through the code and replace gdb::make_unique with
std::make_unique later on.
I've make use of this function in all the places I think this can
easily be used, though I'm sure I've probably missed some.
Should be no user visible changes after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I noticed a call to value::copy in gdbpy_get_varobj_pretty_printer,
and I couldn't figure out why it was there. I think maybe it came
from the time when value_to_value_object would release values from the
value chain -- but that was removed in commit f3d3bbbc.
This patch removes this call. Regression tested on x86-64 Fedora 36.
|
|
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/
|
|
DAP specifies an event that should be sent when a module is removed.
This patch implements this.
Tested-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
|
|
When building gdb with -O2 -flto, I run into:
...
gdb/guile/scm-param.c:121:6: warning: type 'param_types' violates the C++ \
One Definition Rule [-Wodr]
enum param_types
^
gdb/python/py-param.c:33:6: note: an enum with different value name is \
defined in another translation unit
enum param_types
^
...
Fix this by renaming to enum scm_param_types and py_param_types.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR build/22395
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=22395
|
|
In gdb/python/py-param.c we have:
...
enum param_types
{
...
}
param_types;
...
which declares both an enum param_types, and an unused variable param_types.
Fix this by removing the variable.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
One more f-string snuck into the DAP code, in breakpoint.py. Most of
them were removed here:
https://sourceware.org/pipermail/gdb-patches/2023-June/200023.html
but I think this one landed after that patch.
While DAP only supports Python 3.5 and later, f-strings were added in
3.6, so remove this.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30708
|
|
A co-worker pointed out that gdb's DAP implementation might return an
integer for the name of a stack frame, like:
{"id": 1, "name": 93824992310799, ...}
This can be seen currently in the logs of the bt-nodebug.exp test
case.
What is happening is that FrameDecorator falls back on returning the
PC when the frame's function symbol cannot be found, relying on the
gdb core to look up the minsym and print its name.
This can actually yield the wrong answer sometimes, because it falls
into the get_frame_pc / get_frame_address_in_block problem -- if the
frame is at a call to a noreturn function, the PC in this case might
appear to be in the next function in memory. For more on this, see:
https://sourceware.org/bugzilla/show_bug.cgi?id=8416
and related bugs.
However, there's a different approach we can take: the code here can
simply use Frame.name. This handles the PC problem correctly, and
gets us the information we need.
|
|
DAP requires python module typing, which is supported starting python 3.5.
Make this formal by:
- disabling the dap interpreter for python version < 3.5
- returning 0 in allow_dap_tests for python version < 3.5
Approved-By: Tom Tromey <tom@tromey.com>
PR dap/30708
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30708
|
|
This implements the DAP "source" request. I renamed the
"loadedSources" function from "sources" to "loaded_sources" to avoid
any confusion. I also moved the loadedSources test to the new
sources.exp.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30691
|
|
This changes the DAP breakpointLocations request to accept a Source
and to decode it properly.
|
|
This changes the gdb DAP implementation to emit a real
sourceReference, rather than emitting 0. Sources are tracked in some
maps in sources.py, and a new helper function is introduced to compute
the "Source" object that can be sent to the client.
|
|
The DAP 'module' event may include a 'path' component. I noticed that
this is supplied even when the module in question does not come from a
file.
This patch only emits this field when the objfile corresponds to a
real file.
No test case, because I wasn't sure how to write a portable one.
However, it's clear from gdb.log on Linux:
{"type": "event", "event": "module", "body": {"reason": "new", "module": {"id": "system-supplied DSO at 0x7ffff7fc4000", "name": "system-supplied DSO at 0x7ffff7fc4000"}}, "seq": 21}
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30676
|
|
This patch implements ValueFormat for DAP. Currently this only means
supporting "hex".
Note that StackFrameFormat is defined to have many more options, but
none are currently recognized. It isn't entirely clear how these
should be handled. I'll file a new gdb bug for this, and perhaps an
upstream DAP bug as well.
New in v2:
- I realized that the "hover" context was broken, and furthermore
that we only had tests for "hover" failing, not for it succeeding.
This version fixes the oversight and adds a test.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30469
|
|
I noticed that the support for memoryReference in the "variables"
output is gated on the client "supportsMemoryReferences" capability.
This patch implements this and makes some other changes to the DAP
memory reference code:
* Remove the memoryReference special case from _SetResult.
Upstream DAP fixed this oversight in response to
https://github.com/microsoft/debug-adapter-protocol/issues/414
* Don't use the address of a variable as its memoryReference -- only
emit this for pointer types. There's no spec support for the
previous approach.
* Use strip_typedefs to handle typedefs of pointers.
|
|
This adds DAP support for the various C++ exception-catching
operations.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30682
|
|
This implements the DAP 'terminated' event. Vladimir Makaev noticed
that VSCode will not report the debug session as over unless this is
sent.
It's not completely clear when exactly this event ought to be sent.
Here I've done it when the inferior exits.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30681
|
|
When the DAP client sets a breakpoint, gdb currently sends a "new
breakpoint" event. However, Vladimir Makaev discovered that this
causes VSCode to think there are two breakpoints.
This patch changes gdb to suppress the event in this case.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30678
|
|
A subsequent patch will add the ability to suppress breakpoint events
to DAP. My first attempt at this ended up with recurse imports,
causing Python failures. So, this patch moves all the DAP breakpoint
event code to breakpoint.py in preparation for the change.
I've renamed breakpoint_descriptor here as well, because it can now be
private to breakpoint.py.
|
|
Vladimir Makaev noticed that, in some cases, a DAP stackTrace response
would include a relative path name for the "path" component.
This patch changes the frame decorator code to add a new DAP-specific
decorator, and changes the DAP entry point to frame filters to use it.
This decorator prefers the symtab's full name, and does not fall back
to the solib's name.
I'm not entirely happy with this patch, because if a user frame filter
uses FrameDecorator, it may still do the wrong thing. It would be
better to have frame filters return symtab-like objects instead, or to
have a separate method to return the full path to the source file.
I also tend to think that the solib fallback behavior of
FrameDecorator is a mistake. If this is ever needed, it seems to me
that it should be a separate method.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30665
|
|
This adds the "cwd" parameter to the DAP launch request.
This came up here:
https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/90
... and seemed like a good idea.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
In Python, a member name starting with "__" is specially handled to
make it "more private" to the class -- it isn't truly private, but it
is renamed to make it less likely to be reused by mistake. This patch
ensures that this is done for the private method of FrameDecorator.
|
|
Reports a thread exit according to the DAP spec:
https://microsoft.github.io/debug-adapter-protocol/specification#Events_Thread
This patch requires the ThreadExitedEvent to be checked in,
in order to work. That patch is found here https://sourceware.org/pipermail/gdb-patches/2023-June/200071.html
Formatted correctly using black
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30474
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Tom de Vries found a bug where, sometimes, a SIGCHLD would be
delivered to a non-main thread, wreaking havoc.
The problem is that gdb.block_signals after first blocking a set of
signals, then unblocked the same set rather than restoring the initial
situation. This function being called from the DAP thread lead to
SIGCHLD being unblocked there.
This patch fixes the problem by restoring the previous set of signals
instead.
Tested-by: Tom de Vries <tdevries@suse.de>
Reviewed-By: Tom de Vries <tdevries@suse.de>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30680
|
|
Tom de Vries filed a bug about an intermittent gdb DAP failure -- and
coincidentally, at the same time, Alexandra Hájková sent email about a
somewhat similar failure.
After looking into this for a while (with no results) using ASan and
valgrind, I found that setting PYTHONMALLOC=malloc_debug found the bug
instantly.
The problem is that gdbpy_parse_and_eval releases the GIL while
calling parse_and_eval, but fails to re-acquire it before calling
value_to_value_object. This is easily fixed by introducing a new
scope.
I wonder whether the test suite should unconditionally set
PYTHONMALLOC=malloc_debug.
Tested-by: Tom de Vries <tdevries@suse.de>
Reviewed-By: Tom de Vries <tdevries@suse.de>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30686
|
|
While looking at the DAP spec, I noticed that the breakpointLocations
request is gated behind a capability. This patch changes gdb to
report this capability.
I've also added a comment to explain the fact that arguments to
breakpointLocations are not optional, even though the spec says they
are.
|
|
In gdb/tui/tui-layout.c, we have:
...
static window_types_map known_window_types;
...
and in gdb/python/py-tui.c:
...
/* A global list of all gdbpy_tui_window_maker objects. */
static intrusive_list<gdbpy_tui_window_maker> m_window_maker_list;
};
/* See comment in class declaration above. */
intrusive_list<gdbpy_tui_window_maker>
gdbpy_tui_window_maker::m_window_maker_list;
...
With a gdb build with -O0 or -O2, the static destructor calling order seems to be:
- first gdb/tui/tui-layout.c,
- then gdb/python/py-tui.c.
So when running test-case gdb.python/tui-window-factory.exp, we see the
following order of events:
- the destructor for known_window_types is called, which triggers calling the
destructor for the only element E of m_window_maker_list. The destructor
destroys E, and also removes E from m_window_maker_list, leaving it empty.
- the destructor for m_window_maker_list is called. It's empty, so it's a nop.
However, when building gdb with -O2 -flto=auto, the static destructor calling
order seems to be reversed.
Instead, we have these events:
- the destructor for m_window_maker_list is called. This doesn't destroy it's
only element E, but it does make m_window_maker_list empty.
- the destructor for known_window_types is called, which triggers calling the
destructor for E. An attempt is done to remove E from m_window_maker_list,
but we run into an assertion failure, because the list is empty.
Fix this by checking is_linked () before attempting to remove from
m_window_maker_list, similar to how things were addressed in commit 995a34b1772
("Guard against frame.c destructors running before frame-info.c's").
Tested on x86_64-linux.
PR tui/30646
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30646
|