[RESOLVED] Sometimes VirtualDub hangs with no error message

Support forum for DGDecNV
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

OK, thanks. Can you also collect the stacks for the two Veedub64 instances?
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

You mean one stack when not hanging, and one stack when hanging ? I should be able to do the first very soon, and it will also validate that i'll provide you the correct thing.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

No I mean that when you show Properties for Veedub64, there will be two threads labeled Veedub64.exe. I'd like to see the stacks for both.

I only need data for the hanging case because I can get the data for normal operation myself.

Thanks!
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

FYI, here is the stack I see for DGDecodeNV after opening a file and seeing the first frame displayed in Vdub:

ntdll.dll!ZwWaitForMultipleObjects+0xa
KERNELBASE.dll!WaitForMultipleObjectsEx+0xed
KERNEL32.DLL!WaitForMultipleObjects+0xf
dgdecodenv.dll!CAVCDecoder::DisplayPicture+0xd5
dgdecodenv.dll!CAVCDecoder::DHandlePictureDisplay+0x32
dgdecodenv.dll!CAVCDecoder::DisplayPicture+0x2b6
nvcuvid.dll!cuvidCtxUnlock+0x67300
nvcuvid.dll!cuvidCtxUnlock+0x143912
nvcuvid.dll!cuvidCtxUnlock+0x14318d
nvcuvid.dll!cuvidCtxUnlock+0x68212
dgdecodenv.dll!CAVCDecoder::decoder_decode_nalu+0xb9
dgdecodenv.dll!CAVCDecoder::AVCDecode+0x577
dgdecodenv.dll!CAVCDecoder::ThreadFunc+0xe8
KERNEL32.DLL!BaseThreadInitThunk+0x22
ntdll.dll!RtlUserThreadStart+0x34

After displaying the picture a wait is executed for a signal to come from the next execution of Avisynth's GetFrame().

Both Vdub threads are also waiting on signals, as we would expect.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

admin wrote:No I mean that when you show Properties for Veedub64, there will be two threads labeled Veedub64.exe.
Ah... Yes, indeed there is 2 threads.
Ok, i'll do that next time it occurs.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

Sweet. Thank you.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Here is the result.
Hope it can help figure out at least if the suspect is the guilty.

Code: Select all

VDUB64 process-1

ntoskrnl.exe!memset+0x64a
ntoskrnl.exe!KeWaitForMultipleObjects+0xd52
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!PoStartNextPowerIrp+0xbd4
ntoskrnl.exe!PoStartNextPowerIrp+0x186d
ntoskrnl.exe!KeWaitForMultipleObjects+0xf5d
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!NtWaitForSingleObject+0xde
ntoskrnl.exe!KeSynchronizeExecution+0x3a23
ntdll.dll!NtWaitForSingleObject+0xa
KERNELBASE.dll!WaitForSingleObjectEx+0x9c
DGDecodeNV.dll!CAVCDecoder::ThreadFunc+0x20d9
AviSynth.dll!DllGetClassObject+0xab8
AviSynth.dll!avs_vsprintf+0x2d24
AviSynth.dll!DllGetClassObject+0xc82
AviSynth.dll!DllGetClassObject+0x27e10
AviSynth.dll!DllGetClassObject+0xc82
AviSynth.dll!avs_get_height_p+0x2191
AviSynth.dll!avs_get_height_p+0x1cc2
AviSynth.dll!avs_get_height_p+0x1d6c
AVIFIL32.dll!AVIStreamRead+0x2a
Veedub64.exe+0xfe012
Veedub64.exe+0x1167f1
Veedub64.exe+0xff2a4
Veedub64.exe+0x42cea
Veedub64.exe+0x80885
Veedub64.exe+0x82632
Veedub64.exe+0x84fb4
Veedub64.exe+0x91219
Veedub64.exe+0x919bc
Veedub64.exe+0xa23f3
USER32.dll!TranslateMessageEx+0x29d
USER32.dll!TranslateMessage+0x1e2
Veedub64.exe+0x6cd8e
Veedub64.exe+0x226674
kernel32.dll!BaseThreadInitThunk+0xd
ntdll.dll!RtlUserThreadStart+0x21
ntoskrnl.exe!memset+0x64a
ntoskrnl.exe!KeWaitForMultipleObjects+0xd52
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!PoStartNextPowerIrp+0xbd4
ntoskrnl.exe!PoStartNextPowerIrp+0x186d
ntoskrnl.exe!KeWaitForMultipleObjects+0xf5d
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!NtWaitForSingleObject+0xde
ntoskrnl.exe!KeSynchronizeExecution+0x3a23
ntdll.dll!NtWaitForSingleObject+0xa
KERNELBASE.dll!WaitForSingleObjectEx+0x9c
DGDecodeNV.dll!CAVCDecoder::ThreadFunc+0x20d9
AviSynth.dll!DllGetClassObject+0xab8
AviSynth.dll!avs_vsprintf+0x2d24
AviSynth.dll!DllGetClassObject+0xc82
AviSynth.dll!DllGetClassObject+0x27e10
AviSynth.dll!DllGetClassObject+0xc82
AviSynth.dll!avs_get_height_p+0x2191
AviSynth.dll!avs_get_height_p+0x1cc2
AviSynth.dll!avs_get_height_p+0x1d6c
AVIFIL32.dll!AVIStreamRead+0x2a
Veedub64.exe+0xfe012
Veedub64.exe+0x1167f1
Veedub64.exe+0xff2a4
Veedub64.exe+0x42cea
Veedub64.exe+0x80885
Veedub64.exe+0x82632
Veedub64.exe+0x84fb4
Veedub64.exe+0x91219
Veedub64.exe+0x919bc
Veedub64.exe+0xa23f3
USER32.dll!TranslateMessageEx+0x29d
USER32.dll!TranslateMessage+0x1e2
Veedub64.exe+0x6cd8e
Veedub64.exe+0x226674
kernel32.dll!BaseThreadInitThunk+0xd
ntdll.dll!RtlUserThreadStart+0x21


