mgravell / Pipelines.Sockets.Unofficial

.NET managed sockets wrapper using the new "Pipelines" API
Other
412 stars 54 forks source link

Failing on Azure Worker role - BadImageFormatException #37

Closed jonorogers closed 5 years ago

jonorogers commented 5 years ago

Hi, using this in an Azure Worker Role project; .net 4.7.2, package reference style references. I get System.Buffers/System.IO.Pipelines assembly load errors unless both those projects are explicitly referenced; and binding redirect errors for System.Buffers unless the same version (4.4.0) is installed as Pipelines.Sockets.Unofficial uses.

Now it's throwing the following, when await is called on DefaultPipeReader.ReadAsync(): System.BadImageFormatException: 'Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)'

At the moment I'm just running locally in the Azure Compute Emulator (Azure SDK 2.9.6).

Any ideas?

mgravell commented 5 years ago

Hmmm. I don't know the the emulator is a factor here, but something sounds odd! "Unsafe" is one of 3 notoriously awkward assemblies re this problem (the other two being "Buffers" and "Numerics.Vectors"). The usual fix here is to manually add assembly binding redirects, but I don't think that will fix a bad image format problem. You could try the "preview" package (this avoids the problem by simply not appearing in the inbuilt runtime binding table), but - not one I've seen before.

On Sun, 21 Jul 2019, 16:00 Jono Rogers, notifications@github.com wrote:

Hi, using this in an Azure Worker Role project; .net 4.7.2, package reference style references. I get System.Buffers/System.IO.Pipelines assembly load errors unless both those projects are explicitly referenced; and binding redirect errors for System.Buffers unless the same version (4.4.0) is installed as Pipelines.Sockets.Unofficial uses.

Now it's throwing the following, when await is called on DefaultPipeReader.ReadAsync(): System.BadImageFormatException: 'Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)'

At the moment I'm just running locally in the Azure Compute Emulator (Azure SDK 2.9.6).

Any ideas?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/mgravell/Pipelines.Sockets.Unofficial/issues/37?email_source=notifications&email_token=AAAEHMA6OGL7EL2MQSLMO3TQAR2Z7A5CNFSM4IFSSOJ2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HAPWQ2A, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAEHMFFIJW7WVEKAUXC24LQAR2Z7ANCNFSM4IFSSOJQ .

jonorogers commented 5 years ago

Thanks for the feedback. Since last night I've been playing around trying the newer csproj format (still targeting net472) and some other bits and peices, and now (after reverting) I can't even get back to the runtime error complaining about CompilerServices.Unsafe; it's stuck on complaining about System.Buffers.

I did earlier try the preview version of CompilerServices.Unsafe with no change. I've also tried manually adding references to the DLL's, with no change - but I can't manually add a reference to System.Buffers as VS complains "A reference to System.Buffers could not be added. This component is already automatically referenced by the build system."...

My knowledge is running up against a wall here. I'm using ILSpy to see what versions of DLL's are being placed in the build folder.. Which seems correct. My local machine GAC has no entries for System.Buffers, and fuslogvw won't show any binding logging information. But these last two points might be obsfucated by the emulator.

I've also tried just crossing my fingers and deploying to Azure, but it displayed the same issues running on Azure as well :/

For reference I also created a new .NET 4.7.2 console project and tested; everything works as expected (without needing to add any binding redirects or explicitly referencing System.IO.Pipelines, System.Buffers or System.Runtime.CompilerServices.Unsafe).

I believe this guy has run into the same issue: https://stackoverflow.com/questions/53429474/missing-assembly-binding-redirect-from-stackexchange-redis-2-0-513-package

jonorogers commented 5 years ago

After leaving the above comment I created a new Azure Worker Role project & Service (.net 4.7.2), added System.Buffers as a reference and ran GC.KeepAlive(typeof(System.Buffers.ArrayPool<byte>)); on start with no problems. I then pulled in the Pipelines.Sockets.Unofficial nuget package, created a rudimentary server and verified everything was working while debugging through the emulator.

No idea what was going wrong with my previous project structure - but I think you can consider this closed for now. Only differences are that the new project isn't using Package Reference style, it doesn't have a whole heap of legacy shit glued to it, and that I realised I was being stupid and inspecting DLL's / deleting bin/obj folders from the class library bin folder, not the Azure Cloud Service folder..

Quppa commented 4 years ago

We experienced the same problem with the combination of an Azure Cloud Services Worker Role project + StackExchange.Redis + SDK-style CSPROJ/PackageReference. Ultimately we got it working using Eric StJohn's script. Still not quite sure why it was copying the wrong DLL versions without it.