Age | Commit message (Collapse) | Author | Files | Lines |
|
In commit 9d9dd861e98 ("[gdb/testsuite] Fix regression in
step-indirect-call-thunk.exp with gcc 7") I accidentally committed a duplicate
of supports_gnuc, which caused:
...
DUPLICATE: gdb.base/gdb-caching-proc.exp: supports_gnuc: consistency
...
Fix this by removing the duplicate.
Tested on x86_64-linux.
|
|
It is possible that a system might have a python3 executable, but no
python executable. For example, on my Fedora system the python2
package provides /usr/bin/python2, the python3 package provides
/usr/bin/python3, and the python-unversioned-command package provides
/usr/bin/python, which picks between python2 and python3.
It is quite possible to only have python3 available on a system.
Currently, when GDB configures, it looks for a 'python' executable.
If non is found then GDB will be built without python support. Or the
user needs to configure using --with-python=/usr/bin/python3.
This commit updates GDB's configure.ac script to first look for
'python', and then 'python3'. Now, on a system that only has a
python3 executable, GDB will automatically find, and use that in order
to provide python support, no user supplied configure arguments are
needed.
I've tested this on my local machine by removing the
python-unversioned-command package, confirming that there is no longer
a 'python' executable in my $PATH, and then rebuilding GDB from
scratch. GDB with this patch has python support.
|
|
Both forms were missing VexW0 (thus allowing Evex.W=1 to be encoded by
suitable means, which would cause #UD). The memory operand form further
was using the wrong Masking value, thus allowing zeroing-masking to be
encoded for the store form (which would again cause #UD).
|
|
This saves quite a number of shift instructions: The "operands" field
can now be retrieved by just masking (no shift), and extracting the
"extension_opcode" field now only requires a (signed) right shift, with
no prereq left one. (Of course there may be architectures where, in a
cross build, there might be no difference at all, e.g. when there are
suitable bitfield extraction insns.)
|
|
When running a task using parallel_for_each, we get the following
distribution:
...
Parallel for: n_elements: 7271
Parallel for: minimum elements per thread: 10
Parallel for: elts_per_thread: 1817
Parallel for: elements on worker thread 0 : 1817
Parallel for: elements on worker thread 1 : 1817
Parallel for: elements on worker thread 2 : 1817
Parallel for: elements on worker thread 3 : 0
Parallel for: elements on main thread : 1820
...
Note that there are 4 active threads, and scheduling elts_per_thread on each
of those handles 4 * 1817 == 7268, leaving 3 "left over" elements.
These leftovers are currently handled in the main thread.
That doesn't seem to matter much for this example, but for say 10 threads and
99 elements, you'd have 9 threads handling 9 elements and 1 thread handling 18
elements.
Instead, distribute the left over elements over the worker threads, such that
we have:
...
Parallel for: elements on worker thread 0 : 1818
Parallel for: elements on worker thread 1 : 1818
Parallel for: elements on worker thread 2 : 1818
Parallel for: elements on worker thread 3 : 0
Parallel for: elements on main thread : 1817
...
Tested on x86_64-linux.
|
|
Use set_sanitizer_default for ASAN_OPTIONS in lib/gdb.exp.
This allows us to override the default detect_leaks=0 setting, by manually
doing:
...
$ export ASAN_OPTIONS=detect_leaks=1
$ make check
...
Tested on x86_64-linux, by building with -fsanitize=address and running
test-case gdb.dwarf2/gdb-add-index.exp with and without
"export ASAN_OPTIONS=detect_leaks=1".
|
|
Since commit 43127ae5714 ("Fix gdb.base/step-indirect-call-thunk.exp") I run
into:
...
gdb compile failed, gcc: error: unrecognized command line option \
'-fcf-protection=none'; did you mean '-flto-partition=none'?
UNTESTED: gdb.base/step-indirect-call-thunk.exp: failed to prepare
...
The problem is that -fcf-protection is supported starting gcc 8, but I'm using
system gcc 7.5.0.
Fix this by only adding -fcf-protection=none for gcc 8 and later.
Tested on x86_64-linux, with gcc 7.5.0, 8.2.1 and 12.1.1.
|
|
Since commit c4a3dbaf113 ("Expose current 'print' settings to Python") we
have:
...
(gdb) print /x $bnd0 = {0x10, 0x20}^M
$22 = {lbound = 0x10, ubound = 0x20} : size 0x11^M
(gdb) FAIL: gdb.arch/i386-mpx.exp: verify size for bnd0
...
The regexp in the test-case expects "size 17".
Fix this by updating the regexp.
Tested on x86_64-linux.
|
|
Add a parallel_for_each_debug variable, set to false by default.
With an a.out compiled from hello world, we get with
parallel_for_each_debug == true:
...
$ gdb -q -batch a.out -ex start
...
Parallel for: n_elements: 7271
Parallel for: minimum elements per thread: 10
Parallel for: elts_per_thread: 1817
Parallel for: elements on worker thread 0 : 1817
Parallel for: elements on worker thread 1 : 1817
Parallel for: elements on worker thread 2 : 1817
Parallel for: elements on worker thread 3 : 0
Parallel for: elements on main thread : 1820
Temporary breakpoint 1, main () at /home/vries/hello.c:6
6 printf ("hello\n");
...
Tested on x86_64-linux.
|
|
|
|
|
|
|
|
gdb-add-index runs gdb with -iex 'set debuginfod enabled off'. If gdb
is not compiled against libdebuginfod this causes an unnecessary error
message to be printed to stderr indicating that gdb was not built with
debuginfod support.
Fix this by changing the 'set debuginfod enabled off' command to a
no-op when gdb isn't built with libdebuginfod.
|
|
gdb.base/maint.exp was using several gdb_expect statements, probably
because this test case predates the existance of gdb_test_multiple. This
commit updates the test case to use gdb_test_multiple, making it more
resilient to internal errors and such.
The only gdb_expect left in the testcase is one that specifically looks
for an internal error being triggered as a PASS.
|
|
When I rebased and updated the print_options patch, I forgot to update
print_options to add the new 'nibbles' feature to the result. This
patch fixes the oversight. I'm checking this in.
|
|
The test gdb.base/infcall-nested-structs-c.exp fails on a gdb assert
in function ppc64_sysv_abi_return_value in file gdb/ppc-sysv-tdep.c. The
assert is due to the missing IEEE 128-bit support in file
gdb/ppc-sysv-tdep.c.
The IBM long double was the initial float 128-bit support added by IBM
The IEEE 128-bit support, which is similar IBM long double support, was
made the default starting with GCC 12. The floating point format
differences include the number of bits used to encode the exponent
and significand. Also, IBM long double values are passed in a pair of
floating point registers. The IEEE 128-bit value is passed in a single
vector register.
This patch fixes the gdb_assert (ok); in function
ppc64_sysv_abi_return_value in gdb/ppc-sysv-tdep.c by adding IEEE FLOAT
128-bit type support for PowerPC.
The patch has been tested on Power 10, ELFv2. It fixes the following list
of regression failures on Power 10:
gdb.base/infcall-nested-structs-c.exp 192
gdb.base/infcall-nested-structs-c++.exp 76
gdb.base/structs.exp 9
The patch has been tested on Power 8 BE which is ELFv1.
|
|
This adds a 'summary' mode to Value.format_string and to
gdb.print_options. For the former, it lets Python code format values
using this mode. For the latter, it lets a printer potentially detect
if it is being called in a backtrace with 'set print frame-arguments'
set to 'scalars'.
I considered adding a new mode here to let a pretty-printer see
whether it was being called in a 'backtrace' context at all, but I'm
not sure if this is really desirable.
|
|
PR python/17291 asks for access to the current print options. While I
think this need is largely satisfied by the existence of
Value.format_string, it seemed to me that a bit more could be done.
First, while Value.format_string uses the user's settings, it does not
react to temporary settings such as "print/x". This patch changes
this.
Second, there is no good way to examine the current settings (in
particular the temporary ones in effect for just a single "print").
This patch adds this as well.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17291
|
|
Disable the Traceback Table generation on PowerPC for this test. The
Traceback Table consists of a series of bit fields to indicate things like
the Traceback Table version, language, and specific information about the
function. The Traceback Table is generated following the end of the code
for every function by default. The Traceback Table is defined in the
PowerPC ELF ABI and is intended to support debuggers and exception
handlers. The Traceback Table is displayed in the disassembly of functions
by default and is part of the function length. The table is typically
interpreted by the disassembler as data represented by .long xxx entries.
Generation of the Traceback Table is disabled in this test using the
PowerPC specific gcc compiler option -mtraceback=no, the xlc option
additional_flags-qtable=none and the clang optons
-mllvm -xcoff-traceback-table=false. Disabling the Traceback Table
generation in this test results in the gdb_test_multiple statement
correctly locating the address of the bclr instruction before the statement
"End of assembler dump." in the disassembly output.
|
|
Running 'black' on gdb fixed a couple of small issues. This patch is
the result.
|
|
|
|
When building gdb with -fsanitize-threads and running test-case
gdb.ada/char_enum_unicode.exp, I run into:
...
WARNING: ThreadSanitizer: data race (pid=21301)^M
Write of size 8 at 0x7b2000008080 by main thread:^M
#0 free <null> (libtsan.so.2+0x4c5e2)^M
#1 _dl_close_worker <null> (ld-linux-x86-64.so.2+0x4b7b)^M
#2 convert_between_encodings() charset.c:584^M
...
#21 cooked_index_functions::expand_symtabs_matching() read.c:18606
...
This is fixed by making cooked_index_functions::expand_symtabs_matching wait
for the cooked index finalization to be done.
Tested on x86_64-linux.
https://sourceware.org/bugzilla/show_bug.cgi?id=29311
https://sourceware.org/bugzilla/show_bug.cgi?id=29286
|
|
Add a sequential_for_each alongside the parallel_for_each, which can be used
as a drop-in replacement.
This can be useful when debugging multi-threading behaviour, and you want to
limit multi-threading in a fine-grained way.
Tested on x86_64-linux, by using it instead of the parallel_for_each in
dwarf2_build_psymtabs_hard.
|
|
Update NEWS and gdb.texinfo to document floating-point support
for LoongArch.
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
|
|
When building gdb with gcc 4.8.5, we run into:
...
In file included from /usr/include/c++/4.8/future:43:0,
from gdbsupport/thread-pool.h:30,
from gdb/dwarf2/cooked-index.h:33,
from gdb/dwarf2/read.h:26,
from gdb/dwarf2/abbrev-cache.c:21:
/usr/include/c++/4.8/atomic: In instantiation of \
‘_Tp std::atomic<_Tp>::load(std::memory_order) const [with _Tp = \
packed<dwarf_unit_type, 1ul>; std::memory_order = std::memory_order]’:
gdb/dwarf2/read.h:332:44: required from here
/usr/include/c++/4.8/atomic:208:13: error: no matching function for call to \
‘packed<dwarf_unit_type, 1ul>::packed()’
_Tp tmp;
^
...
Fix this by adding the default constructor for packed.
Tested on x86_64-linux, with gdb build with gcc 4.8.5.
|
|
When building gdb with -fsanitize=thread and running test-case
gdb.dwarf2/inlined_subroutine-inheritance.exp, we run into a data race
between:
...
Read of size 1 at 0x7b2000003010 by thread T4:
#0 packed<language, 1ul>::operator language() const packed.h:54
#1 dwarf2_per_cu_data::set_lang(language) read.h:363
...
and:
...
Previous write of size 1 at 0x7b2000003010 by main thread:
#0 dwarf2_per_cu_data::set_lang(language) read.h:365
...
Fix this by making per_cu->m_lang atomic.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29286
|
|
With gdb with -fsanitize=thread and test-case gdb.ada/array_bounds.exp, I run
into a data race between:
...
Read of size 1 at 0x7b2000025f0f by main thread:
#0 packed<dwarf_unit_type, 1ul>::operator dwarf_unit_type() const packed.h:54
#1 dwarf2_per_cu_data::set_unit_type(dwarf_unit_type) read.h:339
...
and:
...
Previous write of size 1 at 0x7b2000025f0f by thread T3:
#0 dwarf2_per_cu_data::set_unit_type(dwarf_unit_type) read.h:341
...
Fix this by making per_cu->unit_type atomic.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29286
|
|
When doing:
...
$ gdb ./outputs/gdb.ada/char_enum_unicode/foo -batch -ex "break foo.adb:26"
...
with a gdb build with -fsanitize=thread I run into a data race:
...
WARNING: ThreadSanitizer: data race (pid=30917)
Write of size 8 at 0x7b0400004070 by main thread:
#0 free <null> (libtsan.so.2+0x4c5e2)
#1 xfree<char> gdbsupport/gdb-xfree.h:37 (gdb+0x650f17)
#2 charset_vector::clear() gdb/charset.c:703 (gdb+0x651354)
#3 charset_vector::~charset_vector() gdb/charset.c:697 (gdb+0x6512d3)
#4 <null> <null> (libtsan.so.2+0x32643)
#5 captured_main_1 gdb/main.c:1310 (gdb+0xa3975a)
...
The problem is that we're freeing the charset_vector elements in the destructor,
which may still be used by a worker thread.
Fix this by not freeing the charset_vector elements in the destructor.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29311
|
|
I meant to make this change before committing, to let compilers know
the code on the false branch of md_parse_name is dead.
* config/tc-ppc.c (ppc_parse_name): Return void.
* config/tc-ppc.h (md_parse_name): Always true.
(ppc_parse_name): Update prototype.
|
|
Allows register names to appear in symbol assignments, so for example
tocp = %r2
mr %r3,tocp
now assembles.
* gas/config/tc-ppc.c (REG_NAME_CNT): Delete, replace uses with
ARRAY_SIZE.
(register_name): Rename to..
(md_operand): ..this. Only handle %reg.
(cr_names): Rename to..
(cr_cond): ..this. Just keep conditions.
(ppc_parse_name): Add mode param. Search both cr_cond and
pre_defined_registers. Handle absolute and register symbol
values here rather than in expr.c:operand().
(md_assemble): Don't special case register name matching in
operands, except to set cr_operand as appropriate.
* gas/config/tc-ppc.h (md_operand): Don't define.
(md_parse_name, ppc_parse_name): Update.
* read.c (pseudo_set): Copy over entire O_register value.
* testsuite/gas/ppc/regsyms.d.
* testsuite/gas/ppc/regsyms.s: New test.
* testsuite/gas/ppc/ppc.exp: Run it.
|
|
|
|
A WIP version of a patch
(https://sourceware.org/pipermail/gdb-patches/2022-June/190202.html)
resulted in a bug that went unnoticed by the testuite, like so:
(gdb) PASS: gdb.threads/no-unwaited-for-left.exp: enable scheduler-locking, for main thread
continue
Continuing.
[New Thread 1251861.1251861]
No unwaited-for children left.
(gdb) PASS: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits
info threads
Id Target Id Frame
3 Thread 1251861.1251863 "no-unwaited-for" __pthread_clockjoin_ex (threadid=140737351558976, thread_return=0x0, clockid=<optimized out>, abstime=<optimized out>, block=<optimized out>) at pthread_join_common.c:145
4 Thread 1251861.1251861 "no-unwaited-for" <unavailable> in ?? ()
The current thread <Thread ID 1> has terminated. See `help thread'.
(gdb) PASS: gdb.threads/no-unwaited-for-left.exp: only thread 3 left, main thread terminated
Somehow, above, GDB re-added the zombie leader back before printing
"No unwaited-for children left.". The "only thread 3 left, main
thread terminated" test should have caught this, but didn't. That is
because the test's regexp has a ".*" after the part that matches
thread 3. This commit tightens that regexp to catch such a bug. It
also tightens the "only main thread left, thread 2 terminated" test's
regexp in the same way.
Change-Id: I8744f327a0aa0e2669d1ddda88247e99b91cefff
|
|
On PowePC, the test fails on a compile error:
/../binutils-gdb-current/gdb/testsuite/gdb.base/stap-probe.c:107:1: error: expected '=', ',', ';', 'asm' or 'attribute' before 'use_xmm_reg'
107 | use_xmm_reg (int val)
| ^~~~~~~~~~~
Where the source code for stap-probe.c is:
static const char * __attribute__((noinline)) ATTRIBUTE_NOCLONE
use_xmm_reg (int val) <-- line 107
{
...
The issue is the ATTRIBUTE_NOCLONE is not defined as an attribute as
expected. The #define for ATTRIBUTE_NOCLONE can be found in
../lib/attributes.h.
This patch adds the missing include statement for the definition of
ATTRIBUTE_NOCLONE.
The patch has been tested and verified on a Power10 system.
|
|
This patch adds the needed define ASM_REG for PowerPC.
The patch was run on a Power 10 system. The gdb Summary for the run lists
2 expected passes, no unexpected failures or untested testcases.
Please let me know if this patch is acceptable for mainline.
Carl Love
|
|
Due to recent changes in the default value of -fcf-protection for gcc, the
test gdb.base/step-indirect-call-thunk.exp fails on Intel X86-64 with the
error:
Executing on host: gcc -fno-stack-protector -fdiagnostics-color=never
-mindirect-branch=thunk -mfunction-return=thunk -c -g
-o /.../gdb/testsuite/outputs/gdb.base/step-indirect-call-thunk/step-indirect-call-thunk0.o
/.../gdb/testsuite/gdb.base/step-indirect-call-thunk.c
(timeout = 300) builtin_spawn -ignore SIGHUP gcc -fno-stack-protector
-fdiagnostics-color=never -mindirect-branch=thunk -mfunction-return=thunk -c
-g -o /.../gdb/testsuite/outputs/gdb.base/step-indirect-call-thunk/step-indirect-call-thunk0.o
/.../binutils-gdb-current/gdb/testsuite/gdb.base/step-indirect-call-thunk.c
/.../gdb/testsuite/gdb.base/step-indirect-call-thunk.c:
In function 'inc': /.../gdb/testsuite/gdb.base/step-indirect-call-thunk.c:
22:1: error: '-mindirect-branch' and '-fcf-protection' are not compatible
22 | { /* inc.1 */
As stated in the error message the default "-fcf-protection" and
"-mindirect-branch' are in compatible. The fcf-protection argument needs
to be "-fcf-protection=none" for the test to compile on Intel.
The gcc command line "-mindirect-branch' is an Intel specific and will give
an error on other platforms. A check for X86 is added so the test will
only run on X86 platforms.
The patch has been tested and verified on Power 10 and Intel X86-64 systems
with no regressions.
|
|
With a test like this:
1 #include <dlfcn.h>
2 int
3 main ()
4 {
5 dlsym (RTLD_DEFAULT, "FOO");
6 return 0;
7 }
and then "start" followed by "until 6", GDB currently incorrectly
stops inside the runtime loader, instead of line 6. Vis:
...
Temporary breakpoint 1, main () at until.c:5
4 {
(gdb) until 6
0x00007ffff7f0a90d in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdb00, operate=<optimized out>, args=0x7ffff7f0a90d <__GI__dl_catch_exception+109>) at dl-error-skeleton.c:206
206 dl-error-skeleton.c: No such file or directory.
(gdb)
The problem is related to longjmp handling -- dlsym internally
longjmps on error. The testcase can be reduced to this:
1 #include <setjmp.h>
2 void func () {
3 jmp_buf buf;
4 if (setjmp (buf) == 0)
5 longjmp (buf, 1);
6 }
7
8 int main () {
9 func ();
10 return 0; /* until to here */
11 }
and then with "start" followed by "until 10", GDB currently
incorrectly stops at line 4 (returning from setjmp), instead of line
10.
The problem is that the BPSTAT_WHAT_CLEAR_LONGJMP_RESUME code in
infrun.c fails to find the initiating frame, and so infrun thinks that
the longjmp jumped somewhere outer to "until"'s originating frame.
Here:
case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
{
struct frame_info *init_frame;
/* There are several cases to consider.
1. The initiating frame no longer exists. In this case we
must stop, because the exception or longjmp has gone too
far.
...
init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
if (init_frame) // this is NULL!
{
...
}
/* For Cases 1 and 2, remove the step-resume breakpoint, if it
exists. */
delete_step_resume_breakpoint (ecs->event_thread);
end_stepping_range (ecs); // case 1., so we stop.
}
The initiating frame is set by until_break_command ->
set_longjmp_breakpoint. The initiating frame is supposed to be the
frame that is selected when the command was issued, but
until_break_command instead passes the frame id of the _caller_ frame
by mistake. When the "until LINE" command is issued from main, the
caller frame is the caller of main. When later infrun tries to find
that frame by id, it fails to find it, because frame_find_by_id
doesn't unwind past main.
The bug is that we passed the caller frame's id to
set_longjmp_breakpoint. We should have passed the selected frame's id
instead.
Change-Id: Iaae1af7cdddf296b7c5af82c3b5b7d9b66755b1c
|
|
When building with clang 15, I got this error:
CXX server.o
server.cc:2985:10: error: variable 'new_argc' set but not used [-Werror,-Wunused-but-set-variable]
int i, new_argc;
^
Remove the unused variable to eliminate the error.
Tested by rebuilding on x86_64-linux with clang 15.
|
|
We have in per_cu->set_lang this comment:
...
void set_lang (enum language lang)
{
/* We'd like to be more strict here, similar to what is done in
set_unit_type, but currently a partial unit can go from unknown to
minimal to ada to c. */
...
Fix this by not setting m_lang for partial units.
This requires us to move the m_unit_type initialization to ensure that
m_unit_type is initialized before per_cu->m_lang.
Tested on x86_64-linux, with native and target board cc-with-dwz-m.
|
|
|
|
This improves the "set scheduler-locking" documentation in the GDB
manual:
- Use a table to describe the four available modes.
- Describe "step" in terms of "on" and "off".
- Tweak the "replay" mode's description to describe replay first
instead of recording, and also mention how the mode behaves during
normal execution.
- Say what is the default mode.
Change-Id: Ie12140138b37534b7fc1d904da34f0f174aa11ce
|
|
The cu->per_cu->lang field was added to carry information from the initial
partial symtabs phase to the symtab expansion phase, for the benefit of a
particular optimization in process_imported_unit_die.
Other uses have been added, but since the first phase now has been
parallelized, those have become problematic and sources of race conditions.
Fix this by adding dwarf2_cu::lang () and using it where we can to replace
cu->per_cu->lang () with cu->lang ().
Also assert in dwarf2_cu::lang () that we're not returning language_unknown.
Tested on x86_64-linux.
|
|
include/ChangeLog:
* plugin-api.h (enum ld_plugin_tag): Sync with GCC.
|
|
Add missing support for recording of linux syscall getrandom.
Tested on x86_64-linux with native and target board unix/-m32.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=22081
|
|
This commit adds floating-point support for LoongArch gdbserver.
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
|
|
This commit adds floating-point support for LoongArch gdb.
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
|
|
When building gdb with -fsanitize=address we run into:
...
builtin_spawn gdb -nw -nx -iex set height 0 -iex set width 0 -data-directory \
build/gdb/data-directory^M
==10637==ASan runtime does not come first in initial library list; you \
should either link runtime to your application or manually preload it with \
LD_PRELOAD.^M
ERROR: GDB process no longer exists
...
Prevent the ASan runtime error by using
ASAN_OPTIONS=verify_asan_link_order=0. This makes both test-cases pass.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29358
|
|
Add a new file tsan-suppressions.txt, to suppress the "unlock unlocked mutex"
problem in ncurses, filed in PR29328.
The file is added to the TSAN_OPTIONS in lib/gdb.exp.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29328
|
|
When building gdb with gcc 4.8.5, we run into problems due to unconditionally
using:
...
gdb_static_assert (std::is_trivially_copyable<packed>::value);
...
in gdbsupport/packed.h.
Fix this by guarding the usage with HAVE_IS_TRIVIALLY_COPYABLE.
Tested by doing a full gdb build with gcc 4.8.5.
|
|
When building gdb with -fsanitize=thread and gcc 12, and running test-case
gdb.dwarf2/dwz.exp, we run into a data race between:
...
Read of size 1 at 0x7b200000300d by thread T2:^M
#0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \
abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6164 \
(gdb+0x82ec95)^M
...
and:
...
Previous write of size 1 at 0x7b200000300d by main thread:^M
#0 prepare_one_comp_unit gdb/dwarf2/read.c:23588 (gdb+0x86f973)^M
...
In other words, between:
...
if (this_cu->reading_dwo_directly)
...
and:
...
cu->per_cu->lang = pretend_language;
...
Likewise, we run into a data race between:
...
Write of size 1 at 0x7b200000300e by thread T4:
#0 process_psymtab_comp_unit gdb/dwarf2/read.c:6789 (gdb+0x830720)
...
and:
...
Previous read of size 1 at 0x7b200000300e by main thread:
#0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \
abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6164 \
(gdb+0x82edab)
...
In other words, between:
...
this_cu->unit_type = DW_UT_partial;
...
and:
...
if (this_cu->reading_dwo_directly)
...
Likewise for the write to addresses_seen in cooked_indexer::check_bounds and a
read from is_dwz in dwarf2_find_containing_comp_unit for test-case
gdb.dwarf2/dw2-dir-file-name.exp and target board cc-with-dwz-m.
The problem is that the written fields are part of the same memory location as
the read fields, so executing a read and write in different threads is
undefined behavour.
Making the written fields separate memory locations, using the new
struct packed template fixes this.
The set of fields has been established experimentally to be the
minimal set to get rid of this type of -fsanitize=thread errors, but
more fields might require the same treatment.
Looking at the properties of the lang field, unlike dwarf_version it's
not available in the unit header, so it will be set the first time
during the parallel cooked index reading. The same holds for
unit_type, and likewise for addresses_seen.
dwarf2_per_cu_data::addresses_seen is moved so that the bitfields that
currently follow it can be merged in the same memory location as the
bitfields that currently precede it, for better packing.
Tested on x86_64-linux.
Co-Authored-By: Pedro Alves <pedro@palves.net>
Change-Id: Ifa94f0a2cebfae5e8f6ddc73265f05e7fd9e1532
|
|
When building gdb with -fsanitize=thread and gcc 12, and running test-case
gdb.dwarf2/dwz.exp, we run into a few data races. For example, between:
...
Write of size 1 at 0x7b200000300e by thread T4:
#0 process_psymtab_comp_unit gdb/dwarf2/read.c:6789 (gdb+0x830720)
...
and:
...
Previous read of size 1 at 0x7b200000300e by main thread:
#0 cutu_reader::cutu_reader(dwarf2_per_cu_data*, dwarf2_per_objfile*, \
abbrev_table*, dwarf2_cu*, bool, abbrev_cache*) gdb/dwarf2/read.c:6164 \
(gdb+0x82edab)
...
In other words, between:
...
this_cu->unit_type = DW_UT_partial;
...
and:
...
if (this_cu->reading_dwo_directly)
...
The problem is that the written fields are part of the same memory
location as the read fields, so executing a read and write in
different threads is undefined behavour.
Making the written fields separate memory locations, like this:
...
struct {
ENUM_BITFIELD (dwarf_unit_type) unit_type : 8;
};
...
fixes it, however that also increases the size of struct
dwarf2_per_cu_data, because it introduces padding due to alignment of
these new structs, which align on the natural alignment of the
specified type of their fields. We can fix that with
__attribute__((packed)), like so:
struct {
ENUM_BITFIELD (dwarf_unit_type) unit_type : 8 __attribute__((packed));
};
but to avoid having to write that in several places and add suitable
comments explaining how that concoction works, introduce a new struct
packed template that wraps/hides this. Instead of the above, we'll be
able to write:
packed<dwarf_unit_type, 1> unit_type;
Note that we can't change the type of dwarf_unit_type, as that is
defined in include/, and shared with other projects, some of those
written in C.
This patch just adds the struct packed type. Following patches will
make use of it. One of those patches will want to wrap a struct
packed in an std::atomic, like:
std::atomic<std::packed<language, 1>> m_lang;
so the new gdbsupport/packed.h header adds some operators to make
comparisions between that std::atomic and the type that the wrapped
struct packed wraps work, like in:
if (m_lang == language_c)
It would be possible to implement struct packed without using
__attribute__((packed)), by having it store an array of bytes of the
appropriate size instead, however that would make it less convenient
to debug GDB. The way it's implemented, printing a struct packed
variable just prints its field using its natural type, which is
particularly useful if the type is an enum. I believe that
__attribute__((packed)) is supported by all compilers that are able to
build GDB. Even a few BFD headers use on ATTRIBUTE_PACKED on external
types:
include/coff/external.h: } ATTRIBUTE_PACKED
include/coff/external.h:} ATTRIBUTE_PACKED ;
include/coff/external.h:} ATTRIBUTE_PACKED ;
include/coff/pe.h:} ATTRIBUTE_PACKED ;
include/coff/pe.h:} ATTRIBUTE_PACKED;
include/elf/external.h:} ATTRIBUTE_PACKED Elf_External_Versym;
It is not possible to build GDB with MSVC today, but if it could, that
would be one compiler that doesn't support this attribute. However,
it supports packing via pragmas, so there's a way to cross that bridge
if we ever get to it. I believe any compiler worth its salt supports
some way of packing.
In any case, the worse that happens without the attribute is that some
types become larger than ideal. Regardless, I've added a couple
static assertions to catch such compilers in action:
/* Ensure size and aligment are what we expect. */
gdb_static_assert (sizeof (packed) == Bytes);
gdb_static_assert (alignof (packed) == 1);
Change-Id: Ifa94f0a2cebfae5e8f6ddc73265f05e7fd9e1532
|