1

I am looking at a legacy code. I see that there are two DLLs share common code base therefore Dlls shares some common methods and synchronization object name. It means they both create and use a Critical Section synchronization object with the same name. I know global/Static variables are not shared between two modules even within a process on windows. In theory we are creating two independent synchronization objects running independently in their respective DLLs so it shouldn't be a problem.

Now consider this scenario - There is a process Proc.exe which loads two DLLs A.dll and B.dll as mentioned above.Both of these DLLs will have a common critical section object name g_cs and some common method names, for now consider one common method name foo() which is thread safe as following :

foo()
{
  ....
  EnterCriticalSection(g_cs)
  ....
  ....
  LeaveCriticalSection(g_cs)
  ....
  ....
}

Suppose two threads T1 & T2 are running within Proc.exe and are in foo() method currently. Sometimes I observe a deadlock. From the logs I see t1 and t2 simultaneously acquire the critical_section g_cs one after other and never unlock 'g_cs' afterwards. My understanding is that T1 and T2 can simultaneously acquire 'g_cs' only if they are running in context of A.dll and B.dll respectively. Is that is the case then this execution should be safe ?

My understanding is that critical section object belongs to the process so the problem might be because of common name 'g_cs' of synchronization object in two dlls. But theoretically that shouldn't happen.

Community
  • 1
  • 1
irsis
  • 952
  • 1
  • 13
  • 33
  • 3
    No, they don't acquire the same critical section at the same time. Beyond the basic logistics, it would make your critical section utterly useless. The *variable-name* of a non-exported critsec in two DLLs is irrelevant. More than likely the code you have conveniently omitted between your Enter/Leave pair is invoking a code path to the other DLL, which must likewise enter its own Enter/Leave on a different critical section. Now imagine that happening from two threads , one in each DLLs `foo()`, and both doing the same thing, needing the other DLL's cs-lock after locking their side. Deadlocked. – WhozCraig Aug 22 '13 at 05:53
  • @WhozCraig I agree non-exported critsec variable should be irrelevant.As you mentioned later could be the likely case then. Any suggestion to prevent it ? – irsis Aug 22 '13 at 06:20
  • [Use Lock Hierarchies to Avoid Deadlock](http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163). – IInspectable Aug 22 '13 at 14:15

1 Answers1

0

As already mentioned, giving the same variable name is not the issue. Even if the critical section was somehow being merged, that wouldn't lead to deadlock.

You should attach debugger at the moment of deadlock. Probably the stacks of the threads will already point to the problem. If it's indeed a deadlock, add critical sections to debugger's watch. There will be a field that shows owner thread ID. Go to that thread (select it from "threads" window) and check its stack.

Codeguard
  • 7,787
  • 2
  • 38
  • 41