Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: "Alexander Grigoriev" <alegr@xxxxxxxxxxxxx>
- Date: Fri, 2 Sep 2005 07:09:12 -0700
Are you by any chance using PulseEvent?
How do you create cxt->semaphore?
Where do you reset cxt->IOPending (if ever)?
Is your driver calling KeEnterCriticalSection for some reason, or waiting
for a mutex object?
Is your driver handle open in FILE_FLAG_OVERLAPPED mode? Does the driver
perform synchronous operation or asynchronous?
"Tom Udale" <email@xxxxxxxxxxx> wrote in message
news:cf6dnUppNcqO2oXeRVn-uw@xxxxxxxxxxxxxx
> Alexander,
>
>> A few questions:
>> 1. Are by any chance using SuspendThread/ResumeThread?
> No.
>
>
>> 2. Are you using IoGetOverlappedResult to get the result of your
>> asynchronous operations?
> No.
>
> Entire threads code is:
>
> static DWORD WINAPI p_asyncThreadFunction(LPVOID param)
> {
> struct tag_cyiDrvAsyncContext* cxt=(struct
> tag_cyiDrvAsyncContext*)param;
>
> while(TRUE)
> {
> /* Wait for someone to tell us to do something. */
>
> verify(WaitForSingleObjectEx(cxt->semaphore,INFINITE,FALSE)==WAIT_OBJECT
> _0);
>
> if(cxt->quit) /* If we have been told to
> quit...*/
> {
> if(!cxt->quitting) /* ... see if we have already
> started the quitting procedure. If not..*/
> p_beginQuit(cxt); /* ...do so.*/
> if(!cxt->numOutstandingAPC) /* If there are no outstanding
> APCs...*/
> break; /* ...exit the thread.*/
> }
>
> if(cxt->IOPending) /* If we have been asked to make a
> call...*/
> {
> if(cxt->quit) /* ...first see if we were also
> told to quit. If so...*/
> {
> if(!cxt->quitting) /* ... see if we have already
> started the quitting procedure. If not..*/
> p_beginQuit(cxt); /* ...do so.*/
> if(!cxt->numOutstandingAPC) /* If there are no outstanding
> APCs...*/
> break; /* ...exit the thread.*/
> }
> else /* ...otherwise, do the IO.*/
> {
> cyiKerIOCallData* ioData=cxt->IOPending;
>
> cxt->ioRes=cxt->link.ioFunc /* Call the driver. This will
> block, perhaps for a _very_ long time. */
> (
> cxt->link.devDataPtr,
> ioData->func,
> ioData->in.buffer,
> ioData->in.bufferSize,
> ioData->out.buffer,
> ioData->out.bufferSize,
> &cxt->ioReturnCount
> );
> /* Driver call is finished. Schedule a callback on the original
> thread via an APC.*/
> p_scheduleAsynchCallback(cxt);
> }
> }
> }
> return 0;
> }
>
>> 3. How often you call CreateFile/CloseHandle for your driver?
>
> Once for the original load and then once per async thread.
>
>
>
>> Could you
>> accidentally call CloseHandle from one thread when another is waiting
> for
>> I/O?
> No. The open closes are all called from the main thread. And they only
> happen at startup and shutdown.
>
>
>
> Regards,
>
> Tom
>
>
>
>
>
>> "Tom Udale" <tom@xxxxxxx> wrote in message
>> news:vzPRe.5379$9i4.1727@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> > Dear Ivan,
>> >
>> >> From what I can undestant from the limited information supplied on
> the
>> >> process creation logic,
>> > When you say this, do you mean limited information about this
> specific
>> > case or limited information about how the MS compiler supplied
> startup
>> > routines work in general?
>> >
>> >> the C-Rutnime is initializing the IO information, grabbing the
> handles
>> >> from process startup information, and, it's attempting to see if
> they
>> >> are "good" file handles to set them in the standard IO internal
>> >> structures
>> >> of the C-Runtime that has been linked against your DLL.
>> > It seems plausible from the evidence. Although why on earth would
> they do
>> > that?
>> >
>> > And if this is the case, does it not imply that it is simply illegal
> to
>> > load any module into the address space of a process when the process
> has
>> > any pending IO? This seems inconceivable.
>> >
>> >> Can you elaborate on handle inheritance and process creation
> hierarchy ?
>> > Do you mean what I am doing to create all these threads/load these
> DLLs,
>> > or what the OS is doing for us? I am doing very little magic
> myself.
>> >
>> > Assuming you meant the former, the app works like this:
>> >
>> > 1) Loads. Before entering its main PeekMessage loop, it scans its
>> > directory for a variety of plugins (dynamically loaded DLLs defined
> by
>> > me).
>> >
>> > 2) User selects one dll. The dll is loaded and instructed by the
> app to
>> > initialize itself. That in turn does some scanning of it own for
> some
>> > second tier plugins. This is where the dll that talks to the driver
> gets
>> > loaded, kscam_d4. kscam_d4 loads its closely coupled driver
> component,
>> > kscam_kw.
>> >
>> > 3) After the tree of dlls (and in some cases dll/driver pairs) is
> build,
>> > the app enters an intermediate state, effectivly a "preview" state,
> where
>> > all these threads are created (including the one that blocks on the
> pended
>> > IOCTRL). It is during the setup phase of this state that kscam_d4
> creates
>> > its notification thread and blocks on the a "notification callback"
> ioctrl
>> > it sends to the kscam_kw driver. After the setup phase, the app
> runs some
>> > sample data collection and allows the user to configure parameters
> for an
>> > "acquire" state.
>> >
>> > 4) The user selects to enter what is the "acquire" state.
>> >
>> > 5) All the preview threads are shut down, many of which end up
> blocking on
>> > one thing or another. The app is now ready to enter the "acquire"
> state.
>> > At this point, only the main app thread is active.
>> >
>> > 6) The main app goes to load its "full" GUI for the "acquire" state.
> This
>> > involves loading some other plugins. One of which is the monoatd4
> library
>> > that causes the deadlock.
>> >
>> >
>> > Some points about all these DLLs: They are all built from a common
>> > framework of my own creation. These dlls do nothing in the DLL
> main. All
>> > of them create their internal structures and/or load secondary dlls
> in
>> > response to explicit calls from the loading code through an exported
>> > function. Nothing more than standard CRT/C++ global initializers
> are
>> > called during DLLMain.
>> >
>> > I do not do any kind of clever thread local storage, system event
> hooking,
>> > or anything interesting of that nature that I am aware of.
>> >
>> >
>> >> Honestly, I cannot think of any good reason to have a handle to a
> file of
>> >> a custom driver in the startup information of a process.
>> > Nor I. I was hoping you, or someone else could elaborate on this
> point.
>> >
>> > In fact, I have no idea how I would get a handle of my own choosing
> into
>> > the startup information of a process even if I wanted to (by startup
>> > information I am assuming that you mean overriding the standard CRT
>> > handles such as stdin, stdout and so-on).
>> >
>> > I guess I will try to step through this startup code tomorrow.
>> >
>> > Oh that reminds me of one other thing. This failure only seems to
>> > transpire when I have launched the app from the Visual Studio IDE
> (F5). If
>> > I run it directly or without the debugger (ctrl-F5) it is fine. I
> had
>> > always assumed that the entire problem was a race condition so I did
> not
>> > figure this bit of data was that important in the sense of being
> causal.
>> > I had figured that the debugger was either slowing things down
> enough to
>> > cause the race winner to be different or changing the memory
> environment
>> > in such a way as to cause an uninitialized pointer to be less
> benign.
>> >
>> > Is it possible that this is _entirely_ a side effect of the
> debugger? Not
>> > that I can let that go as completing this project without the IDE
> debugger
>> > would be painful to say the least.
>> >
>> > At any rate, the reason I am reminded of this is that I would like
> to use
>> > windbg to step through this code as it has much more accurate call
> stacks
>> > and so on. But, I cannot figure out how to set the breakpoint.
>> >
>> > Devstudio and windbg both use int 3 for breakpoints. If I set the
> int 3
>> > from windbg, it is actually trapped first by devstudio which then
> takes
>> > over. I cannot figure out how to transfer control from devstudio,
> or
>> > alternately, prevent it from trapping int 3s from the get-go.
> Softice
>> > solves this sort of thing by allowing you to turn on and off int 3
>> > trapping. Is there something analogous for DevStudio? I could not
> find
>> > it.
>> >
>> > Thanks again for your input.
>> >
>> > Best regards,
>> >
>> > Tom Udale
>>
>>
>
>
.
- Follow-Ups:
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Tom Udale
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- References:
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Ivan Brugiolo [MSFT]
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Tom Udale
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Ivan Brugiolo [MSFT]
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Tom Udale
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Alexander Grigoriev
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- From: Tom Udale
- Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- Prev by Date: Re: Add local port
- Next by Date: Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- Previous by thread: Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- Next by thread: Re: Reprise: Pended IOCtrl + LoadLibrary == Deadlock?
- Index(es):
Relevant Pages
|