diff options
author | Tom de Vries <tdevries@suse.de> | 2022-07-14 08:19:00 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2022-07-14 08:19:00 +0200 |
commit | 14dd1080c6127e7ad7566598860a885aa244ff8d (patch) | |
tree | 778335a294f58877774d8c79af14605cab7763d2 /gdb/dwarf2 | |
parent | b35bd7d552f80518ad90e81f592b73ee2ef736d7 (diff) | |
download | gdb-14dd1080c6127e7ad7566598860a885aa244ff8d.zip gdb-14dd1080c6127e7ad7566598860a885aa244ff8d.tar.gz gdb-14dd1080c6127e7ad7566598860a885aa244ff8d.tar.bz2 |
[gdb/symtab] Make per_cu->m_lang atomic
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
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/read.h | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index acbe298..c2f86a9 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -181,7 +181,7 @@ private: std::atomic<packed<dwarf_unit_type, 1>> m_unit_type {(dwarf_unit_type)0}; /* The language of this CU. */ - packed<language, LANGUAGE_BYTES> m_lang = language_unknown; + std::atomic<packed<language, LANGUAGE_BYTES>> m_lang {language_unknown}; public: /* True if this CU has been scanned by the indexer; false if @@ -351,21 +351,25 @@ public: enum language lang (bool strict_p = true) const { + enum language l = m_lang.load (); if (strict_p) - gdb_assert (m_lang != language_unknown); - return m_lang; + gdb_assert (l != language_unknown); + return l; } void set_lang (enum language lang) { if (unit_type () == DW_UT_partial) return; - if (m_lang == language_unknown) - /* Set if not set already. */ - m_lang = lang; - else - /* If already set, verify that it's the same value. */ - gdb_assert (m_lang == lang); + /* Set if not set already. */ + packed<language, LANGUAGE_BYTES> nope = language_unknown; + if (m_lang.compare_exchange_strong (nope, lang)) + return; + /* If already set, verify that it's the same value. */ + nope = lang; + if (m_lang.compare_exchange_strong (nope, lang)) + return; + gdb_assert_not_reached (); } /* Free any cached file names. */ |