Y8 2017 Spring という技術系ノンジャンル(と私は理解している)イベントがあったので登壇してきました。CFPにリアクションして頂いたみなさまありがとうございました。こちらが資料です(更新するかもしれないです)。
イベントサイトはこちら。
.NET Core がLinux(やmacOS)で動くようにどうやって実装しているかとか、デバッグの仕方とか、OS固有の部分をどうやってLinuxの世界に持ち込んでいるのか、というテーマはずっと話したくて機会を伺っていたのですがようやく世に出すことができました。
もし次があれば、デバッグまわりの部分はもう少し実践的な内容にしたいなあと思います。また、Linuxユーザー向けにはVisual Studio側の機能紹介もしたいですね。今回デモしたように、.NET CoreをLinuxにデプロイする場合でも、Windowsで開発することができ、リモートデバッグすることができます。また、リモートデバッグについてはいつの間にかやたらリモートデバッグの接続の種類が増えているので、改めて調査します。
dllに含まれるシグニチャを見るには?
質問されて答えが出せなかったので、いったん調べた内容をこちらに。dllの中で定義されているクラスとかメソッド一覧を取得したいという質問だったのですが、dllの中に定義されているのはIL(中間言語)なのでnmコマンドなどでは見れないはずです。あくまで.NET CoreのILを解釈する必要があります。Windows上の.NET FrameworkならILSpyなどのフリーのツールで逆コンパイルすることもできるのですが、Linux上で動作する.NET Core向けの逆コンパイルツールは見つけられませんでした。
とりあえずできそうな方法はLLDBでlibsospluginをsosコマンドからたどって行く方法です。.NET Coreのlibsospluginの使い方の詳細はこちらにあります。
定義されているsosコマンドは.NET Frameworkのものと対応しており、その詳細はこちらに書いてあります。
ではこれを使って、stringクラスのメソッド一覧を出してみましょう。ちなみにsosコマンドあまり詳しくないので、よりよい方法があればコメントなどをもらえるとうれしいです。
DumpHeapでstring
を指定します。
(lldb) sos DumpHeap string Address MT Size 00007f6b1aed5000 00000000010717b0 24 Free 00007f6b1aed5018 00000000010717b0 24 Free 00007f6b1aed5030 00007f6d3b77db68 72 (以下略)
どれか1つのアドレスを指定してDumpObj
します。
(lldb) sos DumpObj 00007f6b1aed50b8 Name: System.String MethodTable: 00007f6d3b77db68 EEClass: 00007f6d3b0916d0 Size: 60(0x3c) bytes File: /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/System.Private.CoreLib.ni.dll String: Format_GuidDashes Fields: MT Field Offset Type VT Attr Value Name 00007f6d3b797948 4001aa6 8 System.Int32 1 instance 17 m_stringLength 00007f6d3b7827c0 4001aa7 c System.Char 1 instance 46 m_firstChar 00007f6d3b77db68 4001aa8 1258 System.String 0 shared static Empty >> Domain:Value 00000000010e3fb0:NotInit <<
メソッド一覧はMethodTableで取得できます。詳細を出すために--md
を指定します。
(lldb) sos DumpMT -md 00007f6d3b77db68 EEClass: 00007F6D3B0916D0 Module: 00007F6D3B00B000 Name: System.String mdToken: 00000000020005AD File: /opt/dotnet/shared/Microsoft.NETCore.App/1.1.1/System.Private.CoreLib.ni.dll BaseSize: 0x18 ComponentSize: 0x2 Slots in VTable: 196 Number of IFaces in IFaceMap: 7 -------------------------------------- MethodDesc Table Entry MethodDesc JIT Name 00007F6D3B42CE10 00007F6D3B0E1508 PreJIT System.String.ToString() 00007F6D3B42E3F0 00007F6D3B0E17A8 PreJIT System.String.Equals(System.Object) 00007F6D3B42EA60 00007F6D3B0E1878 PreJIT System.String.GetHashCode() 00007F6D3B41EE10 00007F6D3B0DF0B0 PreJIT System.Object.Finalize() 00007F6D3B42CE20 00007F6D3B0E1510 PreJIT System.String.ToString(System.IFormatProvider) 00007F6D3B42CE30 00007F6D3B0E1518 PreJIT System.String.Clone() 00007F6D3B42CF40 00007F6D3B0E1550 PreJIT System.String.GetTypeCode() 00007F6D3B42CF50 00007F6D3B0E1558 PreJIT System.String.System.IConvertible.ToBoolean(System.IFormatProvider) (以下略)
まあ、めんどくさいですね… これはもう少し調べてみることにします。