Age | Commit message (Collapse) | Author | Files | Lines |
|
Fix a few typos:
- implemention -> implementation
- convertion(s) -> conversion(s)
- backlashes -> backslashes
- signoring -> ignoring
- (un)ambigious -> (un)ambiguous
- occured -> occurred
- hidding -> hiding
- temporarilly -> temporarily
- immediatelly -> immediately
- sillyness -> silliness
- similiar -> similar
- porkuser -> pokeuser
- thats -> that
- alway -> always
- supercede -> supersede
- accomodate -> accommodate
- aquire -> acquire
- priveleged -> privileged
- priviliged -> privileged
- priviledges -> privileges
- privilige -> privilege
- recieve -> receive
- (p)refered -> (p)referred
- succesfully -> successfully
- successfuly -> successfully
- responsability -> responsibility
- wether -> whether
- wich -> which
- disasbleable -> disableable
- descriminant -> discriminant
- construcstor -> constructor
- underlaying -> underlying
- underyling -> underlying
- structureal -> structural
- appearences -> appearances
- terciarily -> tertiarily
- resgisters -> registers
- reacheable -> reachable
- likelyhood -> likelihood
- intepreter -> interpreter
- disassemly -> disassembly
- covnersion -> conversion
- conviently -> conveniently
- atttribute -> attribute
- struction -> struct
- resonable -> reasonable
- popupated -> populated
- namespaxe -> namespace
- intialize -> initialize
- identifer(s) -> identifier(s)
- expection -> exception
- exectuted -> executed
- dungerous -> dangerous
- dissapear -> disappear
- completly -> completely
- (inter)changable -> (inter)changeable
- beakpoint -> breakpoint
- automativ -> automatic
- alocating -> allocating
- agressive -> aggressive
- writting -> writing
- reguires -> requires
- registed -> registered
- recuding -> reducing
- opeartor -> operator
- ommitted -> omitted
- modifing -> modifying
- intances -> instances
- imbedded -> embedded
- gdbaarch -> gdbarch
- exection -> execution
- direcive -> directive
- demanged -> demangled
- decidely -> decidedly
- argments -> arguments
- agrument -> argument
- amespace -> namespace
- targtet -> target
- supress(ed) -> suppress(ed)
- startum -> stratum
- squence -> sequence
- prompty -> prompt
- overlow -> overflow
- memember -> member
- languge -> language
- geneate -> generate
- funcion -> function
- exising -> existing
- dinking -> syncing
- destroh -> destroy
- clenaed -> cleaned
- changep -> changedp (name of variable)
- arround -> around
- aproach -> approach
- whould -> would
- symobl -> symbol
- recuse -> recurse
- outter -> outer
- freeds -> frees
- contex -> context
Tested on x86_64-linux.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This simplifies auto_load_expand_dir_vars to first split the string,
then do any needed substitutions. This was suggested by Simon, and is
much simpler than the current approach.
Then this patch also removes substitute_path_component, as it is no
longer called. This is nice because it helps with the long term goal
of removing utils.h.
Regression tested on x86-64 Fedora 36.
|
|
I noticed a few unit tests are using gdb_assert. I think this was an
older style, before SELF_CHECK was added. This patch switches them
over.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
This adds some operators and methods to gdb_mpq, in preparation for
making its implementation private.
This only adds the operators currently needed by gdb. More could be
added as necessary.
|
|
This adds various methods and operators to gdb_mpz, as a step toward
hiding the implementation.
This only adds the operators that were needed. Many more could be
added as required.
|
|
gmp-utils.h includes "defs.h", but normally the rule in gdb is that
the .c files include this first. This patch changes this code to
match the rest of gdb.
|
|
Replace spaces with tabs in a bunch of places.
Change-Id: If0f87180f1d13028dc178e5a8af7882a067868b0
|
|
The copyright years in the ROCm files (e.g. solib-rocm.c) are wrong,
they end in 2022 instead of 2023. I suppose because I posted (or at
least prepared) the patches in 2022 but merged them in 2023, and forgot
to update the year. I found a bunch of other files that are in the same
situation. Fix them all up.
Change-Id: Ia55f5b563606c2ba6a89046f22bc0bf1c0ff2e10
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This commit introduces shared infrastructure that can be used to
implement enum_flags -> to_string functions. With this, if we want to
support converting a given enum_flags specialization to string, we
just need to implement a function that provides the enumerator->string
mapping, like so:
enum some_flag
{
SOME_FLAG1 = 1 << 0,
SOME_FLAG2 = 1 << 1,
SOME_FLAG3 = 1 << 2,
};
DEF_ENUM_FLAGS_TYPE (some_flag, some_flags);
static std::string
to_string (some_flags flags)
{
static constexpr some_flags::string_mapping mapping[] = {
MAP_ENUM_FLAG (SOME_FLAG1),
MAP_ENUM_FLAG (SOME_FLAG2),
MAP_ENUM_FLAG (SOME_FLAG3),
};
return flags.to_string (mapping);
}
.. and then to_string(SOME_FLAG2 | SOME_FLAG3) produces a string like
"0x6 [SOME_FLAG2 SOME_FLAG3]".
If we happen to forget to update the mapping array when we introduce a
new enumerator, then the string representation will pretty-print the
flags it knows about, and then the leftover flags in hex (one single
number). For example, if we had missed mapping SOME_FLAG2 above, we'd
end up with:
to_string(SOME_FLAG2 | SOME_FLAG3) => "0x6 [SOME_FLAG2 0x4]");
Other than in the unit tests included, no actual usage of the
functionality is added in this commit.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I835de43c33d13bc0c95132f42c3f97318b875779
|
|
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 patch teaches frame_info_ptr to reinflate user-created frames
(frames created through create_new_frame, with the "select-frame view"
command).
Before this patch, frame_info_ptr doesn't support reinflating
user-created frames, because it currently reinflates by getting the
current target frame (for frame 0) or frame_find_by_id (for other
frames). To reinflate a user-created frame, we need to call
create_new_frame, to make it lookup an existing user-created frame, or
otherwise create one.
So, in prepare_reinflate, get the frame id even if the frame has level
0, if it is user-created. In reinflate, if the saved frame id is user
create it, call create_new_frame.
In order to test this, I initially enhanced the gdb.base/frame-view.exp
test added by the previous patch by setting a pretty-printer for the
type of the function parameters, in which we do an inferior call. This
causes print_frame_args to not reinflate its frame (which is a
user-created one) properly. On one machine (my Arch Linux one), it
properly catches the bug, as the frame is not correctly restored after
printing the first parameter, so it messes up the second parameter:
frame
#0 baz (z1=hahaha, z2=<error reading variable: frame address is not available.>) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:40
40 return z1.m + z2.n;
(gdb) FAIL: gdb.base/frame-view.exp: with_pretty_printer=true: frame
frame
#0 baz (z1=hahaha, z2=<error reading variable: frame address is not available.>) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:40
40 return z1.m + z2.n;
(gdb) FAIL: gdb.base/frame-view.exp: with_pretty_printer=true: frame again
However, on another machine (my Ubuntu 22.04 one), it just passes fine,
without the appropriate fix. I then thought about writing a selftest
for that, it's more reliable. I left the gdb.base/frame-view.exp pretty
printer test there, it's already written, and we never know, it might
catch some unrelated issue some day.
Change-Id: I5849baf77991fc67a15bfce4b5e865a97265b386
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
|
|
I found that parallel_for_each would submit empty tasks to the thread
pool. For example, this can happen if the number of tasks is smaller
than the number of available threads. In the DWARF reader, this
resulted in the cooked index containing empty sub-indices. This patch
arranges to instead shrink the result vector and process the trailing
entries in the calling thread.
|
|
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.
|
|
The passed in string can't be nullptr, it makes more sense to pass in a
reference.
Change-Id: Idc8bd38abe1d6d9b44aa227d7856956848c233b3
|
|
Gnulib generates a warning if the system version of certain functions
are used (to redirect the developer to use Gnulib version). It caused a
compiler error when...
- Compiled with Clang
- -Werror is specified (by default)
- C++ standard used by Clang is before C++17 (by default as of 15.0.0)
when this unit test is activated.
This issue is raised as PR28413.
However, previous proposal to fix this issue (a "fix" to Gnulib):
<https://lists.gnu.org/archive/html/bug-gnulib/2021-10/msg00003.html>
was rejected because it ruins the intent of Gnulib warnings.
So, we need a Binutils/GDB-side solution.
This commit tries to address this issue on the GDB side. We have
"include/diagnostics.h" to disable certain warnings only when necessary.
This commit suppresses the Gnulib warnings by surrounding entire #include
block with DIAGNOSTIC_IGNORE_USER_DEFINED_WARNINGS to disable Gnulib-
generated warnings on all standard C++ header files.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28413
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ieeb5a31a6902808d4c7263a2868ae19a35e0ccaa
|
|
When running selftest run_on_main_thread and pressing ^C, we can run into:
...
Running selftest run_on_main_thread.
terminate called without an active exception
Fatal signal: Aborted
...
The selftest function looks like this:
...
static void
run_tests ()
{
std::thread thread;
done = false;
{
gdb::block_signals blocker;
thread = std::thread (set_done);
}
while (!done && gdb_do_one_event () >= 0)
;
/* Actually the test will just hang, but we want to test
something. */
SELF_CHECK (done);
thread.join ();
}
...
The error message we see is due to the destructor of thread being called while
thread is joinable.
This is supposed to be taken care of by thread.join (), but the ^C prevents
that one from being called, while the destructor is still called.
Fix this by ensuring thread.join () is called (if indeed required) before the
destructor using SCOPE_EXIT.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29549
|
|
With commit 18a5766d09c ("[gdbsupport] Add sequential_for_each") I added a
drop-in replacement for gdb::parallel_for_each, but there's nothing making
sure that the two remain in sync.
Extend the unit test for gdb::parallel_for_each to test both.
Do this using a slightly unusual file-self-inclusion. Doing so keep things
readable and maintainable, and avoids macrofying functions.
Tested on x86_64-linux.
|
|
Add a task_size parameter to parallel_for_each, defaulting to nullptr, and use
the task size to distribute similarly-sized chunks to the threads.
Tested on x86_64-linux.
|
|
This adds gdb::make_function_view, which lets you create a function
view from a callable without specifying the function_view's template
parameter. For example, this:
auto lambda = [&] (int) { ... };
auto fv = gdb::make_function_view (lambda);
instead of:
auto lambda = [&] (int) { ... };
gdb::function_view<void (int)> fv = lambda;
It is particularly useful if you have a template function with an
optional function_view parameter, whose type depends on the function's
template parameters. Like:
template<typename T>
void my_function (T v, gdb::function_view<void(T)> callback = nullptr);
For such a function, the type of the callback argument you pass must
already be a function_view. I.e., this wouldn't compile:
auto lambda = [&] (int) { ... };
my_function (1, lambda);
With gdb::make_function_view, you can write the call like so:
auto lambda = [&] (int) { ... };
my_function (1, gdb::make_function_view (lambda));
Unit tests included.
Tested by building with GCC 9.4, Clang 10, and GCC 4.8.5, on x86_64
GNU/Linux, and running the unit tests.
Change-Id: I5c4b3b4455ed6f0d8878cf1be189bea3ee63f626
|
|
For PR gdb/29373, I wrote an alternative implementation of struct
packed that uses a gdb_byte array for internal representation, needed
for mingw+clang. While adding that, I wrote some unit tests to make
sure both implementations behave the same. While at it, I implemented
all relational operators. This commit adds said unit tests and
relational operators. The alternative gdb_byte array implementation
will come next.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29373
Change-Id: I023315ee03622c59c397bf4affc0b68179c32374
|
|
Add a unit test that verifies that we can call gdb::parallel_for_each with an
empty range.
Tested on x86_64-linux.
|
|
In this review [1], Eli pointed out that we should be careful when
concatenating file names to avoid duplicated slashes. On Windows, a
double slash at the beginning of a file path has a special meaning. So
naively concatenating "/" and "foo/bar" would give "//foo/bar", which
would not give the desired results. We already have a few spots doing:
if (first_path ends with a slash)
path = first_path + second_path
else
path = first_path + slash + second_path
In general, I think it's nice to avoid superfluous slashes in file
paths, since they might end up visible to the user and look a bit
unprofessional.
Introduce the path_join function that can be used to join multiple path
components together (along with unit tests).
I initially wanted to make it possible to join two absolute paths, to
support the use case of prepending a sysroot path to a target file path,
or the prepending the debug-file-directory to a target file path. But
the code in solib_find_1 shows that it is more complex than this anyway
(for example, when the right hand side is a Windows path with a drive
letter). So I don't think we need to support that case in path_join.
That also keeps the implementation simpler.
Change a few spots to use path_join to show how it can be used. I
believe that all the spots I changed are guarded by some checks that
ensure the right hand side operand is not an absolute path.
Regression-tested on Ubuntu 18.04. Built-tested on Windows, and I also
ran the new unit-test there.
[1] https://sourceware.org/pipermail/gdb-patches/2022-April/187559.html
Change-Id: I0df889f7e3f644e045f42ff429277b732eb6c752
|
|
parallel_for_each currently requires each thread to process at least
10 elements. However, when indexing, it's fine for a thread to handle
just a single CU. This patch parameterizes this, and updates the one
user.
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the printf family of functions. This is done under the name
"gdb_printf". Most of this patch was written by script.
|
|
This commit adds operator+= and operator+ overloads for adding
gdb::unique_xmalloc_ptr<char> to a std::string. I could only find 3
places in GDB where this was useful right now, and these all make use
of operator+=.
I've also added a self test for gdb::unique_xmalloc_ptr<char>, which
makes use of both operator+= and operator+, so they are both getting
used/tested.
There should be no user visible changes after this commit, except when
running 'maint selftest', where the new self test is visible.
|
|
In an earlier version of the pager rewrite series, it was important to
audit unfiltered output calls to see which were truly necessary.
This is no longer necessary, but it still seems like a decent cleanup
to change calls to avoid explicitly passing gdb_stdout. That is,
rather than using something like fprintf_unfiltered with gdb_stdout,
the code ought to use plain printf_unfiltered instead.
This patch makes this change. I went ahead and converted all the
_filtered calls I could find, as well, for the same clarity.
|
|
In my tour of the ui_file subsystem, I found that fputstr and fputstrn
can be simplified. The _filtered forms are never used (and IMO
unlikely to ever be used) and so can be removed. And, the interface
can be simplified by removing a callback function and moving the
implementation directly to ui_file.
A new self-test is included. Previously, I think nothing was testing
this code.
Regression tested on x86-64 Fedora 34.
|
|
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.
For the avoidance of doubt, all changes in this commits were
performed by the script.
|
|
I think it would make sense for extract_integer, extract_signed_integer
and extract_unsigned_integer to take an array_view. This way, when we
extract an integer, we can validate that we don't overflow the buffer
passed by the caller (e.g. ask to extract a 4-byte integer but pass a
2-byte buffer).
- Change extract_integer to take an array_view
- Add overloads of extract_signed_integer and extract_unsigned_integer
that take array_views. Keep the existing versions so we don't
need to change all callers, but make them call the array_view
versions.
This shortens some places like:
result = extract_unsigned_integer (value_contents (result_val).data (),
TYPE_LENGTH (value_type (result_val)),
byte_order);
into
result = extract_unsigned_integer (value_contents (result_val), byte_order);
value_contents returns an array view that is of length
`TYPE_LENGTH (value_type (result_val))` already, so the length is
implicitly communicated through the array view.
Change-Id: Ic1c1f98c88d5c17a8486393af316f982604d6c95
|
|
An assertion was recently added to array_view::operator[] to ensure we
don't do out of bounds accesses. However, when the array_view is copied
to or from using memcpy, it bypasses that safety.
To address this, add a `copy` free function that copies data from an
array view to another, ensuring that the destination and source array
views have the same size. When copying to or from parts of an
array_view, we are expected to use gdb::array_view::slice, which does
its own bounds check. With all that, any copy operation that goes out
of bounds should be caught by an assertion at runtime.
copy is implemented using std::copy and std::copy_backward, which, at
least on libstdc++, appears to pick memmove when copying trivial data.
So in the end there shouldn't be much difference vs using a bare memcpy,
as we do right now. When copying non-trivial data, std::copy and
std::copy_backward assigns each element in a loop.
To properly support overlapping ranges, we must use std::copy or
std::copy_backward, depending on whether the destination is before the
source or vice-versa. std::copy and std::copy_backward don't support
copying exactly overlapping ranges (where the source range is equal to
the destination range). But in this case, no copy is needed anyway, so
we do nothing.
The order of parameters of the new copy function is based on std::copy
and std::copy_backward, where the source comes before the destination.
Change a few randomly selected spots to use the new function, to show
how it can be used.
Add a test for the new function, testing both with arrays of a trivial
type (int) and of a non-trivial type (foo). Test non-overlapping
ranges as well as three kinds of overlapping ranges: source before dest,
dest before source, and dest == source.
Change-Id: Ibeaca04e0028410fd44ce82f72e60058d6230a03
|
|
I would like to print target_waitkind values in debug messages, so I
think that a target_waitkind-to-string function would be useful. While
at it, use it in target_waitstatus::to_string. This changes the output
of target_waitstatus::to_string a bit, but I think it is for the better.
The debug messages will show a string matching exactly the
target_waitkind enumerator (minus the TARGET_WAITKIND prefix).
As a convenience, make string_appendf return the same reference to
string it got as a parameter. This allows doing this:
return string_appendf (str, "foo");
... keeping the code concise.
Change-Id: I383dffc9c78614e7d0668b1516073905e798eef7
|
|
When building with g++ 4.8, I get:
CXX unittests/array-view-selftests.o
/home/smarchi/src/binutils-gdb/gdb/unittests/array-view-selftests.c:123:42: error: expected 'class' before 'Container'
template<template<typename ...> typename Container>
^
I am no C++ template expert, but it looks like if I change "typename" for
"class", as the compiler kind of suggests, the code compiles.
Change-Id: I9c3edd29fb2b190069f0ce0dbf3bc3604d175f48
|
|
Change-Id: I2141b0b8a09f6521a59908599eb5ba1a19b18dc6
|
|
While reading the interface of gdb::array_view, I realized that the
constructor that builds an array_view on top of a contiguous container
(such as std::vector, std::array or even gdb::array_view) can be
missused.
Lets consider the following code sample:
struct Parent
{
Parent (int a): a { a } {}
int a;
};
std::ostream &operator<< (std::ostream& os, const Parent & p)
{ os << "Parent {a=" << p.a << "}"; return os; }
struct Child : public Parent
{
Child (int a, int b): Parent { a }, b { b } {}
int b;
};
std::ostream &operator<< (std::ostream& os, const Child & p)
{ os << "Child {a=" << p.a << ", b=" << p.b << "}"; return os; }
template <typename T>
void print (const gdb::array_view<const T> &p)
{
std::for_each (p.begin (), p.end (), [](const T &p) { std::cout << p << '\n'; });
}
Then with the current interface nothinng prevents this usage of
array_view to be done:
const std::array<Child, 3> elts = {
Child {1, 2},
Child {3, 4},
Child {5, 6}
};
print_all<Parent> (elts);
This compiles fine and produces the following output:
Parent {a=1}
Parent {a=2}
Parent {a=3}
which is obviously wrong. There is nowhere in memory a Parent-like
object for which the A member is 2 and this call to print_all<Parent>
shold not compile at all (calling print_all<Child> is however fine).
This comes down to the fact that a Child* is convertible into a Parent*,
and that an array view is constructed to a pointer to the first element
and a size. The valid type pointed to that can be used with this
constructor are restricted using SFINAE, which requires that a
pointer to a member into the underlying container can be converted into a
pointer the array_view's data type.
This patch proposes to change the constraints on the gdb::array_view
ctor which accepts a container now requires that the (decayed) type of
the elements in the container match the (decayed) type of the array_view
being constructed.
Applying this change required minimum adjustment in GDB codebase, which
are also included in this patch.
Tested by rebuilding.
|
|
The format_pieces selftest currently fails on Windows hosts.
The selftest doesn't handle the "%ll" -> "%I64" rewrite that the
formatter may perform, but also gdbsupport was missing a configure
check for PRINTF_HAS_LONG_LONG. This patch fixes both issues.
|
|
This encourages the callers to use automatic file descriptor management.
Change-Id: I137a81df6f3607b457e28c35aafde8ed6f3a3344
|
|
Change register_test to use std::function arg, such that we can do:
...
register_test (test_name, [=] () { SELF_CHECK (...); });
...
Tested on x86_64-linux.
|
|
Like Tom de Vries' earlier patch to fix the no-CXX_STD_THREAD case in
maint.c, this patch fixes a similar problem in
parallel-for-selftests.c. This fixes a build failure on Windows.
|
|
We get this error when building GDB on some platforms. I get it using
g++-10 on Ubuntu 20.04 (installed using the distro package). It was
also reported by John Baldwin, using a clang that uses libc++.
CXX unittests/parallel-for-selftests.o
cc1plus: warning: command line option '-Wmissing-prototypes' is valid for C/ObjC but not for C++
/home/smarchi/src/binutils-gdb/gdb/unittests/parallel-for-selftests.c: In function 'void selftests::parallel_for::test(int)':
/home/smarchi/src/binutils-gdb/gdb/unittests/parallel-for-selftests.c:53:30: error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
53 | std::atomic<int> counter = 0;
| ^
In file included from /usr/include/c++/9/future:42,
from /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/thread-pool.h:29,
from /home/smarchi/src/binutils-gdb/gdb/../gdbsupport/parallel-for.h:26,
from /home/smarchi/src/binutils-gdb/gdb/unittests/parallel-for-selftests.c:22:
/usr/include/c++/9/atomic:755:7: note: declared here
755 | atomic(const atomic&) = delete;
| ^~~~~~
/usr/include/c++/9/atomic:759:17: note: after user-defined conversion: 'constexpr std::atomic<int>::atomic(std::atomic<int>::__integral_type)'
759 | constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
| ^~~~~~
I haven't dug to know why it does not happen everywhere, but this patch
fixes it by using the constructor to initialize the variable, rather
than the assignment operator.
Change-Id: I6b27958171bf6187f6a875657395fd10441db7e6
|
|
Tom de Vries noticed that a patch in the DWARF scanner rewrite series
caused a regression in parallel_for_each -- it started crashing in the
case where the number of threads is 0 (there was an unchecked use of
"n-1" that was used to size an array).
He also pointed out that there were no tests of parallel_for_each.
This adds a few tests of parallel_for_each, primarily testing that
different settings for the number of threads will work. This test
catches the bug that he found in that series.
|
|
The threads that need a step-over are currently linked using an
hand-written intrusive doubly-linked list, so that seems a very good
candidate for intrusive_list, convert it.
For this, we have a use case of appending a list to another one (in
start_step_over). Based on the std::list and Boost APIs, add a splice
method. However, only support splicing the other list at the end of the
`this` list, since that's all we need.
Add explicit default assignment operators to
reference_to_pointer_iterator, which are otherwise implicitly deleted.
This is needed because to define thread_step_over_list_safe_iterator, we
wrap reference_to_pointer_iterator inside a basic_safe_iterator, and
basic_safe_iterator needs to be able to copy-assign the wrapped
iterator. The move-assignment operator is therefore not needed, only
the copy-assignment operator is. But for completeness, add both.
Change-Id: I31b2ff67c7b78251314646b31887ef1dfebe510c
|
|
GDB currently has several objects that are put in a singly linked list,
by having the object's type have a "next" pointer directly. For
example, struct thread_info and struct inferior. Because these are
simply-linked lists, and we don't keep track of a "tail" pointer, when
we want to append a new element on the list, we need to walk the whole
list to find the current tail. It would be nice to get rid of that
walk. Removing elements from such lists also requires a walk, to find
the "previous" position relative to the element being removed. To
eliminate the need for that walk, we could make those lists
doubly-linked, by adding a "prev" pointer alongside "next". It would be
nice to avoid the boilerplate associated with maintaining such a list
manually, though. That is what the new intrusive_list type addresses.
With an intrusive list, it's also possible to move items out of the
list without destroying them, which is interesting in our case for
example for threads, when we exit them, but can't destroy them
immediately. We currently keep exited threads on the thread list, but
we could change that which would simplify some things.
Note that with std::list, element removal is O(N). I.e., with
std::list, we need to walk the list to find the iterator pointing to
the position to remove. However, we could store a list iterator
inside the object as soon as we put the object in the list, to address
it, because std::list iterators are not invalidated when other
elements are added/removed. However, if you need to put the same
object in more than one list, then std::list<object> doesn't work.
You need to instead use std::list<object *>, which is less efficient
for requiring extra memory allocations. For an example of an object
in multiple lists, see the step_over_next/step_over_prev fields in
thread_info:
/* Step-over chain. A thread is in the step-over queue if these are
non-NULL. If only a single thread is in the chain, then these
fields point to self. */
struct thread_info *step_over_prev = NULL;
struct thread_info *step_over_next = NULL;
The new intrusive_list type gives us the advantages of an intrusive
linked list, while avoiding the boilerplate associated with manually
maintaining it.
intrusive_list's API follows the standard container interface, and thus
std::list's interface. It is based the API of Boost's intrusive list,
here:
https://www.boost.org/doc/libs/1_73_0/doc/html/boost/intrusive/list.html
Our implementation is relatively simple, while Boost's is complicated
and intertwined due to a lot of customization options, which our version
doesn't have.
The easiest way to use an intrusive_list is to make the list's element
type inherit from intrusive_node. This adds a prev/next pointers to
the element type. However, to support putting the same object in more
than one list, intrusive_list supports putting the "node" info as a
field member, so you can have more than one such nodes, one per list.
As a first guinea pig, this patch makes the per-inferior thread list use
intrusive_list using the base class method.
Unlike Boost's implementation, ours is not a circular list. An earlier
version of the patch was circular: the intrusive_list type included an
intrusive_list_node "head". In this design, a node contained pointers
to the previous and next nodes, not the previous and next elements.
This wasn't great for when debugging GDB with GDB, as it was difficult
to get from a pointer to the node to a pointer to the element. With the
design proposed in this patch, nodes contain pointers to the previous
and next elements, making it easy to traverse the list by hand and
inspect each element.
The intrusive_list object contains pointers to the first and last
elements of the list. They are nullptr if the list is empty.
Each element's node contains a pointer to the previous and next
elements. The first element's previous pointer is nullptr and the last
element's next pointer is nullptr. Therefore, if there's a single
element in the list, both its previous and next pointers are nullptr.
To differentiate such an element from an element that is not linked into
a list, the previous and next pointers contain a special value (-1) when
the node is not linked. This is necessary to be able to reliably tell
if a given node is currently linked or not.
A begin() iterator points to the first item in the list. An end()
iterator contains nullptr. This makes iteration until end naturally
work, as advancing past the last element will make the iterator contain
nullptr, making it equal to the end iterator. If the list is empty,
a begin() iterator will contain nullptr from the start, and therefore be
immediately equal to the end.
Iterating on an intrusive_list yields references to objects (e.g.
`thread_info&`). The rest of GDB currently expects iterators and ranges
to yield pointers (e.g. `thread_info*`). To bridge the gap, add the
reference_to_pointer_iterator type. It is used to define
inf_threads_iterator.
Add a Python pretty-printer, to help inspecting intrusive lists when
debugging GDB with GDB. Here's an example of the output:
(top-gdb) p current_inferior_.m_obj.thread_list
$1 = intrusive list of thread_info = {0x61700002c000, 0x617000069080, 0x617000069400, 0x61700006d680, 0x61700006eb80}
It's not possible with current master, but with this patch [1] that I
hope will be merged eventually, it's possible to index the list and
access the pretty-printed value's children:
(top-gdb) p current_inferior_.m_obj.thread_list[1]
$2 = (thread_info *) 0x617000069080
(top-gdb) p current_inferior_.m_obj.thread_list[1].ptid
$3 = {
m_pid = 406499,
m_lwp = 406503,
m_tid = 0
}
Even though iterating the list in C++ yields references, the Python
pretty-printer yields pointers. The reason for this is that the output
of printing the thread list above would be unreadable, IMO, if each
thread_info object was printed in-line, since they contain so much
information. I think it's more useful to print pointers, and let the
user drill down as needed.
[1] https://sourceware.org/pipermail/gdb-patches/2021-April/178050.html
Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I3412a14dc77f25876d742dab8f44e0ba7c7586c0
|
|
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
* Makefile.in (SELFTESTS_SRCS): Add
unittests/scoped_ignore_signal-selftests.c.
* unittests/scoped_ignore_signal-selftests.c: New.
Change-Id: Idce24aa9432a3f1eb7065bc9aa030b1d0d7dcad5
|
|
Same idea as the previous patch, but for prefix instead of alias.
gdb/ChangeLog:
* cli/cli-decode.h (cmd_list_element) <is_prefix>: New, use it.
Change-Id: I76a9d2e82fc8d7429904424674d99ce6f9880e2b
|
|
Add the cmd_list_element::is_alias helper to check whether a command is
an alias. I find it easier to understand the intention in:
if (c->is_alias ())
than
if (c->alias_target != nullptr)
Change all the spots that are reading alias_target just to compare it to
NULL/nullptr to use is_alias instead.
gdb/ChangeLog:
* cli/cli-decode.h (cmd_list_element) <is_alias>: New, use it.
Change-Id: I26ed56f99ee47fe884fdfedf87016501631693ce
|
|
cmd_pointer is another field whose name I found really not clear. Yes,
it's a pointer to a command, the type tells me that. But what's the
relationship of that command to the current command? This field
contains, for an alias, the command that it aliases. So I think that
the name "alias_target" would be more appropriate.
Also, rename "old" parameters to "target" in the functions that add
aliases.
gdb/ChangeLog:
* cli/cli-decode.h (cmd_list_element) <cmd_pointer>: Rename
to...
<alias_target>: ... this.
(add_alias_cmd): Rename old to target.
(add_info_alias): Rename old_name to target_name.
(add_com_alias): Likewise.
Change-Id: I8db36c6dd799fae155f7acd3805f6d62d98befa9
|
|
While browsing this code, I found the name "prefixlist" really
confusing. I kept reading it as "list of prefixes". Which it isn't:
it's a list of sub-commands, for a prefix command. I think that
renaming it to "subcommands" would make things clearer.
gdb/ChangeLog:
* Rename "prefixlist" parameters to "subcommands" throughout.
* cli/cli-decode.h (cmd_list_element) <prefixlist>: Rename to...
<subcommands>: ... this.
* cli/cli-decode.c (lookup_cmd_for_prefixlist): Rename to...
(lookup_cmd_with_subcommands): ... this.
Change-Id: I150da10d03052c2420aa5b0dee41f422e2a97928
|
|
Previously, the prefixname field of struct cmd_list_element was manually
set for prefix commands. This seems verbose and error prone as it
required every single call to functions adding prefix commands to
specify the prefix name while the same information can be easily
generated.
Historically, this was not possible as the prefix field was null for
many commands, but this was fixed in commit
3f4d92ebdf7f848b5ccc9e8d8e8514c64fde1183 by Philippe Waroquiers, so
we can rely on the prefix field being set when generating the prefix
name.
This commit also fixes a use after free in this scenario:
* A command gets created via Python (using the gdb.Command class).
The prefix name member is dynamically allocated.
* An alias to the new command is created. The alias's prefixname is set
to point to the prefixname for the original command with a direct
assignment.
* A new command with the same name as the Python command is created.
* The object for the original Python command gets freed and its
prefixname gets freed as well.
* The alias is updated to point to the new command, but its prefixname
is not updated so it keeps pointing to the freed one.
gdb/ChangeLog:
* command.h (add_prefix_cmd): Remove the prefixname argument as
it can now be generated automatically. Update all callers.
(add_basic_prefix_cmd): Ditto.
(add_show_prefix_cmd): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_abbrev_prefix_cmd): Ditto.
* cli/cli-decode.c (add_prefix_cmd): Ditto.
(add_basic_prefix_cmd): Ditto.
(add_show_prefix_cmd): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_abbrev_prefix_cmd): Ditto.
* cli/cli-decode.h (struct cmd_list_element): Replace the
prefixname member variable with a method which generates the
prefix name at runtime. Update all code reading the prefix
name to use the method, and remove all code setting it.
* python/py-cmd.c (cmdpy_destroyer): Remove code to free the
prefixname member as it's now a method.
(cmdpy_function): Determine if the command is a prefix by
looking at prefixlist, not prefixname.
|
|
Previously, the observers attached to an observable were always notified
in the order in which they had been attached. That order is not easily
controlled, because observers are typically attached in _initialize_*
functions, which are called in an undefined order.
However, an observer may require that another observer attached only
later is called before itself is.
Therefore, extend the 'observable' class to allow explicitly specifying
dependencies when attaching observers, by adding the possibility to
specify tokens for observers that it depends on.
To make sure dependencies are notified before observers depending on
them, the vector holding the observers is sorted in a way that
dependencies come before observers depending on them. The current
implementation for sorting uses the depth-first search algorithm for
topological sorting as described at [1].
Extend the observable unit tests to cover this case as well. Check that
this works for a few different orders in which the observers are
attached.
This newly introduced mechanism to explicitly specify dependencies will
be used in a follow-up commit.
[1] https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search
Tested on x86_64-linux (Debian testing).
gdb/ChangeLog:
* unittests/observable-selftests.c (dependency_test_counters):
New.
(observer_token0, observer_token1, observer_token2,
observer_token3, observer_token4, observer_token5): New.
(struct dependency_observer_data): New struct.
(observer_dependency_test_callback): New function.
(test_observers): New.
(run_dependency_test): New function.
(test_dependency): New.
(_initialize_observer_selftest): Register dependency test.
gdbsupport/ChangeLog:
* observable.h (class observable): Extend to allow specifying
dependencies between observers, keep vector holding observers
sorted so that dependencies are notified before observers
depending on them.
Change-Id: I5399def1eeb69ca99e28c9f1fdf321d78b530bdb
|