[llvm] [DebugInfo/DWARF] Fix data race in DWARFUnit DIE extraction (PR #180470)
Shivam Kunwar via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 8 21:50:32 PST 2026
https://github.com/phyBrackets created https://github.com/llvm/llvm-project/pull/180470
Add reader-writer mutex to protect `DieArray` from concurrent access, when multiple threads call `getLineInfoForAddress()` on a thread-safe DWARFContext.
Fixes #167285"
>From 9b3aa9a3222aa44c04670b4eaca446a652b1147d Mon Sep 17 00:00:00 2001
From: Shivam Kunwar <shivam.kunwar at kdab.com>
Date: Mon, 9 Feb 2026 11:16:12 +0530
Subject: [PATCH] [DebugInfo/DWARF] Fix data race in DWARFUnit DIE extraction
---
llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 9 +++++++--
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 10 +++++++++-
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index bd204f626ac01..292adb7675a4c 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -23,6 +23,7 @@
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/RWMutex.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -246,7 +247,9 @@ class LLVM_ABI DWARFUnit {
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
std::optional<object::SectionedAddress> BaseAddr;
+
/// The compile unit debug information entry items.
+ mutable sys::RWMutex DieArrayMutex;
std::vector<DWARFDebugInfoEntry> DieArray;
/// Map from range's start address to end address and corresponding DIE.
@@ -538,9 +541,10 @@ class LLVM_ABI DWARFUnit {
/// Return the DIE object for a given offset \p Offset inside the
/// unit's DIE vector.
DWARFDie getDIEForOffset(uint64_t Offset) {
- if (std::optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset))
+ if (std::optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset)) {
+ sys::ScopedReader ReadLock(DieArrayMutex);
return DWARFDie(this, &DieArray[*DieIdx]);
-
+ }
return DWARFDie();
}
@@ -548,6 +552,7 @@ class LLVM_ABI DWARFUnit {
/// unit's DIE vector.
std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
extractDIEsIfNeeded(false);
+ sys::ScopedReader ReadLock(DieArrayMutex);
auto It =
llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
return DIE.getOffset() < Offset;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index b8fbdfc8c1d70..f45de29adc580 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -504,8 +504,15 @@ void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
}
Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
+ {
+ sys::ScopedReader ReadLock(DieArrayMutex);
+ if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)
+ return Error::success(); // Already parsed.
+ }
+
+ sys::ScopedWriter WriteLock(DieArrayMutex);
if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1)
- return Error::success(); // Already parsed.
+ return Error::success(); // Another therad parsed while we waited
bool HasCUDie = !DieArray.empty();
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
@@ -660,6 +667,7 @@ bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) {
}
void DWARFUnit::clearDIEs(bool KeepCUDie) {
+ sys::ScopedWriter WriteLock(DieArrayMutex);
// Do not use resize() + shrink_to_fit() to free memory occupied by dies.
// shrink_to_fit() is a *non-binding* request to reduce capacity() to size().
// It depends on the implementation whether the request is fulfilled.
More information about the llvm-commits
mailing list