CoreCLRで遭遇する楽しいエラーというか滅ぼされたものとかと戦う


概要

思ったよりエラーが秩序立って出るのでコレクションしてみた。


使ってる基本ライブラリはこれ。

https://dotnet.github.io



対して、実装している対象はこれ。

Disquuun

https://github.com/sassembla/Disquuun



環境

MacとかUbuntu14とかがメイン。だって確認が簡単なんだもん。

サーバで動く.Net Coreは良いぞ。



遭遇したエラーとかを列挙していく。



いまのところ一番凶悪なエラー Could not load file or assembly 'System.Diagnostics.StackTrace

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.StackTrace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. A device attached to the system is not functioning.

 (Exception from HRESULT: 0x8007001F)

   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)

   at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)

   at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)

   at System.Type.GetType(String typeName, Boolean throwOnError)

   at System.Diagnostics.StackFrameHelper.InitializeSourceInfo(Int32 iSkip, Boolean fNeedFileInfo, Exception exception)

   at System.Diagnostics.StackTrace.CaptureStackTrace(Int32 iSkip, Boolean fNeedFileInfo, Thread targetThread, Exception e)

   at System.Exception.get_Source()

   at System.Exception.InternalPreserveStackTrace()

   at ServerInitializer.Init()

   at ConsoleApplication.Program.Main(String[] args)


わけがわからないときにでる。内容は、StackTraceの入ってるassemblyが読めない、っていうことを言われて、は?ってなるっていう。

端的に言うとこれをひいた。

Exception stack is bogus when ulimit is hit. #5782

https://github.com/dotnet/coreclr/issues/5782

場所がさっぱりわからないことになる。

あっちなみにこのエラーが出ると、プロセスが落ちる。



StackTraceよもやま話

stacktraceに関しての話はこのへんもあっておもしろい。っていうかStackTraceないんで、自分で実行した関数の名前を把握できない。うおお、、、

https://github.com/dotnet/corefx/issues/1420



System.IO.IOException: Too many open files

地味にすごく困るエラーがこれ。

や、Disqueのクライアントごときがこんなエラーだしてちゃいけないんだけどさ、

OSで指定してあるFileDescriptorの数を超えてTCPとかのコネクションを貼ろう、ってした場合に上記エラーが出る。

このパラメータをコード上からいじる、っていう文法がCoreCLR上にまだないんで、困っている。


例えばPythonとかだったら、

import resource


resource.setrlimit(

    resource.RLIMIT_CORE,

    (resource.RLIM_INFINITY, resource.RLIM_INFINITY))

みたいな書き方でOSに対してこのプロセスはどんだけのulimitを使うんだよって指定できるんだけど、この辺はCoreCLRだと

https://github.com/dotnet/coreclr/search?utf8=✓&q=ulimit

shellでセットしたりしてる以外は、、コードに特になってないような、、?

このへんはまあ困っていますね。はい。



Delegate.BeginInvoke/EndInvoke is DEAD

BeginInvokeとかEndInvokeは死にました。やったね?


Unsupportedエラー出そうぜ、っていう話が上がって、叶ってるっぽいんだけどちゃんと出ないことがある。再現したいな~~。

https://github.com/dotnet/coreclr/issues/3811


Socketの接続周りがドラマチックになった

Mac上とかでテストしたいな~みたいな時、IPEndPoint を使ってアドレスとかポートを指定しないとSocketをnewするのに失敗する。

どっかCoreCLRのリポジトリ上にもIssueがあった気がする。



Socketの切断周りがドラマチックになった

socket.CloseとかCloseAsyncとかが全部滅びた。

Dispose()使おうな。という感じで、これもどこかにIssueが上がってて全容が書いてあった気がする。

見つけたら書き足す。


実際にDisposeで書き直したところ、処理が軽量なのか問題は出なかった。なんか見逃してる気がしないでもない。



Reflectionにいろいろ足りない

いろいろやってる最中っぽい。

https://github.com/dotnet/corefx/issues/5381



あのメソッドは今

互換に関する情報は、下記が一番参考になる。公式の移植に関する互換性資料。

http://dotnet.github.io/port-to-core/Moq4_ApiPortabilityAnalysis.htm