VDUB64 process-2
ntoskrnl.exe!memset+0x64a
ntoskrnl.exe!KeWaitForMultipleObjects+0xd52
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!PoStartNextPowerIrp+0xbd4
ntoskrnl.exe!PoStartNextPowerIrp+0x186d
ntoskrnl.exe!KeWaitForMultipleObjects+0xf5d
ntoskrnl.exe!KeWaitForMultipleObjects+0x26a
win32k.sys!memset+0x7c97
win32k.sys!memset+0x7d59
win32k.sys!W32pArgumentTable+0xaa72
ntoskrnl.exe!KeSynchronizeExecution+0x3a23
USER32.dll!WaitMessage+0xa
Veedub64.exe+0x1f07ef
Veedub64.exe+0x13bf8e
Veedub64.exe+0x226ff3
Veedub64.exe+0x227087
kernel32.dll!BaseThreadInitThunk+0xd
ntdll.dll!RtlUserThreadStart+0x21


DGDecodeNV
ntoskrnl.exe!memset+0x64a
ntoskrnl.exe!KeWaitForMultipleObjects+0xd52
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!PoStartNextPowerIrp+0xbd4
ntoskrnl.exe!PoStartNextPowerIrp+0x186d
ntoskrnl.exe!KeWaitForMultipleObjects+0xf5d
ntoskrnl.exe!KeWaitForMultipleObjects+0x26a
ntoskrnl.exe!NtWaitForSingleObject+0x41f
ntoskrnl.exe!NtWaitForSingleObject+0x78e
ntoskrnl.exe!KeSynchronizeExecution+0x3a23
ntdll.dll!ZwWaitForMultipleObjects+0xa
KERNELBASE.dll!GetCurrentProcess+0x40
kernel32.dll!WaitForMultipleObjects+0xb0
DGDecodeNV.dll!CAVCDecoder::ThreadFunc+0xcd
kernel32.dll!BaseThreadInitThunk+0xd
ntdll.dll!RtlUserThreadStart+0x21
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

DGDecodeNV is not getting a frame request so it sits there waiting for Avisynth to invoke GetFrame(). I may have to study VirtualDub source code to see why nobody is asking DGDecodeNV to do anything. Maybe there is a race condition leading to a deadlock. I can make a debug version for you to see if that is happening. The VirtualDub stack does not show it ever asking Avisynth for a frame, although it does query properties.

Let me cogitate on things.

Thank you for the traces.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

I have a theory. Investigating... :wow:
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

I don't know if it can help and if it's even related, but here something i've noticed, just in case of...
I've noticed that the time for the 1rst frame to be displayed when i open a file is variable. It can be very fast, and sometimes it can be "long", a little more than one second (or something like that), making me believe, for a very short time, that VDub has hanged.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

