AviSynth / AviSynthPlus

AviSynth with improvements
http://avs-plus.net
934 stars 73 forks source link

MPV + AVISource = Crash #188

Open belonesox opened 3 years ago

belonesox commented 3 years ago

MPV + AVISource = Crash

Very old bug (I see it several years, sometimes whining on [1] MPV project, because it reproduced with MPV, not VirtualDub or ffplay, but it is actually AVS bug. ). I just retest it on

commit ac90e98e0e51f7bcd6b321c48fab0a7db1e69b9e (HEAD -> master, origin/master, origin/HEAD)
Author: Pinterf <pinterfer@gmail.com>
Date:   Tue Sep 1 11:01:30 2020 +0200

cmake -A Win32 CMAKE_BUILD_TYPE=Debug ..

VS2019

and it still reproduced.

I attached all needed to reproduce (see https://drive.google.com/file/d/1BnsbLrcWNHN1yXGfDkqWwxxl8lyAtCoG/view?usp=sharing):


to reproduce, run:

bug-mjpeg.bat 

we got crash with

ff_vfw.dll!7be44f19()
ff_vfw.dll![Frames below may be incorrect and/or missing, no symbols loaded for ff_vfw.dll]
msvfw32.dll!_ICSendMessage@16()
051a0530()
AviSynth.dll!AlignPlanar::GetFrame(int n, IScriptEnvironment * env) Line 51
    at C:\projects\avsplus\upstream\AviSynthPlus\avs_core\core\alignplanar.cpp(51)
AviSynth.dll!MTGuard::GetFrame(int n, IScriptEnvironment * env) Line 125
    at C:\projects\avsplus\upstream\AviSynthPlus\avs_core\core\MTGuard.cpp(125)
AviSynth.dll!Cache::GetFrame(int n, IScriptEnvironment * env_) Line 216
    at C:\projects\avsplus\upstream\AviSynthPlus\avs_core\core\cache.cpp(216)
AviSynth.dll!CacheGuard::GetFrame(int n, IScriptEnvironment * env) Line 505
    at C:\projects\avsplus\upstream\AviSynthPlus\avs_core\core\cache.cpp(505)
AviSynth.dll!avs_get_frame(AVS_Clip * p, int n) Line 822
    at C:\projects\avsplus\upstream\AviSynthPlus\avs_core\core\avisynth_c.cpp(822)
mpv.exe!00bb4546()
mpv.exe!00bb4755()
mpv.exe!00cebe3e()
mpv.exe!00ced4d0()
mpv.exe!00ceeadd()
mpv.exe!0045f15d()
mpv.exe!00455f09()
mpv.exe!0045722f()
mpv.exe!00546d39()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8()

Definitely something wrong with cache implementation

(after path to case LRU_LOOKUP_NO_CACHE → MTGuard → we got nulls in cached child on child->GetFrame(n, env);)

Because of 10MB restrictions I also attached demo files without MPV/AVisynth but better was download https://drive.google.com/file/d/1BnsbLrcWNHN1yXGfDkqWwxxl8lyAtCoG/view?usp=sharing

to_tracker.zip

pinterf commented 3 years ago

Can you give me a quick help with "couldn't locate a decompressor for fourcc MJPG"

belonesox commented 3 years ago

Ohh. Please install http://ffdshow-tryout.sourceforge.net/ (32bit for 32bit AVS+) May be the problem somehow related to ffdshow. If I use AVISource for video with «msvideo1 (CRAM / 0x4D415243)» codec, no crash. If I use AViSource for MJPEG/HDV/… codecs, provided from ffdshow → crash, so please, install ffdshow-tryout.

Also, run

  "C:\Windows\SysWOW64\rundll32.exe" "C:\Windows\SysWOW64\ff_vfw.dll",configureVFW

to check that MJPEG codecs enabled.

image

It possible to select «libmpeg2» or «libavcodec», crash still occured.

pinterf commented 3 years ago

So ffdshow is a prequisite and we are hunting a possible ffdshow codec problem? Is the whole video stream going through ffdshow?

pinterf commented 3 years ago

I'm just asking because I investigated an ffdshow problem a month ago and there were issues on IScriptEnvironment handing (+other bugs) https://github.com/AviSynth/AviSynthPlus/issues/178#issuecomment-669083106 Anyway I could look at it independently from this question.

pinterf commented 3 years ago

Note: In ffdshow configuration it is not the "MPEG in AVI" section but "MJPEG" which had to be set to libavcodec. After this latter setting the error "couldn't locate a decompressor for fourcc MJPG" disappeared.

pinterf commented 3 years ago

First run w/o process attach

'mpv.com' (Win32): Loaded 'C:\Tape13\Test20160220\AvsMeter\AVSMeter216\20200907_Avisource\to_tracker\mpv.com'. Module was built without symbols.
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. 
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. 
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. 
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. 
The thread 0x7ce8 has exited with code 0 (0x0).
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. 
'mpv.com' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. 
The thread 0x84d4 has exited with code -1073741819 (0xc0000005).
The thread 0x2e54 has exited with code -1073741819 (0xc0000005).
The program '[0x93FC] mpv.com' has exited with code -1073741819 (0xc0000005) 'Access violation'.

Then I put an AssumeFPS(1) in avs script to give myself time to attach mvp.exe to the process, then it showed that the access violation comes from the exit, in ICDecompressEnd(hic) in AviSource::CleanUp

Exception thrown at 0x0000006E in mpv.exe: 0xC0000005: Access violation executing location 0x0000006E.

In avi_source.cpp:

void AVISource::CleanUp() { // Tritical - Jan 2006
  if (hic) {
    !ex ? ICDecompressEnd(hic) : ICDecompressExEnd(hic);
    ICClose(hic);
  }

(hic is pointing to msvfw32.dll!0x6989b320)

Edit: next time crash: Exception thrown at 0x7A0B4F04 (ff_vfw.dll) in mpv.exe: 0xC0000005: Access violation reading location 0x0B2B7654.

belonesox commented 3 years ago

So ffdshow is a prequisite and we are hunting a possible ffdshow codec problem? Is the whole video stream going through ffdshow?

Highly likely. I tried with some codecs not from ffdshow (msvideo, x264vfw) — no crash.

In ffdshow configuration it is not the "MPEG in AVI" section but "MJPEG" which had to be set to libavcodec.

Of course, my mistake, sorry.

belonesox commented 3 years ago

Then I put an AssumeFPS(1) in avs script to give myself time to attach mvp.exe to the process

Hmm. Why not just run it from directory where AviSynth.pdb located, and run debugging in VS, when crash occured? Like this https://vimeo.com/453012067/52c97a2b53

Also I see another stack in "my crash" (pls, look at video)… May be somethink different in our setups… Should I prepare VirtualBox VM?

pinterf commented 3 years ago

It simply did not offer me to do that, simply exited. Now I found this and disabled the windows error reporting disabling: https://monitormyweb.com/guides/how-to-disable-stopped-working-message-in-windows edit: but my crash is still in AVISource::CleanUp(), in ICDecompressEnd(hic)

pinterf commented 3 years ago

Made a debug build of ffdshow.ax (which is really a dll), and now it shows heap corruption on dll exit. I'd exclude that it is a specific AviSynth+ frame caching error. It can still be a buffer overwrite in any of the components ffdshow.ax, ff_vfw, mjpeg codec, even avisynth etc.. involved.

belonesox commented 3 years ago

I reproduced all this in isolated VM (Virtualbox OVA http://bit.do/188_avsbug-demo-v001 , login vagrant/vagrant , 11GB, run C:\projects\avsplus\upstream\AviSynthPlus\build\avs_core\Debug\bug-mjpeg.bat )

and got stack slightly different from stack from first comment and, it is probably different from "your" stack

>   AviSynth.dll!AVISource::DecompressFrame(int n, bool preroll, IScriptEnvironment * env) Line 352 C++
    AviSynth.dll!AVISource::GetFrame(int n, IScriptEnvironment * env) Line 1314 C++
    AviSynth.dll!AlignPlanar::GetFrame(int n, IScriptEnvironment * env) Line 51 C++
    AviSynth.dll!MTGuard::GetFrame(int n, IScriptEnvironment * env) Line 125    C++
    AviSynth.dll!Cache::GetFrame(int n, IScriptEnvironment * env_) Line 216 C++
    AviSynth.dll!CacheGuard::GetFrame(int n, IScriptEnvironment * env) Line 505 C++
    AviSynth.dll!avs_get_frame(AVS_Clip * p, int n) Line 822    C++

image

May be this VM will be useful?