deadlock in alloc_osfhnd(), when fopen("NUL:",w) and _pipe() called in multithread environment

I am facing thread deadlock in following scenario

thread1 -> calls _pipe(filedes,4096,0);
thread 2 -> calls fopen with NULL device. fopen("NUL:","w");

this deadlock is happening randomly. i am using libcmt.lib. is this some know issue ?
i couldnt find any KB article as well. Please some one guide me.

Thanks in advance
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cannanifyAuthor Commented:
I am adding a sample console application to simulate the problem.

-> since dsp & dsw not allowed extn couldnt upload the entire application.
   Please add macro WRAPPRINT in preprocessor definitions of project settings.
-> I use VS6 IDE.
-> dead lock happens in few execution of the console application
-> i tried to change linker option as MDd (to use msvcrtd.lib). getting same deadlock.

Thanks in advance PipeDeadLockTestApp.C PipeDeadLockTestApp.C
Janusz CzopowikSenior Software EngineerCommented:
I downloaded your file and built a project. After running many times I was not able to reproduce your problem.

Could you give me more information about your environment? VS verion, OS version.
Does it happen when you define WRAPPRINT?
cannanifyAuthor Commented:
hi johncz,

thanks for the response. I think you are using latest IDE.

- > My environment is,

OS : win XP sp3.
vs : vs6.0 SP6

-> yes. but it happens with out this WRAPPRINT macro also.

-> i have added a swf file which will show the video recording of the issue.

-> there is some more observation ,

msvcrt.dll 7.0.2600.5512  ->      No deadlock
msvcrtd.dll 6.0.9782.0  ->   Deadlock
libcmt.lib  ->  dead lock
libcmtd.lib -> Dead lock

I think there is some fix done in msvcrt.dll . i tried to get corresponding debug version but couldnt find.  i am also not sure how this 7.0 version of dll got installed in my PC.

Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

cannanifyAuthor Commented:
Hi Johncz,

Thanks. I checked the same code in VS2008 in XP SP3. this deadlock problem is not comming.
I am not sure the exact root cause. is there a problem in CRT and is fixed in later versions?
i am trying to find in MSDN forums. is there anywhere i can get answer to this ?

one more confusion i have, In MSDN page of _pipe() there is a note " In multithreaded programs, no locking is performed. The handles returned are newly opened and should not be referenced by any thread until after the _pipe call is complete."

is this any way related with the scenario i got ?

Thanks in advance
what threading model has your vc6 project?

is there any single-threaded dll involved?

do you have dlls which were built against msvcrt.dll rather than libcmt.dll?

note, it is not recommended to using different runtime libraries in one project even if that solves some linker issues regarding the order of default libraries. unfortunately vc6 projects often had those issues.

instead of pipes i used shared memory with memory mapped files and critical section to make it thread-safe. that is faster and safer.

cannanifyAuthor Commented:
what threading model has your vc6 project?
my vc6 project has multithread model set.
is there any single-threaded dll involved?
do you have dlls which were built against msvcrt.dll rather than libcmt.dll?
No. All of the dependant libraries use MT.

I modified all the modules settings to MTd. with this also problem was comming. I tried MDd as well.
Only MD option was not giving the deadlock issue.

with MD option,the CRT library version used was latest [ msvcrt.dll 7.0.2600.5512 - aug 2004 ].
where in other CRT libraies were older [ msvcrtd.dll 6.0.9782.0 - feb 2004].

Then i created a sample and tried with VS2008. it worked. With all the options deadlock wasnt happening.  

But then , migrating is not a feasible solution by looking at the volume.

But still I wonder what is the problem. both are normal CRT calls. why should the alloc_osfhnd() got blocked. if the problem in CRT has been solved in Aug 2004, i wonder why microsoft did not release the other libraries by then.

Shared memory option i tried. this solves the issue. Even I tried to replace fopen() with createfile() and writefile() which is also solving the issue. But then there is ample amount of code needs to be modified for both the solutions. there are multiple places this has been done.

