2013/10 追記 :
Azure SDK 2.2 以降では、SDK を使った Remote Debug の設定が可能になりました。(もう、こちらの投稿のように Remote Tool (Remote Debugger) を無理やり押し込む必要はありません。)
まず、発行時、Azure Web Sites では、[構成] (Configuration) で「Debug」を選択してください。(下図参照)
Azure Cloud Services では、[ビルド構成] (Build Configuration) で「Debug」を選択し、[詳細設定] タブで [すべてのロールのリモート デバッガーを有効にする] (Enable Remote Debugging for all roles) を選択します。(下図参照。なお、デバッガーがインスタンスにアタッチするので、発行の際は、必ず 1 インスタンスにしておいてください。)
ブレーク ポイントを置き、[サーバー エクスプローラー] (Server Explorer) で、配置された Role (または Azure Web site) を右クリックして [デバッガーの接続] (Attach Debugger) を選択することで、リモート デバッグが開始されます。あとは、例えば、ブラウザーなどから処理を呼び出すと、設定したブレークポイントで停止します。(実際には、ワーカー プロセスの起動タイミングなどの関係で、実行中のプロセスにアタッチできていない場合もあるようなので注意してください。)
==============================
環境 : Visual Studio 2012, Remote Tools for Visual Studio 2012 (Update 1), Windows Azure SDK for .NET v1.8 – October 2012
こんにちは。
今回は、Windows Azure に配置したプロジェクトを Remote からデバッグする方法について記載します。
ご存じの通り、Visual Studio では、Remote Server 上で Debug 用のバックグラウンド プロセス (Remote tool) を動かし、Visual Studio からアタッチ (Attach) することで、Remote Debug が可能です。当然、この方法を使うと、Windows Azure 上に配置されたプロジェクトもデバッグ (つまり、ブレークポイントで止めたり、ウォッチしたり) できますが、いざ使おうと思うといろいろと面倒ですので、How-To の続きとしてメモしておきます。(すみません、現在、諸々の理由で How-To コンテンツの拡充はおこなっていません。このため、本ブログで補足します。)
「Windows Azure に配置したときだけ発生するエラー」というのは稀にありますが、そんなときでも、すぐに使っていただけるように、ポイントとなるコードだけ記述します。
なお、これと同様のサンプルは下記からダウンロードできますので、ちゃんと作りたい方は、是非ダウンロードして確認してみてください。
[MSDN] Remote Debugging Windows Azure Cloud Services with Visual Studio 2012 :
http://code.msdn.microsoft.com/windowsazure/Remote-Debugging-Windows-dedaaec9
補足 : この MSDN のサンプル コードでは、Cloud Services の構成変更をおこなって、このデバッグ用のプロセス (msvsmon.exe) の開始・終了を制御できるように構築しています。(構成変更によって VM の再起動なども発生しないよう、プログラムで制御しています。)
以降で紹介するプログラムでは、こうした処理はおこなっていません。(最低限の構成をしているだけです。)
またまた横道にそれてすみませんが、実は、「SharePoint 2013 Apps 開発 シリーズ」の次の掲載 (次回、「Remote Event Receiver の開発」を予定) で必要なため。。。
全体の流れ
この方法では、プロジェクトを Windows Azure 上に配置すると同時に、Remote Debug 用のモニター (Debug Monitor) をインストールして実行する必要があるので、Windows Azure Web Site (Web サイト) ではなく Windows Azure Cloud Services (クラウド・サービス) を使います。(Azure Web Site については、@IT の 亀渕さんの記事 を参照。)
また、Cloud Services (クラウド・サービス) なので、バグが発生した際の再配置など「遅いんじゃないの ?」と思われるかもしれませんが、「Web 配置ツール (Web Deployment Tool) を使用して Windows Azure アプリケーションをすばやく再配置する」で紹介している手法と組み合わせて、バグ発生時の修正と配置も迅速化できます。(もちろん、すべて完成したら、時間をかけて再配置しなおしてください。)
以下の手順 (流れ) で処理します。
- Azure Blob Storage に、Remote tool のインストーラーを配置します。(これは、プログラム コードではなく、手動で配置します。)
- Web ロールの開始処理 (WebRole.cs の OnStart) で、以下の通り処理します。
- 上記のインストーラーを (Blob storage から) Local Storage にコピーします。
- このインストーラーを実行します。
- インストールされた Remote tool の Debug Monitor (msvsmon.exe) を起動します。
- ローカル環境 (クライアント) の Visual Studio から、リモートにアタッチ (Attach) してデバッグ実行します。
プログラミング手順
それでは、手順を掲載します。
- まず、下記から Remote tool のインストーラーをダウンロードし、Windows Azure Blob Storage に配置しておきましょう。なお、日本人の皆さんも、英語版を配置するようにしてください。(また、Windows Azure の場合、Guest OS 1.x も含めて、すべて 64 bit になりますので、rtools_setup_x64.exe をダウンロードしてください。)[Download Center] Remote Tools for Visual Studio 2012 Update 1 (En) :
http://www.microsoft.com/en-us/download/details.aspx?id=30674いろいろな方法がありますが、例えば、Azure Storage Explorer を使用すると、UI を使って簡単にファイルを Blob Storage にアップロードできます。
なお、ストレージにアクセスするための Account と Key を取得するには、Windows Azure Portal で該当の Storage を選択して表示される画面で、[キーの管理] (下図) をクリックすると表示されます。(以降も頻繁に使用しますので、どこかにメモしておきましょう。) - Visual Studio 2012 を起動して、[Windows Azure クラウド サービス] (Windows Azure Cloud Services) のプロジェクトを新規作成します。(あらかじめ、Windows Azure SDK for .NET をインストールしておいてください。)
今回は、「ASP.NET MVC 4」の Web ロールを追加します。 - 作成したプロジェクトに、上記の Blob Storage に接続するための接続文字列を設定します。
作成されたクラウド サービスのプロジェクトのロール (WebRole1, MvcWebRole1 など) をダブルクリックしてロールのプロパティ画面を開きます。[設定] タブを選択して、表示される画面で [設定の追加] ボタンを押し、上記の Storage への接続文字列を設定 (追加) します。(今回、この名前を「RemoteToolsStorage」とします。)
なお、この接続文字列は、上図の右の […] ボタンを押すと、下図の通り、UI を使って入力できます。 - つぎに、Blob Storage にアップロードした Remote Tool のインストーラー (rtools_setup_x64.exe) をローカル (Azure のインスタンス) にダウンロードしてインストールするため、ダウンロード先のローカル ストレージ (Local Storage) の構成をおこないます。
上記の Web Role のプロパティ画面で、今度は、[ローカル ストレージ] (Local Storage) のタブを選択して、下図の通り、「DownloadedTools」という名前のローカル ストレージを追加します。 - ローカルの Visual Studio から Remote Debugger が接続できるように、ポートをあけておきます。
上記の Web Role のプロパティ画面で、今度は、[エンドポイント] (Endpoint) のタブを選択して、下図の通り、tcp 4016 番の入力ポートを追加します。 - さらに、今回、インストーラーを動作させるため、WebRole を昇格された権限で動作させます。
Visual Studio のクラウド プロジェクトの ServiceDefinition.csdef を開き、下記の通り Runtime 要素を追記します。
<?xml version="1.0" encoding="utf-8"?><ServiceDefinition name="WindowsAzure1" . . .> <WebRole name="MvcWebRole1" vmsize="Small"><Runtime executionContext="elevated" /><Sites> . . .</Sites>. . .
- では、Remote tool をダウンロードしてインストール (セットアップ) するためのプログラム コードを記述しましょう。
作成された Web プロジェクト (ASP.NET MVC 4 プロジェクト) に WebRole.cs というファイルがあり、ここに、OnStart の override メソッドがあります。(インスタンス開始時の処理は、ここに記述できます。) 今回は、ここに、下記の通り記述します。
なお、下記で、「debug-test.cloudapp.net」の箇所は、ホスト先の DNS を設定してください。(Service Name などは Management API で取得できますが、今回は、決め打ちで記載してます。) また、Windows Azure Blob Storage の「vstools」という名前のコンテナ (Container) にインストーラーを置いていると仮定します。
. . .using Microsoft.WindowsAzure.StorageClient;using System.IO;using System.Diagnostics;. . .public override bool OnStart(){ // step1 : get remote tools installer in azure storage CloudStorageAccount account =CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("RemoteToolsStorage")); CloudBlobClient client =account.CreateCloudBlobClient(); CloudBlobContainer container =client.GetContainerReference("vstools"); CloudBlob blob =container.GetBlobReference("rtools_setup_x64.exe"); // step2 : download tool into local storage LocalResource resource =RoleEnvironment.GetLocalResource("DownloadedTools"); string downloadPath = Path.Combine(resource.RootPath, "rtools_setup_x64.exe"); blob.DownloadToFile(downloadPath); // step3 : install remote tool Process p1 = new Process(); p1.StartInfo =new ProcessStartInfo(downloadPath){ Arguments = "/install /norestart /quiet", CreateNoWindow = true, UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden}; p1.Start(); p1.WaitForExit(); // step4 : configure debug monitor // (prepare WWSAPI and configure firewall) string installedPath =Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft Visual Studio 11.0\Common7\IDE\Remote Debugger\x64\msvsmon.exe"); Process p2 = new Process(); p2.StartInfo =new ProcessStartInfo(installedPath){ Arguments = "/prepcomputer /domain /private /public /quiet", CreateNoWindow = true, UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden}; p2.Start(); p2.WaitForExit(); // step5 : execute debug monitor Process p3 = new Process(); p3.StartInfo =new ProcessStartInfo(installedPath){ Arguments = string.Format( "/hostname {0} /noauth /anyuser /nosecuritywarn /silent /timeout 2147483646", "debug-test.cloudapp.net"), CreateNoWindow = true, UseShellExecute = true, WindowStyle = ProcessWindowStyle.Hidden}; p3.Start(); return base.OnStart();}. . .
- 最後に、このプロジェクトを Windows Azure に配置します。
バグが見つかった場合など、修正して迅速に再配置するため、下図の通り、リモート デスクトップ (Remote Desktop) と Web 配置 (Web Deployment) を有効にして配置をおこないます。(詳細は、「Web 配置ツール (Web Deployment Tool) を使用して Windows Azure アプリケーションをすばやく再配置する」を参照してください。)
なお、最初の配置だけは時間がかかるので、我慢してください。(以降は、Web Deployment により、迅速に配置できます。)
補足 : 「Web 配置ツール (Web Deployment Tool) を使用して Windows Azure アプリケーションをすばやく再配置する」に記載した通り、この Web Depolyment を使用した場合は、1 インスタンスで稼働してください。(バグ修正がすべて完了したら、複数のインスタンスで動作させてください。)
Remote Debug の実行
以上で完了です。
では、Remote Debug をおこなってみましょう。
下図の通りブレーク ポイントを置いて、メニューの [デバッグ] – [プロセスにアタッチ] (Attach to Process) を選択します。
上記のプログラム コードを見ておわかりの通り、Debug Monitor を「認証なし」(noauth) で起動しています。このため、表示される画面で、下図の通り、[トランスポート] として [リモート (認証なし)] (Remote (no authentication)) を選択し、[修飾子] (Qualifier) にインスタンスのホスト名 (今回は debug-test.cloudapp.net) を入力して Enter キーを押します。
サーバー (Windows Azure 上のインスタンス) に接続し、プロセスの一覧が表示されます。
[すべてのユーザーからのプロセスを表示する] のチェックボックスを選択して、表示されるプロセス一覧から、w3wp.exe を選択して、[アタッチ] (Attach) ボタンを押します。(今回の場合、アタッチ先の対象は、[マネージ (v4.5、v4.0) コード] を選択してください。なお、w3wp.exe が表示されない場合は、いったん、ブラウザーなどで Web Role のサイトに接続してから、再度、表示してみてください。)
なお、Worker Role をデバッグする場合には、WaWorkerHost.exe にアタッチします。
ブラウザーなどで表示をおこなうと、下図の通り、ブレークポイントの設定された箇所で停止し、内部の変数などを確認 (ウォッチ) できます。
コードを修正して再配置をおこなうには、下図の通り、Web プロジェクトだけ発行すれば充分です。(クラウドのプロジェクト全体を再発行する必要はありません。) Web Deployment のため、迅速に配置が終了します。
また、シンボルとの対応関係がとれなくなってデバッガーが停止しなくなった場合なども、コードを編集して再発行すれば、すぐにデバッグをやりなおすことができます。
補足 : Web Deployment による再配置は、パッチ適用などのタイミング (再起動) によって元に戻されますので、上述の通り、プロジェクトのバグを修正して完成したら、再度、初期配置をやりなおしてください。
プログラミングを使用しない (手動の) 設定方法
もちろん、WebRole 自体に elevated の権限を付与せず、Remote Desktop でログインして rtools_setup_x64.exe をコピーし、上記プログラム コードの step3 – step5 をコマンド プロンプトで入力しても構いません。上記のプログラムで実行している処理をコマンドで記載すると、下記の通りです。
ホスト (皆さんが使用している Windows デスクトップ) と Remote Desktop の間でファイルのコピー / ペーストも可能なので、rtools_setup_x64.exe も問題なくコピーできるはずです。(この方法だと、プログラムを汚さずに Remote Debug ができます。ただし、上記のエンドポイントの設定だけは必要です。)
rem — arbitary guid (Ex : 33c091bcc3974c67b08d81ca86387498.MvcWebRole1.DownloadedTools)cd "C:\Resources\Directory\<arbitary guid>.MvcWebRole1.DownloadedTools"rtools_setup_x64.exe /install /norestart /quietcd "%programfiles%\Microsoft Visual Studio 11.0\Common7\IDE\Remote Debugger\x64"msvsmon.exe /prepcomputer /domain /private /public /quietrem — host dns (Ex : debug-test.cloudapp.net)cd "%programfiles%\Microsoft Visual Studio 11.0\Common7\IDE\Remote Debugger\x64"msvsmon.exe /hostname <host dns> /noauth /anyuser /nosecuritywarn /silent /timeout 2147483646
プログラム コードに余計な処理を入れたくない場合や、elevated にすることによってバグが再現できない場合なども、この方法が良いでしょう。
その他 留意事項
ちなみに、デバッグの速度については、ある程度我慢してください。(ローカルの Visual Studio と、Azure 上の msvsmon.exe の間で情報のやりとりがされますので、もちろん、速くはありません。) 当たり前ですが、ローカル環境やエミュレート環境でのデバッグ (バグ取り) が完了して、Windows Azure に配置した場合だけで発生するような特別なケースで、この方法を使用すると良いでしょう。(あるいは、次回紹介するような、SharePoint の Remote Event Receiver 開発の場合など。)
また、うまく接続できない場合、配置したインスタンスに Remote Desktop でログインし、タスク マネージャーで、下図の通り「Visual Studio Remote Debugging Monitor」(msvsmon.exe) が稼働していることを確認してください。うまく起動しない場合は、上記コマンドの /quiet や /silent のオプションを削除して起動し、出力されるメッセージなどを確認してみてください。
Categories: Uncategorized
9 replies»