Nuance deadlock on console output redirection.

来源:互联网 发布:linux安装下载好的内核 编辑:程序博客网 时间:2024/05/21 22:34

I helped a colleague on debugging the program she wrote. It's so weird that if we invoke  the program directly by cmd.exe, it executes perfectly. However, if we invoke it from another program wrote by she, both programs just hung there.

 

I went through the code and there is nothing special. So I use Windbg attached the the child process and printed out call stack of every thread, I saw main thread was blocked on NtWriteFile. So I checked the handle used by NtWriteFile, but there was not much info useful. So I went ahead checked all critical sections but it seems there was no dead lock in the child process. I made a mistake here: I did not check the parent process to see where it's blocked!

 

Since nothing found via debugger, I went back to look at the codes and I see something like this in the parent process' code:

Process cp = Process.Start(CurrentCommand);cp.WaitForExit();RedirectStandard(cp);


Wow, seems there is something wrong. You can see that parent process is waiting for child process to exit so that it can read it output. What if the child process' output buffer is full before it finishes its job and exit?

 

Things become clear here. After changing the sequence, the hung issue gone. After that I seached the web for the buffer size, I did not find out the exact size of the buffer, but I did find out someone encounters the similar issue before, however, he/she used a different approach.

 

Ref link:

http://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why

 

Addtional Notes:

If you only need to redirect only one of stdout / stderr, it's fine to simply switch the sequence of the wait for exit and the redirection. But if you need to redirect both of them, then you will need to implement an async redirection pattern, as the link provided.