Successfully reported this slideshow.
Your SlideShare is downloading. ×

20170527 inside .NET Core on Linux

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 40 Ad

More Related Content

Slideshows for you (20)

Similar to 20170527 inside .NET Core on Linux (20)

Advertisement

More from Takayoshi Tanaka (20)

Recently uploaded (20)

Advertisement

20170527 inside .NET Core on Linux

  1. 1. .NET Core がLinuxで どのように動いているか、 またわれわれは どのようにデバッグするのか たなか (@TANAKA_733) Y8 2017 SPRING IN SHIBUYA 1
  2. 2. @tanaka_733 Red Hat K. K. ◦ .NET Core on RHEL, Red Hat on Azure, OpenShift ◦ SQL Server on RHEL も調べたり Microsoft MVP for VSDT* ◦ .NET, C#, Azure系の勉強会によく出現します ◦ Build Insider でよく執筆しています (C# 文法, C# 7.0 や .NET Core) ◦ (需要があれば) ほかの勉強会にもお邪魔したいです Contact ◦ contact@tanaka733.net or twitterで 2 * VSDT: Visual Studio and Development Technologies
  3. 3. AGENDA .NET Core とは ◦ (この後出てくる) coreclr とか corefxが何かを知ってもらう CoreFX on Linux ◦ ネットワーク通信とかファイルIOとかどう実装してるのか Debugging .NET Core on Linux ◦ Visual Studioが使えないLinux上でどうやってデバッグするのか 3
  4. 4. …は話しません Getting Started with .NET Core ◦ .NET Coreでのアプリ開発について ◦ 近々Build Insiderで連載が始まるので読んでね! ダイレクトマーケティング Xamarin ◦ Xamarinの出自のmonoは関連が深いけれど、.NET Coreではないです .NET Core 2.0/.NET Standard 2.0 ◦ 2.0はpreview、現在の正式最新版が1.x ◦ 今日の話は.NET Core 1.xベース ◦ 概念としては2.0でも変わらない(予定) ◦ 利用可能なツールのバージョンとかオプションとかは変わるかも 4
  5. 5. .NET Core とは? .NET Frameworkとの違いや、 coreFX, coreCLRの意味するもの 5
  6. 6. .NET Application Model 6
  7. 7. .NET Core Inside 7 .NET Core App (C#/VB) IL Assembly (exe, dll) Roslyn CoreFX (.NET Core Class Library) ManagedUnmanaged OS Native ABI etc (F#) compiler CoreCLR (.NET Core Runtime) .NET Core SDK Tools
  8. 8. coreFXに見る OS固有処理の実装 8
  9. 9. coreFX とは .NET Core の基本クラスライブラリ群 ◦コレクションとかIOとか 開発時、実行時ともライブラリとしてロードされる ◦開発時と実行時では参照するものが異なる 後で NuGetとよばれるパッケージマネージャを通して提供 9
  10. 10. NuGet nodejsのnpm、Javaのmaven的なパッケージ管理エコシステム ◦ mavenとは違ってビルドシステムは別(MSBuild) デフォルトでnuget.orgでホストされるパッケージを参照する ◦ 公式ライブラリも正式版はここから提供される ◦ アカウントを作成すればだれでもここにホストできる ◦ 専用ホスティングを立てることもできる(社内限定など) NuGetパッケージの.nupkgは単なるzip圧縮 ◦ フォルダ階層やフォルダ名に意味がある ◦ 中身はWindowsでおなじみのdllとか ◦ LinuxやmacOSでもクラスライブラリの拡張子はdll 10
  11. 11. NuGetにおける複数環境への対応 .NET Core以前にも、異なる環境ごとに実装を入れ替えたい要望があった ◦ SilverlightとかWindows Phoneとかありましたしね… (遠い目 ◦ .NET Frameworkのバージョンごとにわけたというのもある (歴史的な経緯で)名称は複雑だが、 環境ごとにフォルダを分けて同梱できる ◦ Portable Class Library (PCL)とかその辺 NuGetクライアントがいい感じに対応するバイナリを拾ってくれる 11
  12. 12. OS固有の処理をいかに記述するか NetworkやFile IOといった処理 プログラミング的なアプローチとしては… ◦ 通常のif文 ◦ コンパイラスイッチ ◦ プラットフォームごとにコンパイラにスイッチを渡して コンパイル対象のコードを切り替えることができる パフォーマンス上の問題になったり、 コードの見通しが悪くなったり… 13
  13. 13. OSごとに参照するdllを差し替える 14 System.Net.Http/4.1.0 ┗ref ┗ netstandard1.3 ┗System.Net.Http.dll ┗lib ┗ win/lib/ netstandard1.3 ┗System.Net.Http.dll ┗ unix/lib/ netstandard1.6 ┗System.Net.Http.dll 開発時に参照するライブラリ Windows上で実行するときに参照 Unix (Linux+Mac)上で実行するときに参照 対応している.NETの環境を示す
  14. 14. 15 せっかくHttp通信ライブラリを例に出したので Unix(Linux+Mac)でHttp通信がどのように実装されているか見てみよう
  15. 15. HttpClient.XXX.cs 16 https://github.com/dotnet/corefx/blob/release/1.1.0/src/Syste m.Net.Http/src/System/Net/Http/HttpClient.cs
  16. 16. 17
  17. 17. HttpClientの実装はcurlだった…? .NET Frameworkにはネイティブライブラリを実行する P/Invokeという技術がありました ◦ COM だったり ◦ C styleの関数だったり .NET Coreの世界に来てもP/Invokeは健在です ◦ P/Invoke on Linuxはmonoで実現できていたことです ◦ 機能追加に関してもmonoの機能が提案されています 18
  18. 18. P/Invokeのしていること 関数を格納している共有ライブラリを検索 そのライブラリをメモリに読み込み 関数のアドレスを指定+引数をスタックにプッシュ • .NET とC++のデータ型が一致しないのでマーシャリングも 19
  19. 19. P/Invokeを使えばLinuxでもGUIが!? .NET CoreはGUIはサポートしていない (monoはサポートしている) が、ネイティブのGUIライブラリをP/Invoke経由で実行することは可能 20 public static void Main(string[] args) { var argc = 0; var argv = IntPtr.Zero; gtk_init(ref argc, ref argv); var diag = gtk_message_dialog_new(IntPtr.Zero, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, “Hello from .NET Core on Red Hat!”, IntPtr.Zero); var res = gtk_dialog_run(diag); gtk_widget_destroy(diag); Console.WriteLine(res); }
  20. 20. P/Invokeが故におきる事案 https://github.com/dotnet/coreclr/issues/5612 ロケールがen-usでない環境だと、次のシンプルなコードが、 LinuxだとWindowsの10倍以上遅くなる問題  libicu のロード時間の問題 (未解決) 21 "abcfeg".EndsWith("123");
  21. 21. async on Linux C# (5.0以降)では非同期処理の記述にasync/await構文が使えます .NET ではasync/await構文の実装は単純なスレッドプールではないです WindowsではIO完了ポートが使われています。では、Linuxは? 24 public async Task<string> GetExample() { var client = new HttpClient(); var res = await client.GetAsync("http://example.com"); return await res.Content.ReadAsStringAsync(); }
  22. 22. epoll for async in Linux 25 https://github.com/dotnet/corefx/blob/release/1.1.0/src/Nativ e/Unix/System.Native/pal_networking.cpp Linux では epoll が、 macOSではkqueueが使われています
  23. 23. Debugging .NET Core on Linux Linuxの上でも.NET Coreをデバッグしたい 26
  24. 24. WindowsとLinuxでの違い 27 windbg sos procmon perfview LLDB/GDB libsosplugin.so strace perfcollect
  25. 25. LLDBを使ったデバッグ 起動中のプロセスにアタッチする場合 1. sosplugin のパスを探しておく 例: /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/libsosplugin.so 2. アタッチ対象のPIDを取得 3. lldb起動 4. lldbコンソールでアタッチ (lldb) process attach -p <PID> 5. プラグインロード (lldb) plugin load/opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/libsosplugin.so (lldb) setclrpath /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1 (lldb) clrstack
  26. 26. LLDBを使ったデバッグ 出力されたcoreファイルにattachする場合 1. sosplugin のパスを探しておく 例: /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/libsosplugin.so 2. gcore <PID> でcoreをはかせる 3. lldb起動 $ sudo lldb /opt/dotnet/dotnet --core <corefile> 4. プラグインロード (lldb) plugin load/opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/libsosplugin.so (lldb) setclrpath /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1 (lldb) clrstack
  27. 27. 30
  28. 28. 31
  29. 29. perf ツール 1. 対象のPIDを取得 2. PERFを出力して表示する $ sudo perf record -F 99 -p <PID> -a -g -- sleep 10 $ sudo perf report --stdio 32
  30. 30. 33
  31. 31. Tracing Runtime Event インストール https://lttng.org/docs/v2.8/#doc-fedora CentOS向け http://frederic-wou.net/lttng/ https://raw.githubusercontent.com/dotnet/corefx- tools/master/src/performance/perfcollect/perfcollect $ wget https://raw.githubusercontent.com/dotnet/corefx- tools/master/src/performance/perfcollect/perfcollect $ sudo ./perfcollect collect samplePerfTrace $ sudo ./perfcollect view samplePerfTrace.trace.zip 34
  32. 32. 35
  33. 33. High Level Debugging .NET Core 36 GDB/LLDB MICore MIDE/Engine.Impl MIDE(*)/AD7.Impl VSCode Debugger AD7 Interface *MIDE: MIDebugEngine *vsdbgはVS製品以外での利用禁止かつ再頒布禁止なライセンス MIText VS Debugger VS Debugger Engine vsdbg (クローズド ライセンス*) windbg 統合可能
  34. 34. リモートデバッキング リモートデバッキングはデバッガーのクライアントと対象のプロセス間で 信頼できる通信ができさえすればよい ◦ 多くの場合SSHを利用 ◦ Windows同士だったら、昔から対象のマシンにデバッガーツールを入れて通信できていた ◦ クライアントはデバッガーのライセンス上、Visual Studio Family限定になるのが現状 ◦ 技術的にはクライアントも任意。ライセンス的にはソースからビルドすればよさそう? 37
  35. 35. Visual Studio Codeからの リモートデバッグ接続 .vscode/launch.json を編集する ◦ 通信コマンドを記述するので、sshコマンドのほかにdocker rshなども指定可能 38 { "name": ".NET Core Docker Remote Attach", "type": "coreclr", "request": "attach", “processId”: “86”, //アタッチするPIDを指定 "pipeTransport": { "pipeProgram": “ssh", “pipeArgs”: [ “-T”, “tanaka733@centos.example.com”], //接続先の指定 “quoteArgs”:false, //接続プログラムによりfalseがいいときとtrueがいいときがある “debuggerPath”: “/opt/app-root/src/vsdbg/vsdbg”, //接続先のvsdbgパス "pipeCwd": "${workspaceRoot}" }, "sourceFileMap": { "/opt/app-root/src": "${workspaceRoot}“ } }
  36. 36. Visual Studio on Windowsからの リモートデバッグ接続 リモート接続画面でSSHを選択する ◦ 設定が隠れているので、docker rshなどは現状指定できない ◦ docker for WindowsやAzure上のdockerコンテナへはVSの機能により接続可能 ◦ つまり、Visual Studio拡張とかを書けば技術的にはいけるはず  調査中です… あと今日見たら、プロトコルにWebSocketが追加されてたので夢は広がる? 39
  37. 37. まとめ .NET CoreのクラスライブラリでOS固有の処理ではP/Invokeが大活躍 ◦ P/Invokeを利用するが故の問題も起きている Linux上の.NET Coreプロセスは通常のプロセス ◦ lldbやperfといったデバッグ・プロファイルコマンドが利用可能 GUIからのデバッグにはVisual Studio Codeが便利 ◦ 原理的には別のエディタでもできるが、ライセンス的にVS Familyのみ デバッグインターフェースに互換性があるので、 WindowsとLinux間で相互にリモートデバッグできる ◦ 明示的に記述がないけど、VS on WindowsからLinuxへ、VS Code on LinuxからWindowsへ 40
  38. 38. 参考資料 GitHub repo 「NuGetでプラットフォーム毎にアセンブリを展開する方法」と「良い感じにコードを共有してプラット フォーム別のアセンブリを作る方法」 P/Invokeを使って.NET Core on LinuxでGUIを作る記事 (英語) ◦ https://developers.redhat.com/blog/2016/09/14/pinvoke-in-net-core-rhel/ HttpClient ◦ https://github.com/dotnet/corefx/blob/release/1.1.0/src/System.Net.Http/src/System/Net/Http/HttpClient.cs Staring.StartsWith の呼び出し階層 (StringクラスなどRuntime側でも必要なクラスはcorefxではなくcoreclrで定義 されている) ◦ https://github.com/dotnet/coreclr/issues/5612 (Issue本体) ◦ https://github.com/dotnet/coreclr/blob/release/1.1.0/src/mscorlib/src/System/String.Comparison.cs#L1104-L1114 ◦ https://github.com/dotnet/coreclr/blob/release/1.1.0/src/mscorlib/src/System/Globalization/CompareInfo.cs#L582-L591 ◦ https://github.com/dotnet/coreclr/blob/release/1.1.0/src/mscorlib/src/System/Globalization/CompareInfo.cs#L1346-L1351 ◦ ※.NET Core 2.0で割と大掛かりに内部実装変わってます 41
  39. 39. 参考資料(2) Async/Await ◦ http://forums.dotnetfoundation.org/t/socket-async-on-linux-vs-windows/2498 ◦ https://github.com/dotnet/corefx/blob/release/1.1.0/src/Native/Unix/System.Native/pal_networking.c pp#L2501 ◦ https://news.ycombinator.com/item?id=12341909 ◦ Async訪ねて3000里 (6) : I/O完了ポートによるワーカースレッドの運用 ◦ .NET Frameworkでの話。ぜひ(1)から… ◦ https://msdn.microsoft.com/ja-jp/library/cc429203.aspx ◦ http://southworks.com/blog/2013/10/29/asynchronous-io-in-c-io-completion-ports/ Performance Tracing ◦ https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/linux-performance- tracing.md 42
  40. 40. 参考資料(3) LLDB ◦ http://blogs.microsoft.co.il/sasha/2017/02/26/analyzing-a-net-core-core-dump-on-linux/ Tracing Runtime Event ◦ https://lttng.org/docs/v2.8/#doc-fedora ◦ CentOS向け ◦ http://frederic-wou.net/lttng/ ◦ スクリプト ◦ https://raw.githubusercontent.com/dotnet/corefx-tools/master/src/performance/perfcollect/perfcollect vsdbg ◦ https://github.com/OmniSharp/omnisharp-vscode/wiki/Attaching-to-remote-processes ◦ clrdbg は vsdbg にリプレースされました ◦ OpenShift上のプロセスで説明していますが、docker rshでも同様に実行可能 ◦ Remote Debugging s2i dotnetcore from Visual Studio Code 43

×