[gdb/symtab] Fix data race in ~charset_vector

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
This commit is contained in:
Tom de Vries 2022-07-14 08:19:00 +02:00
parent 5f6c92298a
commit 4f92e10cda

View file

@ -694,7 +694,13 @@ struct charset_vector
{
~charset_vector ()
{
clear ();
/* Note that we do not call charset_vector::clear, which would also xfree
the elements. This destructor is only called after exit, at which point
those will be freed anyway on process exit, so not freeing them now is
not classified as a memory leak. OTOH, freeing them now might be
classified as a data race, because some worker thread might still be
accessing them. */
charsets.clear ();
}
void clear ()