Age | Commit message (Collapse) | Author | Files | Lines |
|
When a GDB built with -D_GLIBCXX_DEBUG=1 reads a binary with a single
character name, we hit this assertion failure:
$ ./gdb -q --data-directory=data-directory -nx ./x
/usr/include/c++/12.1.0/string_view:239: constexpr const std::basic_string_view<_CharT, _Traits>::value_type& std::basic_string_view<_CharT, _Traits>::operator[](size_type) const [with _CharT = char; _Traits = std::char_traits<char>; const_reference = const char&; size_type = long unsigned int]: Assertion '__pos < this->_M_len' failed.
The backtrace:
#3 0x00007ffff6c0f002 in std::__glibcxx_assert_fail (file=<optimized out>, line=<optimized out>, function=<optimized out>, condition=<optimized out>) at /usr/src/debug/gcc/libstdc++-v3/src/c++11/debug.cc:60
#4 0x000055555da8a864 in std::basic_string_view<char, std::char_traits<char> >::operator[] (this=0x7fffffffcc30, __pos=1) at /usr/include/c++/12.1.0/string_view:239
#5 0x00005555609dcb88 in path_join[abi:cxx11](gdb::array_view<std::basic_string_view<char, std::char_traits<char> > const>) (paths=...) at /home/simark/src/binutils-gdb/gdbsupport/pathstuff.cc:203
#6 0x000055555e0443f4 in path_join<char const*, char const*> () at /home/simark/src/binutils-gdb/gdb/../gdbsupport/pathstuff.h:84
#7 0x00005555609dc336 in gdb_realpath_keepfile[abi:cxx11](char const*) (filename=0x6060000a8d40 "/home/simark/build/binutils-gdb-one-target/gdb/./x") at /home/simark/src/binutils-gdb/gdbsupport/pathstuff.cc:122
#8 0x000055555ebd2794 in exec_file_attach (filename=0x7fffffffe0f9 "./x", from_tty=1) at /home/simark/src/binutils-gdb/gdb/exec.c:471
#9 0x000055555f2b3fb0 in catch_command_errors (command=0x55555ebd1ab6 <exec_file_attach(char const*, int)>, arg=0x7fffffffe0f9 "./x", from_tty=1, do_bp_actions=false) at /home/simark/src/binutils-gdb/gdb/main.c:513
#10 0x000055555f2b7e11 in captured_main_1 (context=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1209
#11 0x000055555f2b9144 in captured_main (data=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1319
#12 0x000055555f2b9226 in gdb_main (args=0x7fffffffdb60) at /home/simark/src/binutils-gdb/gdb/main.c:1344
#13 0x000055555d938c5e in main (argc=5, argv=0x7fffffffdcf8) at /home/simark/src/binutils-gdb/gdb/gdb.c:32
The problem is this line in path_join:
gdb_assert (strlen (path) == 0 || !IS_ABSOLUTE_PATH (path));
... where `path` is "x". IS_ABSOLUTE_PATH eventually calls
HAS_DRIVE_SPEC_1:
#define HAS_DRIVE_SPEC_1(dos_based, f) \
((f)[0] && ((f)[1] == ':') && (dos_based))
This macro accesses indices 0 and 1 of the input string. However, `f`
is a string_view of length 1, so it's incorrect to try to access index
1. We know that the string_view's underlying object is a null-terminated
string, so in practice there's no harm. But as far as the string_view
is concerned, index 1 is considered out of bounds.
This patch makes the easy fix, that is to change the path_join parameter
from a vector of to a vector of `const char *`. Another solution would
be to introduce a non-standard gdb::cstring_view class, which would be a
view over a null-terminated string. With that class, it would be
correct to access index 1, it would yield the NUL character. If there
is interest in having this class (it has been mentioned a few times in
the past) I can do it and use it here.
This was found by running tests such as gdb.ada/arrayidx.exp, which
produce 1-char long filenames, so adding a new test is not necessary.
Change-Id: Ia41a16c7243614636b18754fd98a41860756f7af
|
|
When building GDB with -std=c++17 and -D_GLIBCXX_DEBUG=1, I get:
$ ./gdb -nx --data-directory=data-directory -q -ex "maint selftest path_join"
/usr/include/c++/11.2.0/string_view:233: constexpr const value_type& std::basic_string_view<_CharT, _Traits>::operator[](std::basic_string_view<_CharT, _Traits>::size_type) const [with _CharT = char; _Traits = std::char_traits<char>; std::basic_string_view<_CharT, _Traits>::const_reference = const char&; std::basic_string_view<_CharT, _Traits>::size_type = long unsigned int]: Assertion '__pos < this->_M_len' failed.
The problem is that we're passing an empty string_view to
IS_ABSOLUTE_PATH. IS_ABSOLUTE_PATH accesses [0] on that string_view,
which is out-of-bounds.
The reason this is not seen with -std less than c++17 is that our local
copy of string_view (used with C++ < 17) does not have the assert in
operator[], as that wouldn't work in a constexpr method:
https://gitlab.com/gnutools/binutils-gdb/-/blob/5890af36e5112bcbb8d7555e63570f68466e6944/gdbsupport/gdb_string_view.h#L180
IS_ABSOLUTE_PATH is normally used with null-terminated string. It's
fine to pass an empty null-terminated string to IS_ABSOLUTE_PATH,
because index 0 in such a string is valid. But not with an empty
string_view.
Fix that by avoiding the "call" to IS_ABSOLUTE_PATH if the string_view
is empty.
Change-Id: Idf4df961b63f513b3389235e93814c02b89ea32e
|
|
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
|
|
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: I793aab17baaef8345488f4c40b9094e2695425bc
|
|
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
|
|
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.
|
|
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.
|
|
As reported in PR 27157, if some environment variables read at startup
by GDB are defined but empty, we hit the assert in gdb_abspath:
$ XDG_CACHE_HOME= ./gdb -nx --data-directory=data-directory -q
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2007040==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000001b0 (pc 0x5639d4aa4127 bp 0x7ffdac232c00 sp 0x7ffdac232bf0 T0)
==2007040==The signal is caused by a READ memory access.
==2007040==Hint: address points to the zero page.
#0 0x5639d4aa4126 in target_stack::top() const /home/smarchi/src/binutils-gdb/gdb/target.h:1334
#1 0x5639d4aa41f1 in inferior::top_target() /home/smarchi/src/binutils-gdb/gdb/inferior.h:369
#2 0x5639d4a70b1f in current_top_target() /home/smarchi/src/binutils-gdb/gdb/target.c:120
#3 0x5639d4b00591 in gdb_readline_wrapper_cleanup::gdb_readline_wrapper_cleanup() /home/smarchi/src/binutils-gdb/gdb/top.c:1046
#4 0x5639d4afab31 in gdb_readline_wrapper(char const*) /home/smarchi/src/binutils-gdb/gdb/top.c:1104
#5 0x5639d4ccce2c in defaulted_query /home/smarchi/src/binutils-gdb/gdb/utils.c:893
#6 0x5639d4ccd6af in query(char const*, ...) /home/smarchi/src/binutils-gdb/gdb/utils.c:985
#7 0x5639d4ccaec1 in internal_vproblem /home/smarchi/src/binutils-gdb/gdb/utils.c:373
#8 0x5639d4ccb3d1 in internal_verror(char const*, int, char const*, __va_list_tag*) /home/smarchi/src/binutils-gdb/gdb/utils.c:439
#9 0x5639d5151a92 in internal_error(char const*, int, char const*, ...) /home/smarchi/src/binutils-gdb/gdbsupport/errors.cc:55
#10 0x5639d5162ab4 in gdb_abspath(char const*) /home/smarchi/src/binutils-gdb/gdbsupport/pathstuff.cc:132
#11 0x5639d5162fac in get_standard_cache_dir[abi:cxx11]() /home/smarchi/src/binutils-gdb/gdbsupport/pathstuff.cc:228
#12 0x5639d3e76a81 in _initialize_index_cache() /home/smarchi/src/binutils-gdb/gdb/dwarf2/index-cache.c:325
#13 0x5639d4dbbe92 in initialize_all_files() /home/smarchi/build/binutils-gdb/gdb/init.c:321
#14 0x5639d4b00259 in gdb_init(char*) /home/smarchi/src/binutils-gdb/gdb/top.c:2344
#15 0x5639d4440715 in captured_main_1 /home/smarchi/src/binutils-gdb/gdb/main.c:950
#16 0x5639d444252e in captured_main /home/smarchi/src/binutils-gdb/gdb/main.c:1229
#17 0x5639d44425cf in gdb_main(captured_main_args*) /home/smarchi/src/binutils-gdb/gdb/main.c:1254
#18 0x5639d3923371 in main /home/smarchi/src/binutils-gdb/gdb/gdb.c:32
#19 0x7fa002d3f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#20 0x5639d392314d in _start (/home/smarchi/build/binutils-gdb/gdb/gdb+0x4d414d)
gdb_abspath doesn't handle empty strings, so handle this case in the
callers. If a variable is defined but empty, I think it's reasonable in
this case to just ignore it, as if it was not defined.
Note that this sometimes also lead to a segfault, because the failed
assertion happens very early during startup, before things are fully
initialized.
gdbsupport/ChangeLog:
PR gdb/27157
* pathstuff.cc (get_standard_cache_dir, get_standard_config_dir,
find_gdb_home_config_file): Add empty string check.
gdb/testsuite/ChangeLog:
PR gdb/27157
* gdb.base/empty-host-env-vars.exp: New test.
Change-Id: I8654d8e97e74e1dff6d308c111ae4b1bbf07bef9
|
|
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.
|
|
Use the LOCALAPPDATA environment variable to determine the cache dir
when running on Windows with native command line, otherwise nasty
warning "Couldn't determine a path for index cached directory" appears.
Change-Id: I77903f9f0cb4743555866b8aea892cef55132589
|
|
A recent commit caused pathstuff.cc to fail to compile on mingw, like:
../../binutils-gdb/gdbsupport/pathstuff.cc:324:1: error: no previous declaration for 'std::string find_gdb_home_config_file(const char*, _stati64*)' [-Werror=missing-declarations]
Some newly-added #includes were changing which "stat" was being seen
by the compiler. This patch moves the includes to the header, so that
the declaration and definition now agree.
2020-11-10 Tom Tromey <tromey@adacore.com>
PR build/26848:
* pathstuff.h: Move include block here...
* pathstuff.cc: ... from here.
|
|
This commit effectively changes the default location of the .gdbinit
file, while maintaining backward compatibility.
For non Apple hosts the .gdbinit file will now be looked for in the
following locations:
$XDG_CONFIG_HOME/gdb/gdbinit
$HOME/.config/gdb/gdbinit
$HOME/.gdbinit
On Apple hosts the search order is instead:
$HOME/Library/Preferences/gdb/gdbinit
$HOME/.gdbinit
I've performed an extensive rewrite of the documentation, moving all
information about initialization files and where to find them into a
new @node, text from other areas has been moved into this one
location, and other areas cross-reference to this new @node as much as
possible.
gdb/ChangeLog:
* NEWS: Mention changes to config file search path.
* main.c
gdb/doc/ChangeLog:
* gdb.texinfo (Mode Options): Descriptions of initialization files
has been moved to 'Initialization Files'.
(Startup): Likewise.
(Initialization Files): New node.
(gdb man): Update to mention alternative file paths.
(gdbinit man): Likewise.
|
|
This adds a new get_standard_config_dir, which returns the name of the
configuration directory. In XDG, this is ~/.config/gdb/. Future
patches will make use of this.
2020-07-05 Tom Tromey <tom@tromey.com>
* pathstuff.h (get_standard_config_dir): Declare.
* pathstuff.cc (get_standard_config_dir): New function.
|
|
This patch renames the .c source files in gdbsupport to .cc.
In the gdb directory, there is an argument against renaming the source
files, which is that it makes using some git commands more difficult to
do archeology. Some commands have some kind of "follow" option that
makes git try to follow renames, but it doesn't work in all situations.
Given that we have just moved the gdbsupport directory, that argument
doesn't hold for source files in that directory. I therefore suggest
renaming them to .cc, so that they are automatically recognized as C++
by various tools and editors.
The original motivation behind this is that when building gdbsupport
with clang, I get:
CC agent.o
clang: error: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Werror,-Wdeprecated]
In the gdb/ directory, we make clang happy by passing "-x c++". We
could do this in gdbsupport too, but I think that renaming the files is
a better long-term solution.
gdbserver still does its own build of gdbsupport, so a few changes in
its Makefile are necessary.
gdbsupport/ChangeLog:
* Makefile.am: Rename source files from .c to .cc.
(CC, CFLAGS): Don't override.
(AM_CFLAGS): Rename to ...
(AM_CXXFLAGS): ... this.
* Makefile.in: Re-generate.
* %.c: Rename to %.cc.
gdbserver/ChangeLog:
* Makefile.in: Rename gdbsupport source files from .c to .cc.
|