Skip to content

Commit 447d1c2

Browse files
committed
Make the whole DbgHelpLoader class thread safe
1 parent 9f753a9 commit 447d1c2

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121

2222
DbgHelpLoader* DbgHelpLoader::Inst = NULL;
23+
CriticalSectionClass DbgHelpLoader::CriticalSection;
2324

2425
DbgHelpLoader::DbgHelpLoader()
2526
: m_symInitialize(NULL)
@@ -45,21 +46,29 @@ DbgHelpLoader::~DbgHelpLoader()
4546

4647
bool DbgHelpLoader::isLoaded()
4748
{
49+
CriticalSectionClass::LockClass lock(CriticalSection);
50+
4851
return Inst != NULL && Inst->m_dllModule != HMODULE(0);
4952
}
5053

5154
bool DbgHelpLoader::isLoadedFromSystem()
5255
{
56+
CriticalSectionClass::LockClass lock(CriticalSection);
57+
5358
return isLoaded() && Inst->m_loadedFromSystem;
5459
}
5560

5661
bool DbgHelpLoader::isFailed()
5762
{
63+
CriticalSectionClass::LockClass lock(CriticalSection);
64+
5865
return Inst != NULL && Inst->m_failed;
5966
}
6067

6168
bool DbgHelpLoader::load()
6269
{
70+
CriticalSectionClass::LockClass lock(CriticalSection);
71+
6372
if (Inst == NULL)
6473
{
6574
// Cannot use new/delete here when this is loaded during game memory initialization.
@@ -68,14 +77,14 @@ bool DbgHelpLoader::load()
6877
}
6978

7079
// Always increment the reference count.
71-
const long referenceCount = InterlockedIncrement(&Inst->m_referenceCount);
80+
++Inst->m_referenceCount;
7281

7382
// Optimization: return early if it failed before.
7483
if (Inst->m_failed)
7584
return false;
7685

7786
// Return early if someone else already loaded it.
78-
if (referenceCount > 1)
87+
if (Inst->m_referenceCount > 1)
7988
return true;
8089

8190
// Try load dbghelp.dll from the system directory first.
@@ -122,10 +131,12 @@ bool DbgHelpLoader::load()
122131

123132
void DbgHelpLoader::unload()
124133
{
134+
CriticalSectionClass::LockClass lock(CriticalSection);
135+
125136
if (Inst == NULL)
126137
return;
127138

128-
if (InterlockedDecrement(&Inst->m_referenceCount) != 0)
139+
if (--Inst->m_referenceCount != 0)
129140
return;
130141

131142
freeResources();
@@ -137,6 +148,8 @@ void DbgHelpLoader::unload()
137148

138149
void DbgHelpLoader::freeResources()
139150
{
151+
// Is private. Needs no locking.
152+
140153
while (!Inst->m_initializedProcesses.empty())
141154
{
142155
symCleanup(*Inst->m_initializedProcesses.begin());
@@ -167,6 +180,8 @@ BOOL DbgHelpLoader::symInitialize(
167180
LPSTR UserSearchPath,
168181
BOOL fInvadeProcess)
169182
{
183+
CriticalSectionClass::LockClass lock(CriticalSection);
184+
170185
if (Inst == NULL)
171186
return FALSE;
172187

@@ -192,6 +207,8 @@ BOOL DbgHelpLoader::symInitialize(
192207
BOOL DbgHelpLoader::symCleanup(
193208
HANDLE hProcess)
194209
{
210+
CriticalSectionClass::LockClass lock(CriticalSection);
211+
195212
if (Inst == NULL)
196213
return FALSE;
197214

@@ -214,6 +231,8 @@ BOOL DbgHelpLoader::symLoadModule(
214231
DWORD BaseOfDll,
215232
DWORD SizeOfDll)
216233
{
234+
CriticalSectionClass::LockClass lock(CriticalSection);
235+
217236
if (Inst != NULL && Inst->m_symLoadModule)
218237
return Inst->m_symLoadModule(hProcess, hFile, ImageName, ModuleName, BaseOfDll, SizeOfDll);
219238

@@ -224,6 +243,8 @@ DWORD DbgHelpLoader::symGetModuleBase(
224243
HANDLE hProcess,
225244
DWORD dwAddr)
226245
{
246+
CriticalSectionClass::LockClass lock(CriticalSection);
247+
227248
if (Inst != NULL && Inst->m_symGetModuleBase)
228249
return Inst->m_symGetModuleBase(hProcess, dwAddr);
229250

@@ -234,6 +255,8 @@ BOOL DbgHelpLoader::symUnloadModule(
234255
HANDLE hProcess,
235256
DWORD BaseOfDll)
236257
{
258+
CriticalSectionClass::LockClass lock(CriticalSection);
259+
237260
if (Inst != NULL && Inst->m_symUnloadModule)
238261
return Inst->m_symUnloadModule(hProcess, BaseOfDll);
239262

@@ -246,6 +269,8 @@ BOOL DbgHelpLoader::symGetSymFromAddr(
246269
LPDWORD Displacement,
247270
PIMAGEHLP_SYMBOL Symbol)
248271
{
272+
CriticalSectionClass::LockClass lock(CriticalSection);
273+
249274
if (Inst != NULL && Inst->m_symGetSymFromAddr)
250275
return Inst->m_symGetSymFromAddr(hProcess, Address, Displacement, Symbol);
251276

@@ -258,6 +283,8 @@ BOOL DbgHelpLoader::symGetLineFromAddr(
258283
PDWORD pdwDisplacement,
259284
PIMAGEHLP_LINE Line)
260285
{
286+
CriticalSectionClass::LockClass lock(CriticalSection);
287+
261288
if (Inst != NULL && Inst->m_symGetLineFromAddr)
262289
return Inst->m_symGetLineFromAddr(hProcess, dwAddr, pdwDisplacement, Line);
263290

@@ -267,6 +294,8 @@ BOOL DbgHelpLoader::symGetLineFromAddr(
267294
DWORD DbgHelpLoader::symSetOptions(
268295
DWORD SymOptions)
269296
{
297+
CriticalSectionClass::LockClass lock(CriticalSection);
298+
270299
if (Inst != NULL && Inst->m_symSetOptions)
271300
return Inst->m_symSetOptions(SymOptions);
272301

@@ -277,6 +306,8 @@ LPVOID DbgHelpLoader::symFunctionTableAccess(
277306
HANDLE hProcess,
278307
DWORD AddrBase)
279308
{
309+
CriticalSectionClass::LockClass lock(CriticalSection);
310+
280311
if (Inst != NULL && Inst->m_symFunctionTableAccess)
281312
return Inst->m_symFunctionTableAccess(hProcess, AddrBase);
282313

@@ -294,6 +325,8 @@ BOOL DbgHelpLoader::stackWalk(
294325
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
295326
PTRANSLATE_ADDRESS_ROUTINE TranslateAddress)
296327
{
328+
CriticalSectionClass::LockClass lock(CriticalSection);
329+
297330
if (Inst != NULL && Inst->m_stackWalk)
298331
return Inst->m_stackWalk(MachineType, hProcess, hThread, StackFrame, ContextRecord, ReadMemoryRoutine, FunctionTableAccessRoutine, GetModuleBaseRoutine, TranslateAddress);
299332

Core/Libraries/Source/WWVegas/WWLib/DbgHelpLoader.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,18 @@
2424
#include <imagehlp.h> // Must be included after Windows.h
2525
#include <set>
2626

27+
#include "mutex.h"
2728
#include "SystemAllocator.h"
2829

29-
// This static class can load and unload dbghelp.dll
30+
// This static class can load, unload and use dbghelp.dll. Is thread-safe.
3031
// Internally it must not use new and delete because it can be created during game memory initialization.
3132

3233
class DbgHelpLoader
3334
{
3435
private:
3536

3637
static DbgHelpLoader* Inst; // Is singleton class
38+
static CriticalSectionClass CriticalSection; // Required because dbg help is not thread safe for the most part
3739

3840
DbgHelpLoader();
3941
~DbgHelpLoader();
@@ -49,7 +51,7 @@ class DbgHelpLoader
4951
// Returns whether dbghelp.dll was attempted to be loaded but failed
5052
static bool isFailed();
5153

52-
// Every call to load needs a paired call to unload, no matter if the load was successful.
54+
// Every call to load needs a paired call to unload, no matter if the load was successful
5355
static bool load();
5456
static void unload();
5557

@@ -180,7 +182,8 @@ class DbgHelpLoader
180182

181183
Processes m_initializedProcesses;
182184
HMODULE m_dllModule;
183-
Interlocked32 m_referenceCount;
185+
int m_referenceCount;
186+
CriticalSectionClass m_criticalSection;
184187
bool m_failed;
185188
bool m_loadedFromSystem;
186189
};

Core/Libraries/Source/WWVegas/WWLib/WWCommon.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ enum
3838

3939
#if defined(_MSC_VER) && _MSC_VER < 1300
4040
typedef unsigned MemValueType;
41-
typedef long Interlocked32;
41+
typedef long Interlocked32; // To use with Interlocked functions
4242
#else
4343
typedef unsigned long long MemValueType;
44-
typedef volatile long Interlocked32;
44+
typedef volatile long Interlocked32; // To use with Interlocked functions
4545
#endif

0 commit comments

Comments
 (0)