My current theory is that there is a race condition such that this desired order:

VD instantiates DGDecodeNV
DGDecodeNV completes init and waits on the first GetFrame() call
VD asks for the first frame and Avisynth calls GetFrame()
DGDecodeNV is awoken by GetFrame() and starts decoding

...becomes:

VD instantiates DGDecodeNV
VD asks for the first frame and Avisynth calls GetFrame()
DGDecodeNV completes init and waits on the first GetFrame() call
DGDecodeNV hangs because it had not yet started waiting before the first GetFrame() call
VD hangs because the previous GetFrame() call never completed

It all depends on how fast VD is in asking for the first frame. My code currently does not exclude this scenario where VD is "too fast". I am testing a fix and will give it to you in a few minutes.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

Please re-download 2052 and update both DGIndexNV and DGDecodeNV. I am hopeful that there will be no further hangs. Please test and report.

Note that this slipstream includes another change (HEVC 10-bit support) that bumps the DGI file version, so you must re-make your index files.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Ok, thanks, i will. It will take a little while before i'll be able to report.

At first glance i found strange that you "leave Instance" before it's fully finished, so somehow i'm not surprise of this kind of things happen. I'm even surprised that it's not happened before... :o
It's just a little thought that immediatly pops when i've seen this part :
DGDecodeNV completes init and waits on the first GetFrame() call
=> Meaning VD continue in parallel because you've leaved/ended the instance part code, but the init is still not yet finished... :shock:
=> Meaning also i may have misunderstood what you've said with this... :scratch:
But... I don't know how decode pluggins work, and neither if when VD instantiates a pluggin it also "continues" in parallel without waiting the end of instance (which would be strange). :?
Now, if it's because VD is "too fast", well, it's indeed an i7-6950x overclocked at 4,1GHz :geek: So... It increases the chances indeed of being "too fast".
And i've use lot of smiles... :lol:
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

"At first glance i found strange that you "leave Instance" before it's fully finished"

To be fully finished I have to execute the wait, but if I wait I can't inform the VD thread to return. If Win32 had a clean way to determine if a thread is waiting I could solve this deterministically (by having the VD thread return when it sees my thread start waiting), but for now I have solved it heuristically. There is a simple managed solution but my code is not managed. And there apparently is a WMI API used by debuggers but it's total overkill.

The full explanation is involved and I'd have to show you the code for your full understanding. Suffice to say I believe I have solved the race condition. Your testing will determine if that is the case.

Cut me some slack; one doesn't always anticipate all race conditions, especially in a complex application.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

admin wrote: Cut me some slack; one doesn't always anticipate all race conditions, especially in a complex application.
For having created a threadpool for my needs (and very probably very less complex than your application), i know...
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

I've never done decoding avs pluggin, only standard filters. I have the code of rawsource, very simple, but i've been able to check if something was different from a standard filter, and didn't see anything.
I have to assume that your dgdecodenv has a more complex structure than the standard "Create/Constructor/Getframe" calling, because i don't understand the part where "you wait", neither what you're waiting for (probably a WaitForSingleObject, but what is the object ?). In a classic standard "Create/Constructor/Getframe" calling, there is no wait, but obviously we are not in a classic case.
If i take a look at the code of dgindex, is it possible that i can see what you mean ? (I had it once, but i have to retrieve it to check).

After, you said it's solved, i'll take your word.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

I said I'm hopeful it is resolved. ;)

Yes, DGDecodeNV is more complicated than a simple filter, mainly due to threading needs imposed by CUVID. Therefore, looking at DGIndex won't enlighten you.

Just think about the catch22: I'm not done until I wait, and if I wait I can't release VD to continue, so I have to release VD just before I execute the wait. It's a tiny window but you have been hitting it apparently. We'll see.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Just to understand globaly the situation :

A thread (or a process) will call A, start a thread (or a process) call B.
A "stop/wait" for B to finish before continue.
And B has finished only when is begining to wait.
My first idea of course will be to wait for event (With CreateEvent, WaitForSingleObject), and if you don't know it, take a look at what i've discovered yesterday when checking what kind of fuction exist SignalObjectAndWait :
https://msdn.microsoft.com/fr-fr/librar ... s.85).aspx
And i think using this function will prevent the issue, because it's probably "mono...." don't rememeber the word, but basicaly while executing SignalObjectAndWait, no other code can be run in parallel.
So basicaly, A create an event, start thread B, providing to it the handle of the event, and then A wait for this event.
B do its stuff, and when finished, call SignalObjectAndWait.
What do you think ? Unless it's allready what you've done, or you're telling me that B wait for multiple objects...
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

