troushoo

Linux で動く PowerShell を LLDB とそのエクステンション libsosplugin.so を用いてデバッグ

概要

Linux で動く PowerShell を LLDB 並びに、そのエクステンション libsosplugin.so を用いてデバッグする方法を紹介します。
Ubuntu 16.04 を用いて試しています。

内容

PowerShell のインストール
1. PowerShell のダウンロードサイトより deb ファイルをダウンロードします。

wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/powershell_6.0.0-alpha.14-1ubuntu1.16.04.1_amd64.deb

2. PowerShell のインストールに必要な libunwind8 と libcurl3 をインストールします。
apt-get install -y libunwind8 libcurl3

3. PowerShell をインストールします。
sudo dpkg -i powershell_6.0.0-alpha.14-1ubuntu1.16.04.1_amd64.deb

PowerShell のビルド
PowerShell のデバッグに利用する LLDB のエクステンション libsosplugin.so を作成するため、PowerShell をビルドします。
1. PowerShell のソースコードをクローンします。
git clone --recursive https://github.com/PowerShell/PowerShell.git

2. PowerShell を起動し、クローンしたフォルダーの PowerShell フォルダー移動しておきます。
powershell


3. PowerShell のビルドに必要な build.psm1 をインポートします。
Import-Module ./build.psm1

4. PowerShell のビルドに必要なモジュールをインストールします。
Start-PSBootstrap

5. PowerShell をビルドします。
Start-PSBuild -Publish -Output /source/PowerShell/debug

lldb を用いた PowerShell のデバッグ
1. 別ターミナルを起動し、LLDB を起動します。
lldb-3.6


2. powershell にアタッチします。
process attach --name powershell


3. PowerShell を実行させます。
c


4. PowerShell で Get-Command を実行し、Get-Command が実装されているタイプを確認します。
Get-Command Get-Command | fl ImplementingType  

実行結果より、ImplementingType は、Microsoft.PowerShell.Commands.GetCommandCommand とわかりました。


5. LLDB に戻り、Ctrl + C でデバッガーにブレイクさせます。


6. LLDB の .NET 用のエクステンション libsosplugin.so を読み込みます。
plugin load /root/powershell/PowerShell/debug/libsosplugin.so


7. Get-Command にブレークポイントを設定してみます。
まず、Method Table を見つけるために、Name2EE を利用します。
sos Name2EE *!Microsoft.PowerShell.Commands.GetCommandCommand

出力結果は以下のようになります。黄色の部分が、必要な情報です。

