I plan to use the WinApi CreateMutex function to only allow one running instance of my application. But I wonder what happens if the apps crashs. Is the created Mutex automatically released by the OS if the main process dies? I can't find an answer to this in the MS knowledgebase.
TIA!
A mutex is a kernel object whose lifetime is controlled by its references. When a process terminates, however it terminates, all the references to kernel objects held by that process are removed. If this leaves a kernel object having no remaining references to it, that kernel object is destroyed.
Related
I'm looking at an application which hangs on Server 2016 but runs find on Server 2008 R2. I have traced it to a hang caused by deadlock when a particular DLL loads. Analysing the DLL (I don't have the source code) I can see that it violates the guideline here
Call GetStringTypeA, GetStringTypeEx, or GetStringTypeW (either
directly or indirectly). This can cause a deadlock or a crash
Specifically it calls GetStringTypeW from DllMain.
I'm trying to understand how this function can cause deadlocks in DllMain.
Your DllMain function runs inside the loader lock, one of the few
times the OS lets you run code while one of its internal locks is
held. This means that you must be extra careful not to violate a lock
hierarchy in your DllMain; otherwise, you are asking for a deadlock. (Refer to "Another reason not to do anything scary in your DllMain: Inadvertent deadlock")
DllMain is called while the loader-lock is held, so if GetStringType acquires the loader lock, deadlock appears.
Significant restrictions are imposed on the functions that can be
called within DllMain. As such, DllMain is designed to perform minimal
initialization tasks, by using a small subset of the Microsoft®
Windows® API. You cannot call any function in DllMain that directly or
indirectly tries to acquire the loader lock. Otherwise, you will
introduce the possibility that your application deadlocks or crashes.
We can't see source code of GetStringType function. It is suggested to follow Dynamic-Link Library Best Practices.
Calling a function from DllMain that will (directly or indirectly) attempt to load another module is going to deadlock.
Module loading is serialized. The system uses a lock to ensure that at any given time no more than a single DLL entry point is entered. If you are calling LoadLibrary (directly or indirectly) from your DLL entry point, you are holding the loader lock. LoadLibrary will attempt to acquire the loader lock itself prior to calling into the module's entry point. So while your code is waiting for LoadLibrary to return, LoadLibrary is waiting for the lock you are holding. That's a deadlock.
This is likely the reason why calling GetStringType from DllMain deadlocks. Without access to source code I cannot verify this, though. You may be able to find evidence by enabling loader snaps.
We develop a user-space process running on Linux 3.4.11 in an embedded MIPS system. The process creates multiple (>10) threads using pthreads. The process has a SIGSEGV signal handler which, among other things, generates a log message which goes to our log file. As part of this flow, it acquires a semaphore (bad, I know...).
During our testing the process appeared to hang. We're currently unable to build gdb for the target platform, so I wrote a CLI tool that uses ptrace to extract the register values and USER data using PTRACE_PEEKUSR.
What surprised me to see is that all of our threads were inside our crash handler, trying to acquire the semaphore. This (obviously?) indicates a deadlock on the semaphore, which means that a thread died while holding it. When I dug up the stack, it seemed that almost all of the threads (except one) were in a blocking call (recv, poll, sleep) when the signal handler started running. Manual stack reconstruction on MIPS is a pain so we have not fully done it yet. One thread appeared to be in the middle of a malloc call, which to me indicates that it crashed due to a heap corruption.
A couple of things are still unclear:
1) Assuming one thread crashed in malloc, why would all other threads be running the SIGSEGV handler? As I understand it, a SIGSEGV signal is delivered to the faulting thread, no? Does it mean that each and every one of our threads crashed?
2) Looking at the sigcontext struct for MIPS, it seems it does not contain the memory address which was accessed (badaddr). Is there another place that has it? I couldn't find it anywhere, but it seemed odd to me that it would not be available.
And of course, if anyone can suggest ways to continue the analysis, it would be appreciated!
Yes, it is likely that all of your threads crashed in turn, assuming that you have captured the thread state correctly.
siginfo_t has a si_addr member, which should give you the address of the fault. Whether your kernel fills that in is a different matter.
In-process crash handlers will always be unreliable. You should use an out-of-process handler, and set kernel.core_pattern to invoke it. In current kernels, it is not necessary to write the core file to disk; you can either read the core file from standard input, or just map the process memory of the zombie process (which is still available when the kernel invokes the crash handler).
I use global mutex in multi-process in windows, however, the mutex won't be released when the owner process crashes, and then another process calls WaitForSingleObject, it returns WAIT_ABANDONED, how should I do to let this mutex relase, or do some other actions when returns WAIT_ABANDONED?
Suppose that a Linux driver code acquires a spinlock, inside the critical section a function call force the process running on top of the driver to sleep. Knowing that to hold spinlock disables preemption on the relevant processor, is it possible for the process to wake up, and consequently to permit the driver code to release the spinlock ?
No, it is not allowed to sleep while holding a spinlock. Code that does this is buggy.
The only way the process could be woken is if code running on another core did something to wake it up (which means that yes, it will certainly deadlock if there is only one core).
while spinlock other process can't do anything to wake it up, you could try to use semaphores for this type of switching
I'm trying to understand in a bit more detail how a OS loaderlock is used in relation to the loading and unloading of DLL's in Windows.
I understand that every loaded DLL get notified when a new thread is created/destroyed and or a new DLL is loaded/unloaded.
So does that mean that the DllMain function is run inside a lock and no other thread can access it while it is running, and if you were to create another thread in that function, you could hang the process or even the OS?
Is my understanding correct?
Is there some article somewhere that explain this?
A deadlock can happen when two threads try to acquire two locks in different sequence.
Thread A gets lock A and then tries to get lock B
Meanwhile thread B gets lock B and then tries to get lock A
A thread that's running DllMain has already acquired an implicit O/S lock: therefore they (Microsoft) reckon that it may be unsafe for that thread to try to acquire any other, second lock (e.g. because a different thread might already own that lock and be currently blocked on the implicit O/S lock).
that is correct.
Any such execution is illegal because
it can lead to deadlocks and to use of
DLLs before they have been initialized
by the operating system's loader.
More information can be found here: LoaderLock MDA (MSDN Website)