I was not aware of the SignalObjectAndWait() function. Thanks for bringing it to my attention.

Unfortunately, my thread does wait on two events. I may be able to revise it to use a single event with a flag to indicate the invoker.

Strangely, SignalObjectAndWait() is said to not be atomic. :?
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Euh... Stupid remark from me. Of course a waiting function can't be atomic... Otherwise it will be a little... troublesome to execute the code the function is waiting for. But probably that the "setting" part is. Anyway, my first guess is that it's probably the most proper way to do what you want to.
After, if your thread is waiting for 2 events with a waitformultipleobject, maybe you can just split it with 2 waitforsingleobject,
transforming waitformultipleobject in :
SignalObjectAndWait(xx,A)
waitforsingleobject(B)
without modifying anything and/or using a flag.
waitformultipleobject on 2 objects or 2 waitforsingleobject will produce the same result, it's just that waitformultipleobject is a little more optimized in performance, but both will produce the exact same synchronisation result. In your situation (or at least what i think i've understood from), just splitting with SignalObjectAndWait and waitforsingleobject will do the trick.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

I'll experiment with it today. Thank you for the ideas. Obviously a deterministic solution is preferred.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

I just slipstreamed my latest version of this fix. Please run with this one and let me know if it ever hangs again. Thanks.
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Thanks for your work :bow:
Just out of curiosity, if my guess is roughly correct, according what you've said.
In the constructor (i was hesitating between creator/constructor, but constructeur seems more logical), you start a thread to handle all the CUDA things. This thread init things, and when done, wait for a getframe (and maybe other things). When this "CUDA thread" has finished its init and is waiting, you have to notify the constructor that it's finished and it can itself finish.
In the getframe, you trig an event to tell the "CUDA thread" that you've received a getframe.
So is it, roughly, something like this ?
DAE avatar
jpsdr
Posts: 214
Joined: Tue Sep 21, 2010 4:16 am

Re: Sometimes VirtualDub hangs with no error message

Post by jpsdr »

Don't want to patronize or anything, just giving suggestion if needed, in case my guess is correct.
If not needed or don't want it, just ignore, absolutely no hard feelings.
My suggestion :

Code: Select all

constructor
{
  Doing stuff
  Creating E1 Event.
  Starting "CUDA Thread"
  // Waiting "CUDA Thread" finished
  WaitForSingleEvent(E1)
  Destroying E1 event
  (will not be needed anymore, don't waste resources for nothing).
}

Destructor
{
  Destroy E2 to E6
}

CUDA Thread
{
  Doing Init Stuff
  // Init is done, i'm ready, notify constructor
  SetEvent(E1)
  While whateever_exit_or_ending_filter_condition_is
  {
     WaitForMultipleEvent(E2,E3)
     ResetEvent(E2)
     ResetEvent(E3)
     // Don't know what E3 is, don't care, it will follow the same idea than GetFrame
     // Doing CUDA stuff
     // Notify GetFrame 1rst part of CUDA Stuff is done
     SetEvent(E4)
     // Waiting GetFrame notifying its part is done
     WaitForSingleEvent(E5)
     ResetEvent(E5)
     // Doing CUDA stuff
     // Notify GetFrame 2nd and last part of CUDA Stuff is done
     SetEvent(E6)
  }
  Doing Ending stuff
}

GetFrame
{
  Do Things
  // Notify CUDA it can do its stuff 
  SetEvent(E2)
  // Waiting CUDA finishing part of its job.
  WaitForSingleEvent(E4)
  ResetEvent(E4)
  Do things
  // Notify CUDA it can do the 2nd part
  SetEvent(E5)
  // Waiting CUDA finishing part of its job.
  WaitForSingleEvent(E6)
  ResetEvent(E6)
  Do things
}
In that case, even if Getframe is called between the tiny interval, it shouldn't matter, the event was already trigged, there will just be no wait. Ajust according the number of dispatching jobs between both.
User avatar
admin
Posts: 4551
Joined: Thu Sep 09, 2010 3:08 pm

Re: Sometimes VirtualDub hangs with no error message

Post by admin »

"If not needed or don't want it, just ignore"

OK.

Please advise the results of testing my last slipstream.
Post Reply