thanks for  you reply.

in my opinion the deadlock didn't happen because there was a bug in one of the runtime libraries but because in the wrong case you have both msvcrt.dll and libcmt.dll linked. in that case parts of your program would use runtime functions from different libraries what could work but fails if the functions use static information to save information of last call or if multi-threading would require synchronisation. functions of different libraries won't do such synchronization and so it could crash occasionally.

you could see whether i am right by using dependency walker (depends.exe) and check the libraries linked.

you could make own functions fmyopen, fmyread, ... which easily could replace fopen, fread, ...  and were implemented using std::ifstream, std::ofstream, or other working file access functions.

cannanifyAuthor Commented:

there is nothing wrong with the link. I have attached the dependancy snap shot FYR.
I also coouldnt believe this issue as CRT issue earlier. But working with this issue couple of months and no other conclusion is arrived.
if there is any way i could send you the sample binaries, please let me know.
May be once you see the problem , might get some idea. MT/MD dependancy walker snap
you might try the depends while the program was running. then it should show much more libraries which were loaded dynamically at runtime. it is some years ago i lastly used the depends, so i can't give you much help on that.

generally the /MD would use msvcrt.lib (and version specific msvcrtxx.lib) while /MT would use libcmt.lib.

i always prefered the msvc runtime libraries cause they made less problems. i remember some troubles when using /MT option in the past though it may be caused when mixing those options.

Janusz CzopowikSenior Software EngineerCommented:
Main thread fopen _alloc_osfhnd()
threadProc _pipe _alloc_osfhnd

It looks like both threads (main and threadProc) are deadlocked here but you are not able to see deeper tha that.
In the call stack window for the main thread, you will see the following:
Ntdll 7C90E4F4
Ntdll 7C901046
The same when you show call stack for threadProc
Ntdll 7C90E4F4
Ntdll 7C901046

Ergo, both threads have a race condition and they are deadlocked.

It is happening deeper in the NtDll library. This is why:
Both threads are trying to find a free lock handle in the lock array to be used internally by critical section. Once the free handle is found by one of the threads, this thread is trying to use it to enter critical section.
 At the same time another thread is using the same available spot and changes value of it to lock internal handle for critical section. As the result Main thread enters critical section when threadProc already entered the same critical section with different internal handle. Main is not leaving a critical section and threadProc waiting for critical section to be released and waits forever, ergo deadlock.
It was not easy to find what is going on, since I had to use VS 2005/2008 to access Windows source code and libcmtd.lib code is different in versions of SDKs for VS 6.0.
Libcmtd has changed betwee VS 6.0  and later releases starting with VS 2005 handling proper locking internally. Therefore you can classify this behavior as a bug.
The remedy is to provide your own guard preventing deadlock in the form of critical section. See file.
I wrote an app that starts PipeDeadLockTestApp.exe in the loop using threads controlling timeout.
Original code resulted in the deadlock after less than 100 runs. Modified code did not go into a deadlock after 2541 runs. I consider it to be a fix.
If you would like I can make this app available for you for downloading so you can test it your app.

Modified souce file:


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
cannanifyAuthor Commented:
thanks johnCz. this is also solving the problem. thanks for the details. but me too not able to trace whats going on inside ntdll.
i dont want to change my code for some issue in run time library. is there any patch released to solve this issue in VS6.0 ?
Janusz CzopowikSenior Software EngineerCommented:
You are not changing your code "for some issue in run time library."

There is no patch. As I have mentioned, comparing code in ntdll between versions shows that changes were made between 6.0 and later releases. I have traced the code into using VS 2005. Unfortunately VS 6.0 does not have ability to use source code servers that is why I had to map VS 6.0 trace to the source code. It is very tedious and time consuming process but in this case it ended with an explanation.

Your code should have been written this way: implementing synchronization in accessing shared resources; it does not matter what library you are using and no matter how the library's code has changed; under certain condition you may run into the same issue. This is just a good programming practice.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.