Age | Commit message (Collapse) | Author | Files | Lines |
|
Commit b5661ff2 ("gdb: fix possible use-after-free when
executing commands") used lookup_cmd_exact () to lookup
command again after its execution to avoid possible
use-after-free error.
However this change broke test gdb.base/define.exp which
defines a post-hook for subcommand ("target testsuite").
In this case, lookup_cmd_exact () returned NULL because
there's no command 'testsuite' in top-level commands.
This commit fixes this case by looking up the command again
using the original command line via lookup_cmd ().
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
[I sent this earlier today, but I don't see it in the archives.
Resending it through a different computer / SMTP.]
The use of the static buffer in command_line_input is becoming
problematic, as explained here [1]. In short, with this patch [2] that
attempt to fix a post-hook bug, when running gdb.base/commands.exp, we
hit a case where we read a "define" command line from a script file
using command_command_line_input. The command line is stored in
command_line_input's static buffer. Inside the define command's
execution, we read the lines inside the define using command_line_input,
which overwrites the define command, in command_line_input's static
buffer. After the execution of the define command, execute_command does
a command look up to see if a post-hook is registered. For that, it
uses a now stale pointer that used to point to the define command, in
the static buffer, causing a use-after-free. Note that the pointer in
execute_command points to the dynamically-allocated buffer help by the
static buffer in command_line_input, not to the static object itself,
hence why we see a use-after-free.
Fix that by removing the static buffer. I initially changed
command_line_input and other related functions to return an std::string,
which is the obvious but naive solution. The thing is that some callees
don't need to return an allocated string, so this this an unnecessary
pessimization. I changed it to passing in a reference to an std::string
buffer, which the callee can use if it needs to return
dynamically-allocated content. It fills the buffer and returns a
pointers to the C string inside. The callees that don't need to return
dynamically-allocated content simply don't use it.
So, it started with modifying command_line_input as described above, all
the other changes derive directly from that.
One slightly shady thing is in handle_line_of_input, where we now pass a
pointer to an std::string's internal buffer to readline's history_value
function, which takes a `char *`. I'm pretty sure that this function
does not modify the input string, because I was able to change it (with
enough massaging) to take a `const char *`.
A subtle change is that we now clear a UI's line buffer using a
SCOPE_EXIT in command_line_handler, after executing the command.
This was previously done by this line in handle_line_of_input:
/* We have a complete command line now. Prepare for the next
command, but leave ownership of memory to the buffer . */
cmd_line_buffer->used_size = 0;
I think the new way is clearer.
[1] https://inbox.sourceware.org/gdb-patches/becb8438-81ef-8ad8-cc42-fcbfaea8cddd@simark.ca/
[2] https://inbox.sourceware.org/gdb-patches/20221213112241.621889-1-jan.vrany@labware.com/
Change-Id: I8fc89b1c69870c7fc7ad9c1705724bd493596300
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This commit removes the global functions pop_all_targets,
pop_all_targets_above, and pop_all_targets_at_and_above, and makes
them methods on the inferior class.
As the pop_all_targets functions will unpush each target, which
decrements the targets reference count, it is possible that the target
might be closed.
Right now, closing a target, in some cases, depends on the current
inferior being set correctly, that is, to the inferior from which the
target was popped.
To facilitate this I have used switch_to_inferior_no_thread within the
new methods. Previously it was the responsibility of the caller to
ensure that the correct inferior was selected.
In a couple of places (event-top.c and top.c) I have been able to
remove a previous switch_to_inferior_no_thread call.
In remote_unpush_target (remote.c) I have left the
switch_to_inferior_no_thread call as it is required for the
generic_mourn_inferior call.
|
|
In principle, `execute_command()` does following:
struct cmd_list_element *c;
c = lookup_cmd ( ... );
...
/* If this command has been pre-hooked, run the hook first. */
execute_cmd_pre_hook (c);
...
/* ...execute the command `c` ...*/
...
execute_cmd_post_hook (c);
This may lead into use-after-free error. Imagine the command
being executed is a user-defined Python command that redefines
itself. In that case, struct `cmd_list_element` pointed to by
`c` is deallocated during its execution so it is no longer valid
when post hook is executed.
To fix this case, this commit looks up the command once again
after it is executed to get pointer to (possibly newly allocated)
`cmd_list_element`.
|
|
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
|
|
This changes 'struct ui' to use member initialization. This is
simpler to understand.
|
|
This changes ui_out_redirect_pop to also perform the redirection, and
then updates several sites to use this, rather than explicit
redirects.
|
|
A ui initializes its line_buffer, but never calls buffer_free on it.
This patch fixes the oversight. I found this by inspection.
|
|
I noticed a couple of initialization functions that aren't really
needed, and that currently require explicit calls in gdb_init. This
patch removes these functions, simplifying gdb a little.
Regression tested on x86-64 Fedora 34.
|
|
This changes the parameter of target_ops::async from int to bool.
Regression tested on x86-64 Fedora 34.
|
|
This replaces the global input_interactive_p function with a new
method ui::input_interactive_p.
|
|
After this commit:
commit d08cbc5d3203118da5583296e49273cf82378042
Date: Wed Dec 22 12:57:44 2021 +0000
gdb: unbuffer all input streams when not using readline
Issues were reported with some MS-Windows hosts, see the thread
starting here:
https://sourceware.org/pipermail/gdb-patches/2022-March/187004.html
Filed in bugzilla as: PR mi/29002
The problem seems to be that calling setbuf on terminal file handles
is not always acceptable, see this mail for more details:
https://sourceware.org/pipermail/gdb-patches/2022-April/187310.html
This commit does two things, first moving the setbuf calls out of
gdb_readline_no_editing_callback so that we don't end up calling
setbuf so often.
Then, for MS-Windows hosts, we don't call setbuf for terminals, this
appears to resolve the issues that have been reported.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29002
|
|
This commit replaces an earlier commit that worked around the issues
reported in bug PR gdb/28833.
The previous commit just implemented a work around in order to avoid
the worst results of the bug, but was not a complete solution. The
full solution was considered too risky to merge close to branching GDB
12. This improved fix has been applied after GDB 12 branched. See
this thread for more details:
https://sourceware.org/pipermail/gdb-patches/2022-March/186391.html
This commit replaces this earlier commit:
commit 74a159a420d4b466cc81061c16d444568e36740c
Date: Fri Mar 11 14:44:03 2022 +0000
gdb: work around prompt corruption caused by bracketed-paste-mode
Please read that commit for a full description of the bug, and why is
occurs.
In this commit I extend GDB to use readline's rl_deprep_term_function
hook to call a new function gdb_rl_deprep_term_function. From this
new function we can now print the 'quit' message, this replaces the
old printing of 'quit' in command_line_handler. Of course, we only
print 'quit' in gdb_rl_deprep_term_function when we are handling EOF,
but thanks to the previous commit (to readline) we now know when this
is.
There are two aspects of this commit that are worth further
discussion, the first is in the new gdb_rl_deprep_term_function
function. In here I have used a scoped_restore_tmpl to disable the
readline global variable rl_eof_found.
The reason for this is that, in rl_deprep_terminal, readline will
print an extra '\n' character before printing the escape sequence to
leave bracketed paste mode. You might then think that in the
gdb_rl_deprep_term_function function, we could simply print "quit" and
rely on rl_deprep_terminal to print the trailing '\n'. However,
rl_deprep_terminal only prints the '\n' when bracketed paste mode is
on. If the user has turned this feature off, no '\n' is printed.
This means that in gdb_rl_deprep_term_function we need to print
"quit" when bracketed paste mode is on, and "quit\n" when bracketed
paste mode is off.
We could absolutely do that, no problem, but given we know how
rl_deprep_terminal is implemented, it's easier (I think) to just
temporarily clear rl_eof_found, this prevents the '\n' being printed
from rl_deprep_terminal, and so in gdb_rl_deprep_term_function, we can
now always print "quit\n" and this works for all cases.
The second issue that should be discussed is backwards compatibility
with older versions of readline. GDB can be built against the system
readline, which might be older than the version contained within GDB's
tree. If this is the case then the system readline might not contain
the fixes needed to support correctly printing the 'quit' string.
To handle this situation I have retained the existing code in
command_line_handler for printing 'quit', however, this code is only
used now if the version of readline we are using doesn't not include
the required fixes. And so, if a user is using an older version of
readline, and they have bracketed paste mode on, then they will see
the 'quit' sting printed on the line below the prompt, like this:
(gdb)
quit
I think this is the best we can do when someone builds GDB against an
older version of readline.
Using a newer version of readline, or the patched version of readline
that is in-tree, will now give a result like this in all cases:
(gdb) quit
Which is what we want.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28833
|
|
I'm trying to switch these functions to use std::string instead of char
arrays, as much as possible. Some callers benefit from it (can avoid
doing a copy of the result), while others suffer (have to make one more
copy).
Change-Id: Iced49b8ee2f189744c5072a3b217aab5af17a993
|
|
This caused a build failure with !CXX_STD_THREAD.
Change-Id: I30f0c89c43a76f85c0db34809192644fa64a9d18
|
|
I noticed that GDB will display URLs in a few spots. This changes
them to be styled. Originally I thought I'd introduce a new "url"
style, but there aren't many places to use this, so I just reused
filename styling instead. This patch also changes the debuginfod URL
list to be printed one URL per line. I think this is probably a bit
easier to read.
|
|
A race condition in how patches were pushed causes this build failure:
CXX top.o
/home/simark/src/binutils-gdb/gdb/top.c: In function ‘void print_gdb_configuration(ui_file*)’:
/home/simark/src/binutils-gdb/gdb/top.c:1622:3: error: ‘fprintf_filtered’ was not declared in this scope; did you mean ‘printf_unfiltered’?
1622 | fprintf_filtered (stream, _("\
| ^~~~~~~~~~~~~~~~
fprintf_filtered has been removed, gdb_printf must be used now. Fix
this.
Change-Id: I6a172ba0d53dab2e7cc43ed0ed2696c82925245b
|
|
This includes the reporting of --enable/disable-threading as part of
the GDB configuration description.
|
|
I noticed that both gdbserver and gdb define current_directory.
However, as it is referenced by gdbsupport, it seemed better to define
it there as well. This patch also moves the declaration to
pathstuff.h. Tested by rebuilding.
|
|
Various spots in gdb currently know about the wrap buffer, and so are
careful to call wrap_here to be certain that all output has been
flushed.
Now that the pager is just an ordinary stream, this isn't needed, and
a simple call to gdb_flush is enough.
Similarly, there are places where gdb prints to gdb_stderr, but first
flushes gdb_stdout. stderr_file already flushes gdb_stdout, so these
aren't needed.
|
|
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 rewrites the output pager as a ui_file implementation.
A new header is introduced to declare the pager class. The
implementation remains in utils.c for the time being, because there
are some static globals there that must be used by this code. (This
could be cleaned up at some future date.)
I went through all the text output in gdb to ensure that this change
should be ok. There are a few cases:
* Any existing call to printf_unfiltered is required to be avoid the
pager. This is ensured directly in the implementation.
* All remaining calls to the f*_unfiltered functions -- the ones that
take an explicit ui_file -- either send to an unfiltered stream
(e.g., gdb_stderr), which is obviously ok; or conditionally send to
gdb_stdout
I investigated all such calls by searching for:
grep -e '\bf[a-z0-9_]*_unfiltered' *.[chyl] */*.[ch] | grep -v gdb_stdlog | grep -v gdb_stderr
This yields a number of candidates to check.
* The breakpoint _print_recreate family, and
save_trace_state_variables. These are used for "save" commands
and so are fine.
* Things printing to a temporary stream. Obviously ok.
* Disassembly selftests.
* print_gdb_help - this is non-obvious, but ok because paging isn't
yet enabled at this point during startup.
* serial.c - doens't use gdb_stdout
* The code in compile/. This is all printing to a file.
* DWARF DIE dumping - doesn't reference gdb_stdout.
* Calls to the _filtered form -- these are all clearly ok, because if
they are using gdb_stdout, then filtering will still apply; and if
not, then filtering never applied and still will not.
Therefore, at this point, there is no longer any distinction between
all the other _filtered and _unfiltered calls, and they can be
unified.
In this patch, take special note of the vfprintf_maybe_filtered and
ui_file::vprintf change. This is one instance of the above idea,
erasing the distinction between filtered and unfiltered -- in this
part of the change, the "unfiltered_output" flag is never passe to
cli_ui_out. Subsequent patches will go much further in this
direction.
Also note the can_emit_style_escape changes in ui-file.c. Checking
against gdb_stdout or gdb_stderr was always a bit of a hack; and now
it is no longer needed, because this is decision can be more fully
delegated to the particular ui_file implementation.
ui_file::can_page is removed, because this patch removed the only call
to it.
I think this is the main part of fixing PR cli/7234.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=7234
|
|
At the end of this series, the use of unfiltered output will be very
restricted -- only places that definitely need it will use it. To
this end, I thought it would be good to reduce the number of
_unfiltered APIs that are exposed. This patch changes gdb so that
only printf_unfiltered exists. (After this patch, the f* variants
still exist as well, but those will be removed later.)
|
|
Commit b60cea7 (Make target_wait options use enum flags) broke
deprecated_target_wait_hook usage: there's a commit comment telling
this hook has not been converted.
Rather than trying to mend it, this patch replaces the hook by two
target_wait observers:
target_pre_wait (ptid_t ptid)
target_post_wait (ptid_t event_ptid)
Upon target_wait entry, target_pre_wait is notified with the ptid
passed to target_wait. Upon exit, target_post_wait is notified with
the event ptid returned by target_wait. Should an exception occur,
event_ptid is null_ptid.
This change benefits to Insight (out-of-tree): there's no real use of the
late hook in gdb itself.
|
|
This changes all existing calls to wrap_here to call the method on the
appropriate ui_file instead. The choice of ui_file is determined by
context.
|
|
I think it only really makes sense to call wrap_here with an argument
consisting solely of spaces. Given this, it seemed better to me that
the argument be an int, rather than a string. This patch is the
result. Much of it was written by a script.
|
|
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.
|
|
Many otherwise ordinary commands choose to use unfiltered output
rather than filtered. I don't think there's any reason for this, so
this changes many such commands to use filtered output instead.
Note that complete_command is not touched due to a comment there
explaining why unfiltered output is believed to be used.
|
|
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.
|
|
This commit changes the copyright year printed by gdb, gdbserver
and gdbreplay when printing the tool's version.
|
|
The pattern for using execute_command_to_string is:
...
std::string output;
output = execute_fn_to_string (fn, term_out);
...
This results in a problem when using it in a try/catch:
...
try
{
output = execute_fn_to_string (fn, term_out)
}
catch (const gdb_exception &e)
{
/* Use output. */
}
...
If an expection was thrown during execute_fn_to_string, then the output
remains unassigned, while it could be worthwhile to known what output was
generated by gdb before the expection was thrown.
Fix this by returning the string using a parameter instead:
...
execute_fn_to_string (output, fn, term_out)
...
Also add a variant without string parameter, to support places where the
function is used while ignoring the result:
...
execute_fn_to_string (fn, term_out)
...
Tested on x86_64-linux.
|
|
Add a new event, gdb.events.gdb_exiting, which is called once GDB
decides it is going to exit.
This event is not triggered in the case that GDB performs a hard
abort, for example, when handling an internal error and the user
decides to quit the debug session, or if GDB hits an unexpected,
fatal, signal.
This event is triggered if the user just types 'quit' at the command
prompt, or if GDB is run with '-batch' and has processed all of the
required commands.
The new event type is gdb.GdbExitingEvent, and it has a single
attribute exit_code, which is the value that GDB is about to exit
with.
The event is triggered before GDB starts dismantling any of its own
internal state, so, my expectation is that most Python calls should
work just fine at this point.
When considering this functionality I wondered about using the
'atexit' Python module. However, this is triggered when the Python
environment is shut down, which is done from a final cleanup. At
this point we don't know for sure what other GDB state has already
been cleaned up.
|
|
String-like settings (var_string, var_filename, var_optional_filename,
var_string_noescape) currently take a pointer to a `char *` storage
variable (typically global) that holds the setting's value. I'd like to
"mordernize" this by changing them to use an std::string for storage.
An obvious reason is that string operations on std::string are often
easier to write than with C strings. And they avoid having to do any
manual memory management.
Another interesting reason is that, with `char *`, nullptr and an empty
string often both have the same meaning of "no value". String settings
are initially nullptr (unless initialized otherwise). But when doing
"set foo" (where `foo` is a string setting), the setting now points to
an empty string. For example, solib_search_path is nullptr at startup,
but points to an empty string after doing "set solib-search-path". This
leads to some code that needs to check for both to check for "no value".
Or some code that converts back and forth between NULL and "" when
getting or setting the value. I find this very error-prone, because it
is very easy to forget one or the other. With std::string, we at least
know that the variable is not "NULL". There is only one way of
representing an empty string setting, that is with an empty string.
I was wondering whether the distinction between NULL and "" would be
important for some setting, but it doesn't seem so. If that ever
happens, it would be more C++-y and self-descriptive to use
optional<string> anyway.
Actually, there's one spot where this distinction mattered, it's in
init_history, for the test gdb.base/gdbinit-history.exp. init_history
sets the history filename to the default ".gdb_history" if it sees that
the setting was never set - if history_filename is nullptr. If
history_filename is an empty string, it means the setting was explicitly
cleared, so it leaves it as-is. With the change to std::string, this
distinction doesn't exist anymore. This can be fixed by moving the code
that chooses a good default value for history_filename to
_initialize_top. This is ran before -ex commands are processed, so an
-ex command can then clear that value if needed (what
gdb.base/gdbinit-history.exp tests).
Another small improvement, in my opinion is that we can now easily
give string parameters initial values, by simply initializing the global
variables, instead of xstrdup-ing it in the _initialize function.
In Python and Guile, when registering a string-like parameter, we
allocate (with new) an std::string that is owned by the param_smob (in
Guile) and the parmpy_object (in Python) objects.
This patch started by changing all relevant add_setshow_* commands to
take an `std::string *` instead of a `char **` and fixing everything
that failed to build. That includes of course all string setting
variable and their uses.
string_option_def now uses an std::string also, because there's a
connection between options and settings (see
add_setshow_cmds_for_options).
The add_path function in source.c is really complex and twisted, I'd
rather not try to change it to work on an std::string right now.
Instead, I added an overload that copies the std:string to a `char *`
and back. This means more copying, but this is not used in a hot path
at all, so I think it is acceptable.
Change-Id: I92c50a1bdd8307141cdbacb388248e4e4fc08c93
Co-authored-by: Lancelot SIX <lsix@lancelotsix.com>
|
|
Make gdb_open_cloexec return a scoped_fd, to encourage using automatic
management of the file descriptor closing. Except in the most trivial
cases, I changed the callers to just release the fd, which retains their
existing behavior. That will allow the transition to using scoped_fd
more to go gradually, one caller at a time.
Change-Id: Ife022b403f96e71d5ebb4f1056ef6251b30fe554
|
|
When building gdb with "-Wall -O2 -g -flto=auto", I run into:
...
(gdb) call clear_complaints()^M
No symbol "clear_complaints" in current context.^M
(gdb) FAIL: gdb.gdb/complaints.exp: clear complaints
...
The problem is that lto has optimized away the clear_complaints function
and consequently the selftest doesn't work.
Fix this by reimplementing the selftest as a unit test.
Factor out two new functions:
- void
execute_fn_to_ui_file (struct ui_file *file, std::function<void(void)> fn);
- std::string
execute_fn_to_string (std::function<void(void)> fn, bool term_out);
and use the latter to capture the complaints output.
Tested on x86_64-linux.
|
|
The async_init_signals has, for some time, dealt with async and sync
signals, so removing the async prefix makes sense I think.
Additionally, as pointed out by Pedro:
.....
The comments relating to SIGTRAP and SIGQUIT within this function are
out of date.
The comments for SIGTRAP talk about the signal disposition (SIG_IGN)
being passed to the inferior, meaning the signal disposition being
inherited by GDB's fork children. However, we now call
restore_original_signals_state prior to forking, so the comment on
SIGTRAP is redundant.
The comments for SIGQUIT are similarly out of date, further, the
comment on SIGQUIT talks about problems with BSD4.3 and vfork,
however, we have not supported BSD4.3 for several years now.
Given the above, it seems that changing the disposition of SIGTRAP is
no longer needed, so I've deleted the signal() call for SIGTRAP.
Finally, the header comment on the function now called
gdb_init_signals was getting quite out of date, so I've updated it
to (hopefully) better reflect reality.
There should be no user visible change after this commit.
|
|
Some add_set_show commands return a single cmd_list_element, the one for
the "set" command. A subsequent patch will need to access the show
command's cmd_list_element as well. Change these functions to return a
new structure type that holds both pointers.
I initially only modified add_setshow_boolean_cmd (the one I needed),
but I think it's better to change the whole chain to keep everything in
sync.
gdb/ChangeLog:
* command.h (set_show_commands): New.
(add_setshow_enum_cmd, add_setshow_auto_boolean_cmd,
add_setshow_boolean_cmd, add_setshow_filename_cmd,
add_setshow_string_cmd, add_setshow_string_noescape_cmd,
add_setshow_optional_filename_cmd, add_setshow_integer_cmd,
add_setshow_uinteger_cmd, add_setshow_zinteger_cmd,
add_setshow_zuinteger_cmd, add_setshow_zuinteger_unlimited_cmd):
Return set_show_commands. Adjust callers.
* cli/cli-decode.c (add_setshow_cmd_full): Return
set_show_commands, remove result parameters, adjust callers.
Change-Id: I17492b01b76002d09effc84830f9c6db26f1db7a
|
|
Same idea as the previous patches, but for whether a command is a
"command class help" command. I think this one is particularly useful,
because it's not obvious when reading code what "c->func == NULL" means.
Remove the cmd_func_p function, which does kind of the same thing as
cmd_list_element::is_command_class_help (except it doesn't give a clue
about the semantic of a NULL func value).
gdb/ChangeLog:
* cli/cli-decode.h (cmd_list_element) <is_command_class_help>:
New, use it.
* command.h (cmd_func_p): Remove.
* cli/cli-decode.c (cmd_func_p): Remove.
Change-Id: I521a3e1896dc93a5babe1493d18f5eb071e1b3b7
|
|
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
|
|
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.
|
|
Now (thanks to the last few commits) all extension languages are
fully initialised in their finish_initialization method, this commit
delays the call to this method until after the early initialization
files have been processed.
Right now there's no benefit from doing this, but in a later commit I
plan to add new options for Python that will control how Python is
initialized.
With this commit in place, my next commits will allow the user to add
options to their early initialization file and alter how Python starts
up.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* main.c (captured_main_1): Add a call to
finish_ext_lang_initialization.
* top.c (gdb_init): Remove call to finish_ext_lang_initialization.
|
|
The argument to gdb_init is not used, remove it.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* main.c (captured_main_1): Don't pass argument to gdb_init.
* top.c (gdb_init): Remove unused argument, and add header
comment.
* top.h (gdb_init): Remove argument.
|
|
This adds a new command to change GDB to behave as though "-quiet"
were always given. This new command can be added to the gdbearlyinit
file to affect future GDB sessions.
gdb/ChangeLog:
* NEWS: Add entry.
* main.c (captured_main_1): Call check_quiet_mode.
* top.c (startup_quiet): New global.
(check_quiet_mode): New function.
(show_startup_quiet): New function.
(init_main): Register new command.
* top.h (check_quiet_mode): Declare.
gdb/doc/ChangeLog:
* gdb.texinfo (Mode Options): Mention "set startup-quietly".
gdb/testsuite/ChangeLog:
* gdb.base/startup-file.exp: Add more tests.
|
|
It was reported on IRC that using gdb.parameter('data-directory')
doesn't work correctly.
The problem is that the data directory is stored in 'gdb_datadir',
however the set/show command is associated with a temporary
'staged_gdb_datadir'.
When the user does 'set data-directory VALUE', the VALUE is stored in
'staged_gdb_datadir' by GDB, then set_gdb_datadir is called. This in
turn calls set_gdb_data_directory to copy the value from
staged_gdb_datadir into gdb_datadir.
However, set_gdb_data_directory will resolve relative paths, so the
value stored in gdb_datadir might not match the value in
staged_gdb_datadir.
The Python gdb.parameter API fetches the parameter values by accessing
the variable associated with the show command, so in this case
staged_gdb_datadir. This causes two problems:
1. Initially staged_gdb_datadir is NULL, and remains as such until the
user does 'set data-directory VALUE' (which might never happen), but
gdb_datadir starts with GDB's default data-directory value. So
initially from Python gdb.parameter('data-directory') will return the
empty string, even though at GDB's CLI 'show data-directory' prints a
real path.
2. If the user does 'set data-directory ./some/relative/path', GDB
will resolve the relative path, thus, 'show data-directory' at the CLI
will print an absolute path. However, the value is staged_gdb_datadir
will still be the relative path, and gdb.parameter('data-directory')
from Python will return the relative path.
In this commit I fix both of these issues by:
1. Initialising the value in staged_gdb_datadir based on the initial
value in gdb_datadir, and
2. In set_gdb_datadir, after calling set_gdb_data_directory, I copy
the value in gdb_datadir back into staged_gdb_datadir.
With these two changes in place the value in staged_gdb_datadir should
always match the value in gdb_datadir, and accessing data-directory
from Python should now work correctly.
gdb/ChangeLog:
* top.c (staged_gdb_datadir): Update comment.
(set_gdb_datadir): Copy the value of gdb_datadir back into
staged_datadir.
(init_main): Initialise staged_gdb_datadir.
gdb/testsuite/ChangeLog:
* gdb.python/py-parameter.exp: Add test for reading data-directory
using gdb.parameter API.
|
|
I noticed that language_info is only ever called with a value of '1'.
This patch removes the parameter.
2021-03-29 Tom Tromey <tromey@adacore.com>
* top.c (check_frame_language_change): Update.
* language.c (language_info): Remove parameter.
* language.h (language_info): Remove parameter.
|
|
pending statuses
The rationale for this patch comes from the ROCm port [1], the goal
being to reduce the number of back and forths between GDB and the
target when doing successive operations. I'll start with explaining
the rationale and then go over the implementation. In the ROCm / GPU
world, the term "wave" is somewhat equivalent to a "thread" in GDB.
So if you read if from a GPU stand point, just s/thread/wave/.
ROCdbgapi, the library used by GDB [2] to communicate with the GPU
target, gives the illusion that it's possible for the debugger to
control (start and stop) individual threads. But in reality, this is
not how it works. Under the hood, all threads of a queue are
controlled as a group. To stop one thread in a group of running ones,
the state of all threads is retrieved from the GPU, all threads are
destroyed, and all threads but the one we want to stop are re-created
from the saved state. The net result, from the point of view of GDB,
is that the library stopped one thread. The same thing goes if we
want to resume one thread while others are running: the state of all
running threads is retrieved from the GPU, they are all destroyed, and
they are all re-created, including the thread we want to resume.
This leads to some inefficiencies when combined with how GDB works,
here are two examples:
- Stopping all threads: because the target operates in non-stop mode,
when the user interface mode is all-stop, GDB must stop all threads
individually when presenting a stop. Let's suppose we have 1000
threads and the user does ^C. GDB asks the target to stop one
thread. Behind the scenes, the library retrieves 1000 thread
states and restores the 999 others still running ones. GDB asks
the target to stop another one. The target retrieves 999 thread
states and restores the 998 remaining ones. That means that to
stop 1000 threads, we did 1000 back and forths with the GPU. It
would have been much better to just retrieve the states once and
stop there.
- Resuming with pending events: suppose the 1000 threads hit a
breakpoint at the same time. The breakpoint is conditional and
evaluates to true for the first thread, to false for all others.
GDB pulls one event (for the first thread) from the target, decides
that it should present a stop, so stops all threads using
stop_all_threads. All these other threads have a breakpoint event
to report, which is saved in `thread_info::suspend::waitstatus` for
later. When the user does "continue", GDB resumes that one thread
that did hit the breakpoint. It then processes the pending events
one by one as if they just arrived. It picks one, evaluates the
condition to false, and resumes the thread. It picks another one,
evaluates the condition to false, and resumes the thread. And so
on. In between each resumption, there is a full state retrieval
and re-creation. It would be much nicer if we could wait a little
bit before sending those threads on the GPU, until it processed all
those pending events.
To address this kind of performance issue, ROCdbgapi has a concept
called "forward progress required", which is a boolean state that
allows its user (i.e. GDB) to say "I'm doing a bunch of operations,
you can hold off putting the threads on the GPU until I'm done" (the
"forward progress not required" state). Turning forward progress back
on indicates to the library that all threads that are supposed to be
running should now be really running on the GPU.
It turns out that GDB has a similar concept, though not as general,
commit_resume. One difference is that commit_resume is not stateful:
the target can't look up "does the core need me to schedule resumed
threads for execution right now". It is also specifically linked to
the resume method, it is not used in other contexts. The target
accumulates resumption requests through target_ops::resume calls, and
then commits those resumptions when target_ops::commit_resume is
called. The target has no way to check if it's ok to leave resumed
threads stopped in other target methods.
To bridge the gap, this patch generalizes the commit_resume concept in
GDB to match the forward progress concept of ROCdbgapi. The current
name (commit_resume) can be interpreted as "commit the previous resume
calls". I renamed the concept to "commit_resumed", as in "commit the
threads that are resumed".
In the new version, we have two things:
- the commit_resumed_state field in process_stratum_target: indicates
whether GDB requires target stacks using this target to have
resumed threads committed to the execution target/device. If
false, an execution target is allowed to leave resumed threads
un-committed at the end of whatever method it is executing.
- the commit_resumed target method: called when commit_resumed_state
transitions from false to true. While commit_resumed_state was
false, the target may have left some resumed threads un-committed.
This method being called tells it that it should commit them back
to the execution device.
Let's take the "Stopping all threads" scenario from above and see how
it would work with the ROCm target with this change. Before stopping
all threads, GDB would set the target's commit_resumed_state field to
false. It would then ask the target to stop the first thread. The
target would retrieve all threads' state from the GPU and mark that
one as stopped. Since commit_resumed_state is false, it leaves all
the other threads (still resumed) stopped. GDB would then proceed to
call target_stop for all the other threads. Since resumed threads are
not committed, this doesn't do any back and forth with the GPU.
To simplify the implementation of targets, this patch makes it so that
when calling certain target methods, the contract between the core and
the targets guarantees that commit_resumed_state is false. This way,
the target doesn't need two paths, one for commit_resumed_state ==
true and one for commit_resumed_state == false. It can just assert
that commit_resumed_state is false and work with that assumption.
This also helps catch places where we forgot to disable
commit_resumed_state before calling the method, which represents a
probable optimization opportunity. The commit adds assertions in the
target method wrappers (target_resume and friends) to have some
confidence that this contract between the core and the targets is
respected.
The scoped_disable_commit_resumed type is used to disable the commit
resumed state of all process targets on construction, and selectively
re-enable it on destruction (see below for criteria). Note that it
only sets the process_stratum_target::commit_resumed_state flag. A
subsequent call to maybe_call_commit_resumed_all_targets is necessary
to call the commit_resumed method on all target stacks with process
targets that got their commit_resumed_state flag turned back on. This
separation is because we don't want to call the commit_resumed methods
in scoped_disable_commit_resumed's destructor, as they may throw.
On destruction, commit-resumed is not re-enabled for a given target
if:
1. this target has no threads resumed, or
2. this target has at least one resumed thread with a pending status
known to the core (saved in thread_info::suspend::waitstatus).
The first point is not technically necessary, because a proper
commit_resumed implementation would be a no-op if the target has no
resumed threads. But since we have a flag do to a quick check, it
shouldn't hurt.
The second point is more important: together with the
scoped_disable_commit_resumed instance added in fetch_inferior_event,
it makes it so the "Resuming with pending events" described above is
handled efficiently. Here's what happens in that case:
1. The user types "continue".
2. Upon destruction, the scoped_disable_commit_resumed in the
`proceed` function does not enable commit-resumed, as it sees some
threads have pending statuses.
3. fetch_inferior_event is called to handle another event, the
breakpoint hit evaluates to false, and that thread is resumed.
Because there are still more threads with pending statuses, the
destructor of scoped_disable_commit_resumed in
fetch_inferior_event still doesn't enable commit-resumed.
4. Rinse and repeat step 3, until the last pending status is handled
by fetch_inferior_event. In that case,
scoped_disable_commit_resumed's destructor sees there are no more
threads with pending statues, so it asks the target to commit
resumed threads.
This allows us to avoid all unnecessary back and forths, there is a
single commit_resumed call once all pending statuses are processed.
This change required remote_target::remote_stop_ns to learn how to
handle stopping threads that were resumed but pending vCont. The
simplest example where that happens is when using the remote target in
all-stop, but with "maint set target-non-stop on", to force it to
operate in non-stop mode under the hood. If two threads hit a
breakpoint at the same time, GDB will receive two stop replies. It
will present the stop for one thread and save the other one in
thread_info::suspend::waitstatus.
Before this patch, when doing "continue", GDB first resumes the thread
without a pending status:
Sending packet: $vCont;c:p172651.172676#f3
It then consumes the pending status in the next fetch_inferior_event
call:
[infrun] do_target_wait_1: Using pending wait status status->kind = stopped, signal = GDB_SIGNAL_TRAP for Thread 1517137.1517137.
[infrun] target_wait (-1.0.0, status) =
[infrun] 1517137.1517137.0 [Thread 1517137.1517137],
[infrun] status->kind = stopped, signal = GDB_SIGNAL_TRAP
It then realizes it needs to stop all threads to present the stop, so
stops the thread it just resumed:
[infrun] stop_all_threads: Thread 1517137.1517137 not executing
[infrun] stop_all_threads: Thread 1517137.1517174 executing, need stop
remote_stop called
Sending packet: $vCont;t:p172651.172676#04
This is an unnecessary resume/stop. With this patch, we don't commit
resumed threads after proceeding, because of the pending status:
[infrun] maybe_commit_resumed_all_process_targets: not requesting commit-resumed for target extended-remote, a thread has a pending waitstatus
When GDB handles the pending status and stop_all_threads runs, we stop a
resumed but pending vCont thread:
remote_stop_ns: Enqueueing phony stop reply for thread pending vCont-resume (1520940, 1520976, 0)
That thread was never actually resumed on the remote stub / gdbserver,
so we shouldn't send a packet to the remote side asking to stop the
thread.
Note that there are paths that resume the target and then do a
synchronous blocking wait, in sort of nested event loop, via
wait_sync_command_done. For example, inferior function calls, or any
run control command issued from a breakpoint command list. We handle
that making wait_sync_command_one a "sync" point -- force forward
progress, or IOW, force-enable commit-resumed state.
gdb/ChangeLog:
yyyy-mm-dd Simon Marchi <simon.marchi@efficios.com>
Pedro Alves <pedro@palves.net>
* infcmd.c (run_command_1, attach_command, detach_command)
(interrupt_target_1): Use scoped_disable_commit_resumed.
* infrun.c (do_target_resume): Remove
target_commit_resume call.
(commit_resume_all_targets): Remove.
(maybe_set_commit_resumed_all_targets): New.
(maybe_call_commit_resumed_all_targets): New.
(enable_commit_resumed): New.
(scoped_disable_commit_resumed::scoped_disable_commit_resumed)
(scoped_disable_commit_resumed::~scoped_disable_commit_resumed)
(scoped_disable_commit_resumed::reset)
(scoped_disable_commit_resumed::reset_and_commit)
(scoped_enable_commit_resumed::scoped_enable_commit_resumed)
(scoped_enable_commit_resumed::~scoped_enable_commit_resumed):
New.
(proceed): Use scoped_disable_commit_resumed and
maybe_call_commit_resumed_all_targets.
(fetch_inferior_event): Use scoped_disable_commit_resumed.
* infrun.h (struct scoped_disable_commit_resumed): New.
(maybe_call_commit_resumed_all_process_targets): New.
(struct scoped_enable_commit_resumed): New.
* mi/mi-main.c (exec_continue): Use scoped_disable_commit_resumed.
* process-stratum-target.h (class process_stratum_target):
<commit_resumed_state>: New.
* record-full.c (record_full_wait_1): Change commit_resumed_state
around calling commit_resumed.
* remote.c (class remote_target) <commit_resume>: Rename to...
<commit_resumed>: ... this.
(struct stop_reply): Move up.
(remote_target::commit_resume): Rename to...
(remote_target::commit_resumed): ... this. Check if there is any
thread pending vCont resume.
(remote_target::remote_stop_ns): Generate stop replies for resumed
but pending vCont threads.
(remote_target::wait_ns): Add gdb_assert.
* target-delegates.c: Regenerate.
* target.c (target_wait, target_resume): Assert that the current
process_stratum target isn't in commit-resumed state.
(defer_target_commit_resume): Remove.
(target_commit_resume): Remove.
(target_commit_resumed): New.
(make_scoped_defer_target_commit_resume): Remove.
(target_stop): Assert that the current process_stratum target
isn't in commit-resumed state.
* target.h (struct target_ops) <commit_resume>: Rename to ...
<commit_resumed>: ... this.
(target_commit_resume): Remove.
(target_commit_resumed): New.
(make_scoped_defer_target_commit_resume): Remove.
* top.c (wait_sync_command_done): Use
scoped_enable_commit_resumed.
[1] https://github.com/ROCm-Developer-Tools/ROCgdb/
[2] https://github.com/ROCm-Developer-Tools/ROCdbgapi
Change-Id: I836135531a29214b21695736deb0a81acf8cf566
|
|
The function execute_command_to_string had two header comments, one in
gdbcmd.h and one in top.c.
This commit merges the two comments into one and places this comment
in gdbcmd.h. The comment in top.c is updated to just reference
gdbcmd.h.
gdb/ChangeLog:
* gdbcmd.h (execute_command_to_string): Update comment.
* top.c (execute_command_to_string): Update header comment.
|
|
This commit adds a new 'version' style, which replaces the hard coded
styling currently used for GDB's version string. GDB's version number
is displayed:
1. In the output of 'show version', and
2. When GDB starts up (without the --quiet option).
This new style can only ever affect the first of these two cases as
the second case is printed before GDB has processed any initialization
files, or processed any GDB commands passed on the command line.
However, because the first case exists I think this commit makes
sense, it means the style is no longer hard coded into GDB, and we can
add some tests that the style can be enabled/disabled correctly.
This commit is an alternative to a patch Tom posted here:
https://sourceware.org/pipermail/gdb-patches/2020-June/169820.html
I've used the style name 'version' instead of 'startup' to reflect
what the style is actually used for. If other parts of the startup
text end up being highlighted I imagine they would get their own
styles based on what is being highlighted. I feel this is more inline
with the other style names that are already in use within GDB.
I also decoupled adding this style from the idea of startup options,
and the possibility of auto-saving startup options. Those ideas can
be explored in later patches.
This commit should probably be considered only a partial solution to
issue PR cli/25956. The colours of the style are no longer hard
coded, however, it is still impossible to change the styling of the
version string displayed during startup, so in one sense, the styling
of that string is still "hard coded". A later patch will hopefully
extend GDB to allow it to adjust the version styling before the
initial version string is printed.
gdb/ChangeLog:
PR cli/25956
* cli/cli-style.c: Add 'cli/cli-setshow.h' include.
(version_style): Define.
(cli_style_option::cli_style_option): Add intensity parameter, and
use as appropriate.
(_initialize_cli_style): Register version style set/show commands.
* cli/cli-style.h (cli_style_option): Add intensity parameter.
(version_style): Declare.
* top.c (print_gdb_version): Use version_stype, and styled_string
to print the GDB version string.
gdb/doc/ChangeLog:
PR cli/25956
* gdb.texinfo (Output Styling): Document version style.
gdb/testsuite/ChangeLog:
PR cli/25956
* gdb.base/style.exp (run_style_tests): Add version string test.
(test_startup_version_string): Use version style name.
* lib/gdb-utils.exp (style): Handle version style name.
|
|
remote_debug is currently declared in target.h and defined in top.c.
Move them to remote.h and remote.c.
Include remote.h in remote-sim.c, as it uses remote_debug.
gdb/ChangeLog:
* target.h (remote_debug): Move to...
* remote.h (remote_debug): ... here.
* top.c (remote_debug): Move to...
* remote.c (remote_debug): ... here.
* remote-sim.c: Include remote.h.
Change-Id: Iae632d12ff8900b23eee6b2529d6a3cd339a8caa
|