Skip to content

Commit 9379cf9

Browse files
[d3d12] Rework signal handlers to dump debug info. Prevent rogue pointer access. (#1076)
1 parent d74a2af commit 9379cf9

1 file changed

Lines changed: 43 additions & 27 deletions

File tree

lib/API/DX/Device.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,42 @@
4646

4747
#include <codecvt>
4848
#include <locale>
49+
#include <mutex>
4950

5051
using namespace offloadtest;
5152
using Microsoft::WRL::ComPtr;
5253

5354
template <> char CapabilityValueEnum<directx::ShaderModel>::ID = 0;
5455
template <> char CapabilityValueEnum<directx::RootSignature>::ID = 0;
5556

57+
static std::mutex SignalHandlerMutex;
58+
static llvm::SmallVector<ID3D12Device *> SignalHandlerDevices;
59+
60+
static void dumpD3DInfoQueues(void *) {
61+
const std::lock_guard<std::mutex> Lock(SignalHandlerMutex);
62+
for (ID3D12Device *Device : SignalHandlerDevices) {
63+
ComPtr<ID3D12InfoQueue> InfoQueue;
64+
HRESULT HR = Device->QueryInterface(InfoQueue.GetAddressOf());
65+
if (FAILED(HR)) {
66+
llvm::errs() << "Failed to query D3D info queue\n";
67+
continue;
68+
}
69+
for (int I = 0, E = InfoQueue->GetNumStoredMessages(); I < E; ++I) {
70+
SIZE_T Len = 0;
71+
HR = InfoQueue->GetMessage(I, NULL, &Len);
72+
if (FAILED(HR)) {
73+
llvm::errs() << "Failed to get message " << I
74+
<< " from D3D info queue\n";
75+
} else {
76+
D3D12_MESSAGE *Msg = (D3D12_MESSAGE *)malloc(Len);
77+
HR = InfoQueue->GetMessage(I, Msg, &Len);
78+
llvm::errs() << "D3D: " << Msg->pDescription << "\n";
79+
free(Msg);
80+
}
81+
}
82+
}
83+
}
84+
5685
#define DXFormats(FMT) \
5786
if (Channels == 1) \
5887
return DXGI_FORMAT_R32_##FMT; \
@@ -496,7 +525,10 @@ class DXDevice : public offloadtest::Device {
496525
}
497526
DXDevice(const DXDevice &) = default;
498527

499-
~DXDevice() override = default;
528+
~DXDevice() override {
529+
const std::lock_guard<std::mutex> Lock(SignalHandlerMutex);
530+
llvm::erase(SignalHandlerDevices, Device.Get());
531+
}
500532

501533
llvm::StringRef getAPIName() const override { return "DirectX"; }
502534
GPUAPI getAPI() const override { return GPUAPI::DirectX; }
@@ -631,6 +663,16 @@ class DXDevice : public offloadtest::Device {
631663
IID_PPV_ARGS(&Device)),
632664
"Failed to create D3D device"))
633665
return Err;
666+
667+
static std::once_flag SignalHandlerRegistered;
668+
std::call_once(SignalHandlerRegistered, [] {
669+
llvm::sys::AddSignalHandler(dumpD3DInfoQueues, nullptr);
670+
});
671+
{
672+
const std::lock_guard<std::mutex> Lock(SignalHandlerMutex);
673+
SignalHandlerDevices.push_back(Device.Get());
674+
}
675+
634676
assert(
635677
Adapter->IsPropertySupported(DXCoreAdapterProperty::DriverDescription));
636678
size_t BufferSize;
@@ -1796,32 +1838,6 @@ class DXDevice : public offloadtest::Device {
17961838
}
17971839

17981840
llvm::Error executeProgram(Pipeline &P) override {
1799-
llvm::sys::AddSignalHandler(
1800-
[](void *Cookie) {
1801-
ID3D12Device *Device = (ID3D12Device *)Cookie;
1802-
1803-
ComPtr<ID3D12InfoQueue> InfoQueue;
1804-
HRESULT HR = Device->QueryInterface(InfoQueue.GetAddressOf());
1805-
if (FAILED(HR)) {
1806-
llvm::errs() << "Failed to query D3D info queue\n";
1807-
return;
1808-
}
1809-
for (int I = 0, E = InfoQueue->GetNumStoredMessages(); I < E; ++I) {
1810-
SIZE_T Len = 0;
1811-
HR = InfoQueue->GetMessage(I, NULL, &Len);
1812-
if (FAILED(HR)) {
1813-
llvm::errs() << "Failed to get message " << I
1814-
<< " from D3D info queue\n";
1815-
} else {
1816-
D3D12_MESSAGE *Msg = (D3D12_MESSAGE *)malloc(Len);
1817-
HR = InfoQueue->GetMessage(I, Msg, &Len);
1818-
llvm::errs() << "D3D: " << Msg->pDescription << "\n";
1819-
free(Msg);
1820-
}
1821-
}
1822-
},
1823-
(void *)Device.Get());
1824-
18251841
InvocationState State;
18261842
llvm::outs() << "Configuring execution on device: " << Description << "\n";
18271843
if (auto Err = createRootSignature(P, State))

0 commit comments

Comments
 (0)