(lldb) sos Name2EE *!Microsoft.PowerShell.Commands.GetCommandCommand
Module:      00007f3930adf000
Assembly:    System.Private.CoreLib.ni.dll
--------------------------------------
Module:      00007f39309d1cb0
Assembly:    powershell.dll
--------------------------------------
Module:      00007f39309d26f8
Assembly:    System.Runtime.dll
--------------------------------------
Module:      00007f39309d3160
Assembly:    mscorlib.dll
--------------------------------------
Module:      00007f39309d3b68
Assembly:    System.Reflection.dll
--------------------------------------
Module:      00007f39309d45d8
Assembly:    System.Runtime.Extensions.dll
--------------------------------------
Module:      00007f39309d5590
Assembly:    Microsoft.PowerShell.CoreCLR.AssemblyLoadContext.dll
--------------------------------------
Module:      00007f39309d6dc0
Assembly:    System.Runtime.Loader.dll
--------------------------------------
Module:      00007f39309d7b40
Assembly:    System.Collections.Concurrent.dll
--------------------------------------
Module:      00007f3931548350
Assembly:    System.Threading.dll
--------------------------------------
Module:      00007f3931548e98
Assembly:    System.Collections.dll
--------------------------------------
Module:      00007f393154a170
Assembly:    System.IO.FileSystem.dll
--------------------------------------
Module:      00007f393154b5d8
Assembly:    System.IO.FileSystem.Primitives.dll
--------------------------------------
Module:      00007f393154daa8
Assembly:    System.Runtime.InteropServices.dll
--------------------------------------
Module:      00007f39315520b0
Assembly:    Microsoft.PowerShell.ConsoleHost.dll
--------------------------------------
Module:      00007f39315537b0
Assembly:    System.Reflection.TypeExtensions.dll
--------------------------------------
Module:      00007f39315545f8
Assembly:    Microsoft.Win32.Primitives.dll
--------------------------------------
Module:      00007f39315550f8
Assembly:    System.Management.Automation.dll
Token:       00000000020000DF
MethodTable: 00007f39352d5000
EEClass:     00007f39352b0458
Name:        Microsoft.PowerShell.Commands.GetCommandCommand
--------------------------------------
Module:      00007f393507a5f8
Assembly:    System.Threading.Tasks.dll
--------------------------------------
Module:      00007f393507c6b8
Assembly:    System.Globalization.dll
--------------------------------------
Module:      00007f393507ea48
Assembly:    System.Dynamic.Runtime.dll
--------------------------------------
Module:      00007f3935080480
Assembly:    System.Resources.ResourceManager.dll
--------------------------------------
Module:      00007f3935081c00
Assembly:    System.Linq.Expressions.dll
--------------------------------------
Module:      00007f3935086530
Assembly:    System.Runtime.Serialization.Primitives.dll
--------------------------------------
Module:      00007f3935088a70
Assembly:    System.Text.Encoding.dll
--------------------------------------
Module:      00007f393508a268
Assembly:    System.Runtime.InteropServices.RuntimeInformation.dll
--------------------------------------
Module:      00007f39350b5a28
Assembly:    System.Collections.NonGeneric.dll
--------------------------------------
Module:      00007f39350b89f8
Assembly:    System.Security.Cryptography.X509Certificates.dll
--------------------------------------
Module:      00007f39350b9dc0
Assembly:    System.Security.Cryptography.Encoding.dll
--------------------------------------
Module:      00007f39350e00d8
Assembly:    System.Net.Primitives.dll
--------------------------------------
Module:      00007f39350e2d60
Assembly:    Microsoft.Management.Infrastructure.dll
--------------------------------------
Module:      00007f39350e56d8
Assembly:    System.Text.RegularExpressions.dll
--------------------------------------
Module:      00007f39350e7cd8
Assembly:    System.Private.Uri.dll
--------------------------------------
Module:      00007f39350ea868
Assembly:    System.Xml.XmlDocument.dll
--------------------------------------
Module:      00007f393510c9b0
Assembly:    System.Xml.ReaderWriter.dll
--------------------------------------
Module:      00007f393510ebe0
Assembly:    System.Diagnostics.FileVersionInfo.dll
--------------------------------------
Module:      00007f393510fc00
Assembly:    System.Security.SecureString.dll
--------------------------------------
Module:      00007f3935110bc0
Assembly:    System.Runtime.Numerics.dll
--------------------------------------
Module:      00007f3935113350
Assembly:    System.IO.dll
--------------------------------------
Module:      00007f3935114958
Assembly:    System.Security.AccessControl.dll
--------------------------------------
Module:      00007f3935115920
Assembly:    System.Reflection.Metadata.dll
--------------------------------------
Module:      00007f3935117a18
Assembly:    System.Net.NetworkInformation.dll
--------------------------------------
Module:      00007f39351734a8
Assembly:    System.Collections.Immutable.dll
--------------------------------------
Module:      00007f393517ae40
Assembly:    System.Runtime.Handles.dll
--------------------------------------
Module:      00007f39351b6e00
Assembly:    System.IO.MemoryMappedFiles.dll
--------------------------------------
Module:      00007f39351b8400
Assembly:    System.IO.UnmanagedMemoryStream.dll
--------------------------------------
Module:      00007f39351b9668
Assembly:    System.Reflection.Extensions.dll
--------------------------------------
Module:      00007f39351e0a08
Assembly:    System.Reflection.Emit.ILGeneration.dll
--------------------------------------
Module:      00007f39351e9840
Assembly:    System.Reflection.Primitives.dll
--------------------------------------
Module:      00007f39351eb348
Assembly:    System.Reflection.Emit.Lightweight.dll
--------------------------------------
Module:      00007f393523d1c0
Assembly:    System.Text.Encoding.Extensions.dll
--------------------------------------
Module:      00007f3935242dc8
Assembly:   
--------------------------------------
Module:      00007f3935246180
Assembly:    System.Linq.dll
--------------------------------------
Module:      00007f39352702d8
Assembly:    System.ObjectModel.dll
--------------------------------------
Module:      00007f39352a76f8
Assembly:    System.Collections.Specialized.dll
--------------------------------------
Module:      00007f39352ed260
Assembly:    System.Threading.Thread.dll
--------------------------------------
Module:      00007f39352ee478
Assembly:    System.Console.dll
--------------------------------------
Module:      00007f39352f9490
Assembly:    Microsoft.Win32.Registry.dll
--------------------------------------
Module:      00007f39353531c8
Assembly:    System.Data.Common.dll
--------------------------------------
Module:      00007f3935356cb8
Assembly:    System.Diagnostics.Tracing.dll
--------------------------------------
Module:      00007f3935398a20
Assembly:    System.Diagnostics.Debug.dll
--------------------------------------
Module:      00007f39353c9c90
Assembly:    Newtonsoft.Json.dll
--------------------------------------
Module:      00007f39353f1738
Assembly:    Microsoft.PowerShell.Security.dll
--------------------------------------
Module:      00007f39353f2568
Assembly:    System.Threading.Tasks.Parallel.dll
--------------------------------------
Module:      00007f39354533a8
Assembly:    System.Security.Principal.dll
--------------------------------------
Module:      00007f393546ccc8
Assembly:    System.IO.FileSystem.DriveInfo.dll
--------------------------------------
Module:      00007f39354f3458
Assembly:    System.ComponentModel.TypeConverter.dll
--------------------------------------
Module:      00007f3935510020
Assembly:    System.IO.FileSystem.AccessControl.dll
--------------------------------------
Module:      00007f3935510dc0
Assembly:    System.Security.Principal.Windows.dll
--------------------------------------
Module:      00007f3935511bf8
Assembly:    Microsoft.Win32.Registry.AccessControl.dll
--------------------------------------
Module:      00007f3935536300
Assembly:    System.Diagnostics.Process.dll
--------------------------------------
Module:      00007f393560a768
Assembly:    Microsoft.PowerShell.PSReadLine.dll
--------------------------------------
Module:      00007f3935887f88
Assembly:    Microsoft.CSharp.dll
--------------------------------------
Module:      00007f3935929240
Assembly:    System.Reflection.Emit.dll
--------------------------------------
Module:      00007f393598a1d8
Assembly:    Microsoft.PowerShell.Commands.Utility.dll
--------------------------------------
Module:      00007f3935cc3490
Assembly:    System.Diagnostics.TraceSource.dll
--------------------------------------
Module:      00007f3935cee6d8
Assembly:    System.Security.Cryptography.Primitives.dll
--------------------------------------
Module:      00007f3935cf1468
Assembly:    System.Threading.AccessControl.dll
--------------------------------------
Module:      00007f3935eaf300
Assembly:    Microsoft.PowerShell.Commands.Management.dll
--------------------------------------
Module:      00007f3935eb43d0
Assembly:    System.ServiceProcess.ServiceController.dll


8. 見つかった Method Table から、DumpMT を使ってメソッドのアドレスを探します。
sos DumpMT -MD 00007f39352d5000

出力結果は以下のようになります。黄色の部分が必要な情報です。

(lldb) sos DumpMT -MD 00007f39352d5000
EEClass:         00007F39352B0458
Module:          00007F39315550F8
Name:            Microsoft.PowerShell.Commands.GetCommandCommand
mdToken:         00000000020000DF
File:            /opt/microsoft/powershell/6.0.0-alpha.14/System.Management.Automation.dll
BaseSize:        0x110
ComponentSize:   0x0
Slots in VTable: 59
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
           Entry       MethodDesc    JIT Name
00007F3930EF3D90 00007F3930BB3688 PreJIT System.Object.ToString()
00007F3930EF3DB0 00007F3930BB3690 PreJIT System.Object.Equals(System.Object)
00007F3930EF3E00 00007F3930BB36B8 PreJIT System.Object.GetHashCode()
00007F3930EF3E10 00007F3930BB36D8 PreJIT System.Object.Finalize()
00007F3933DAF8A0 00007F39352CD760 PreJIT System.Management.Automation.Cmdlet.DoBeginProcessing()
00007F3933DAFAC0 00007F39352CD768 PreJIT System.Management.Automation.Cmdlet.DoProcessRecord()
00007F3933DAFAF0 00007F39352CD770 PreJIT System.Management.Automation.Cmdlet.DoEndProcessing()
00007F39352252E8 00007F39352CD778   NONE System.Management.Automation.Cmdlet.DoStopProcessing()
00007F39352252F8 00007F39352CD788   NONE System.Management.Automation.Cmdlet.GetResourceString(System.String, System.String)
00007F3933BE0E00 00007F39352D4E88 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.BeginProcessing()
00007F3933BE0F30 00007F39352D4E90 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.ProcessRecord()
00007F3933BE1120 00007F39352D4E98 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.EndProcessing()
00007F39352253E8 00007F39352CD958   NONE System.Management.Automation.Cmdlet.StopProcessing()
00007F3933BE61A0 00007F39352D4FB0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand..ctor()
00007F3933BE0320 00007F39352D4CC8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_Name()
00007F3933BE0350 00007F39352D4CD8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.set_Name(System.String[])
00007F3933BE0440 00007F39352D4CE8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_Verb()
00007F3935226D20 00007F39352D4CF8   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_Verb(System.String[])
00007F3933BE04F0 00007F39352D4D08 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_Noun()
00007F3935226D30 00007F39352D4D18   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_Noun(System.String[])
00007F3933BE05B0 00007F39352D4D28 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_Module()
00007F3935226D40 00007F39352D4D38   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_Module(System.String[])
00007F3935226D48 00007F39352D4D48   NONE Microsoft.PowerShell.Commands.GetCommandCommand.get_FullyQualifiedModule()
00007F3935226D50 00007F39352D4D58   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_FullyQualifiedModule(Microsoft.PowerShell.Commands.ModuleSpecification[])
00007F3933BE0720 00007F39352D4D68 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_CommandType()
00007F3935226D60 00007F39352D4D78   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_CommandType(System.Management.Automation.CommandTypes)
00007F3933BE0790 00007F39352D4D88 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_TotalCount()
00007F3935226D70 00007F39352D4D98   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_TotalCount(Int32)
00007F3933BE07E0 00007F39352D4DA8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_Syntax()
00007F3935226D80 00007F39352D4DB8   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_Syntax(System.Management.Automation.SwitchParameter)
00007F3933BE0870 00007F39352D4DC8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_ShowCommandInfo()
00007F3935226D90 00007F39352D4DD8   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_ShowCommandInfo(System.Management.Automation.SwitchParameter)
00007F3933BE08C0 00007F39352D4DE8 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_ArgumentList()
00007F3935226DA0 00007F39352D4DF8   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_ArgumentList(System.Object[])
00007F3933BE0910 00007F39352D4E08 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_All()
00007F3933BE0950 00007F39352D4E18 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.set_All(System.Management.Automation.SwitchParameter)
00007F3933BE09A0 00007F39352D4E28 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_ListImported()
00007F3935226DC0 00007F39352D4E38   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_ListImported(System.Management.Automation.SwitchParameter)
00007F3933BE0A30 00007F39352D4E48 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_ParameterName()
00007F3935226DD0 00007F39352D4E58   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_ParameterName(System.String[])
00007F3933BE0B40 00007F39352D4E68 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.get_ParameterType()
00007F3935226DE0 00007F39352D4E78   NONE Microsoft.PowerShell.Commands.GetCommandCommand.set_ParameterType(System.Management.Automation.PSTypeName[])
00007F3933BE1760 00007F39352D4EA0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.OutputResultsHelper(System.Collections.Generic.IEnumerable`1<System.Management.Automation.CommandInfo>)
00007F3935226E08 00007F39352D4EB0   NONE Microsoft.PowerShell.Commands.GetCommandCommand.AccumulateMatchingCmdlets()
00007F3933BE1BE0 00007F39352D4EC0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.IsNounVerbMatch(System.Management.Automation.CommandInfo)
00007F3933BE20C0 00007F39352D4ED0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.AccumulateMatchingCommands()
00007F3933BE2170 00007F39352D4EE0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.AccumulateMatchingCommands(System.Collections.Generic.IEnumerable`1<System.String>)
00007F3933BE2C40 00007F39352D4EF0 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.FindCommandForName(System.Management.Automation.SearchResolutionOptions, System.String, Boolean, Boolean, Int32 ByRef, Boolean ByRef)
00007F3933BE3650 00007F39352D4F00 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.IsDuplicate(System.Management.Automation.CommandInfo)
00007F3933BE3840 00007F39352D4F10 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.IsParameterMatch(System.Management.Automation.CommandInfo)
00007F3935226E40 00007F39352D4F20   NONE Microsoft.PowerShell.Commands.GetCommandCommand.IsParameterMatch(System.Management.Automation.ParameterMetadata)
00007F3933BE3E50 00007F39352D4F30 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.IsCommandMatch(System.Management.Automation.CommandInfo ByRef, Boolean ByRef)
00007F3933BE4740 00007F39352D4F40 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.GetMatchingCommandsFromModules(System.String)
00007F3933BE47B0 00007F39352D4F50 PreJIT Microsoft.PowerShell.Commands.GetCommandCommand.IsCommandInResult(System.Management.Automation.CommandInfo)
00007F3935226E60 00007F39352D4F60   NONE Microsoft.PowerShell.Commands.GetCommandCommand.ConvertToShowCommandInfo(System.Management.Automation.CommandInfo)
00007F3935226E68 00007F39352D4F70   NONE Microsoft.PowerShell.Commands.GetCommandCommand.GetModuleInfo(System.Management.Automation.CommandInfo)
00007F3935226E70 00007F39352D4F80   NONE Microsoft.PowerShell.Commands.GetCommandCommand.GetParameterSets(System.Management.Automation.CommandInfo)
00007F3935226E78 00007F39352D4F90   NONE Microsoft.PowerShell.Commands.GetCommandCommand.GetParameterInfo(System.Collections.ObjectModel.ReadOnlyCollection`1<System.Management.Automation.CommandParameterInfo>)
00007F3935226E80 00007F39352D4FA0   NONE Microsoft.PowerShell.Commands.GetCommandCommand.GetParameterType(System.Type)
(lldb)


9. 見つかったメソッドのアドレスを利用して、bpmd を使って、メソッドにブレークポイントを張ります。
sos bpmd -md 00007F39352D4FB0


10. PowerShell のプロセスを再開します。
c

11. PowerShell で Get-Command を実行します。


12. ブレークポイントにヒットし、LLDB に制御が移ります。


13. ClrStack を使用すれば、コールスタックも確認できます。
sos ClrStack



情報元
LLDB with SOS plug-in (英語)
Setting a breakpoint in managed code using Windbg (英語)

関連記事
Linux 上の .NET アプリを Visual Studio でリモートデバッグ
  1. 2016/12/22(木) 23:19:05|
  2. Linux
  3. | トラックバック:0
  4. | コメント:0
<<Message Analyzer の Gantt Viewer | ホーム | Windows 10 Anniversary Update で追加されたストレージ診断ツール stordiag.exe>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://troushoo.blog.fc2.com/tb.php/322-b13b62fb
この記事にトラックバックする(FC2ブログユーザー)

スポンサーリンク

最新記事

月別アーカイブ

カテゴリ

ツール (92)
ネットワーク (76)
Visual Studio (56)
SOS・Psscor2/Psscor4 (25)
WinDbg (25)
Linux (23)
Azure (17)
Tips (20)
英語 (1)
About Me (1)
未分類 (0)

全記事表示リンク

全ての記事を表示する

検索フォーム

RSSリンクの表示

リンク

このブログをリンクに追加する