-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash 0x406d1388 with .NET bindings (for ffmpeg >= 6 because of ff_thread_setname) - mingw bug #412
Comments
Not sure what you're asking. Those codes mean nothing. Looks like a "good old crash" to me, so you're probably doing something wrong in your code. |
I'm pretty sure the issue is with the compilation as Gyan's same version works. One more thought ... possible the SDL version? |
Do you have a commandline that reproduces the crash? |
It happens only when using the libraries as native from Visual Studio (eg. with FFmpeg.AutoGen) but I'm using a custom generator for now with 7.1 that FFmpeg.AutoGen does not support yet. Not sure if it happens with v6.x. I might have a git repo for generator and with a reproducible project to test tomorrow. |
I can't really make any promises when using them from Visual Studio. |
One reason that I'm using a custom Generator is that. To fix all the type sizes issues that currently FFmpeg. Autogen has. But I'm pretty sure that the issue is not with the type sizes. |
What do you mean by "custom Generator", and how does ffmpeg have type size issues? |
FFmpeg.Autogen is an FFmpeg auto generated unsafe bindings for C#/.NET and Core (Linux, MacOS and Mono). |
Ah, yes. autogen.sh is often the script to generate an autotools based build system. |
It takes too long to build the docker and compile so until then ... Update 1: Building a fresh image docker win64 and compiling 7.1 gave me the same issue so far Update 5: Confirmed that by downgrading just mingw to f6b0870e4de11fd04155511606bb6e6564d38c71 commit fixes the issue |
Here is a minimal reproducible example (.NET 8 x64 C#) using System.Runtime.InteropServices;
using System.Security;
namespace BtbNThreadNamingCrash;
unsafe internal partial class Program
{
static void Main(string[] args)
{
LoadFFmpegLibraries(@"c:\FFmpeg\BtbN\x64");
var codec = avcodec_find_decoder_by_name("h264");
var avctx = avcodec_alloc_context3(codec);
void* dict = null;
//av_dict_set(&dict, "threads", "1", 0); // success
av_dict_set(&dict, "threads", "2", 0); // failed
var ret = avcodec_open2(avctx, null, &dict);
Thread.Sleep(3000);
Console.WriteLine("Success");
}
public const string AVCODEC = "avcodec";
public const string AVDEVICE = "avdevice";
public const string AVFILTER = "avfilter";
public const string AVFORMAT = "avformat";
public const string AVUTIL = "avutil";
public const string POSTPROC = "postproc";
public const string SWRESAMPLE = "swresample";
public const string SWSCALE = "swscale";
public static Dictionary<string, nint> libToPtr = [];
public static void LoadFFmpegLibraries(string ffmpegPath)
{
var files = Directory.GetFiles(ffmpegPath, $"{AVUTIL}*.dll");
libToPtr[AVUTIL] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{SWSCALE}*.dll");
libToPtr[SWSCALE] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{SWRESAMPLE}*.dll");
libToPtr[SWRESAMPLE] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{POSTPROC}*.dll");
libToPtr[POSTPROC] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{AVCODEC}*.dll");
libToPtr[AVCODEC] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{AVFORMAT}*.dll");
libToPtr[AVFORMAT] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{AVFILTER}*.dll");
libToPtr[AVFILTER] = LoadLibraryW(files[0]);
files = Directory.GetFiles(ffmpegPath, $"{AVDEVICE}*.dll");
libToPtr[AVDEVICE] = LoadLibraryW(files[0]);
NativeLibrary.SetDllImportResolver(typeof(Program).Assembly, DllImportResolver);
}
private static IntPtr DllImportResolver(string libraryName, System.Reflection.Assembly assembly, DllImportSearchPath? searchPath)
{
libToPtr.TryGetValue(libraryName, out var ptr);
return ptr;
}
[DllImport("kernel32", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true), SuppressUnmanagedCodeSecurity]
public static extern IntPtr LoadLibraryW(string dllToLoad);
[DllImport(AVCODEC, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
public static extern void* avcodec_alloc_context3(void* codec);
[DllImport(AVCODEC, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
public static extern int avcodec_open2(void* avctx, void* codec, void** options);
[DllImport(AVCODEC, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
public static extern void* avcodec_find_decoder_by_name([MarshalAs(UnmanagedType.LPUTF8Str)] string name);
[DllImport(AVUTIL, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
public static extern int av_dict_set(void** pm, [MarshalAs(UnmanagedType.LPUTF8Str)] string key, [MarshalAs(UnmanagedType.LPUTF8Str)] string value, int flags);
} |
Quick VS solution zip Testing the latest Auto-Builds 7.1 fails, 6.1 fails, 5.1 works fine (checking FFmpeg's code they don't use ff_thread_setname on 5.1) |
This doesn't seem like an issue with the builds to me still. Or I'm not sure what you're asking from me. |
There are a lot of people using FFmpeg libraries with .NET bindings that they have this issue and they don't even know it. I'm pretty sure I've provided enough information, so you can see that the issue is with your builds as it does not happen with Gyan's builds (just run the project I've attached). I've even provided a workaround by downgrading MinGW (couldn't investigate this further, at least for now). The issue is critical and you should leave it open, even if you don't care, so other people will be informed and possible contribute resolving this. |
I don't doubt that there is an issue. But I have no experience with the .NET bindings and their inner working, or developing with C# native bindings in general. I generally don't understand what issue you are trying to point to. What does the thread name have to do with it? If the C# bindings crash depending on a thread name, that looks like a bug in the bindings to me? |
It all starts from a stupid MS way to set the thread name from native/managed code (which raises DWORD MS_VC_EXCEPTION = 0x406D1388). MS - Tips for debugging threads I'm not sure what exactly happens, if it thinks that there is a debugger attached or doesn't check at all so even at release mode it throws that exception and the app crashes. It is also possible that FFmpeg should catch that exception, but I think probably the issue is down to mingw. Not even sure if you could 'configure' the threading from your builds (eg. you have some configs for pthreads/winpthreads) |
Hi, it seems there are some compilation flags that causing this issue (which is related with thread naming). It mainly happens when I try to set the tread_count > 1 and then opening the codec. I've tested same ffmpeg version (7.1) with gyan's releases and was working fine.
Possible related compilation flags here?
https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/thread.h
The text was updated successfully, but these errors were encountered: