ASP.NET デッドロック検知機能について (4)

こんにちは。 d99 です。いよいよこのシリーズも最後の回です。 今回は前回の方法で採取したダンプファイルを解析してみましょう。ASP.NET の簡単なダンプ解析方法をご紹介します。細かいところが分からなくても「だいたいのイメージ」が分かって頂けるといいかなと思います。 ダンプ解析には、採取時にインストールした Debugging Tools for Windows に含まれる windbg というデバッガを使用します。[スタート] – [すべてのプログラム] – [Debugging Tools for Windows (x86)] – [WinDbg] を起動し、c:\dump にある .dmp ファイルをドラッグアンドドロップします。Worspace に関するダイアログには一旦 [No] と答えておいてください。 今回の場合、現象はハングアップですので、動作が止まっているスレッドを探し出すことになります。一般的な方法としては、まず各スレッドのスタックトレース、つまり関数の呼び出し履歴を表示し、この中から止まっているスレッドを探します。まずは .NET 用のデバッガエクステンションを読み込みます。以下のコマンドを入力して Enter します。 .loadby sos mscorwks その上で、全スレッドのスタックトレースを表示するコマンドは ~*k、マネージドのみの全スタックトレースは ~*e !clrstack で表示できます。しかしやってみても(シンボルを設定していない事もあり)あまり良く分からない内容が大量に出てきます。 実は、スタックトレースを見るだけでこのスレッドがハングアップしているのか、それとも単に作業を割り当てられるのを待っているなどの問題のない状態なのかを判断するには、それなりの経験が必要です。ダンプが採取できるタイミングというのは各スレッドが一瞬でも止まることができるタイミングなので、基本的にすべてのスレッドはなんらかの理由で止まっています。問題はその停止が動作の流れの中の一時的なものなのか、それとも異常なものなのかを見極める事です。それを間違うと何の問題もないスレッドをハングアップの原因とみなしてしまう事になります。 では、何か良いヒントはないのでしょうか。実は、ASP.NET の比較的シンプルな Web ページであれば、簡単な判別方法があります。先ほど読み込んだ sos デバッガエクステンションのコマンド、!threads でLockCount が 1以上 になっているスレッドは、非常にざっくりと言うと、ASP.NET ページ処理で作業中の可能性が高いスレッドです。…


ASP.NET デッドロック 検知機能について (3)

こんにちは d99 です。 またもや間が空いてしまいましたが、このネタの続きを。これを完結させませんと先には進めませんので。 前回 「デッドロックが検出されました」 というイベントログをわざと発生させる設定とサンプルプログラムをご紹介しました。 ASP.NET デッドロック 検知機能について (2) http://blogs.msdn.com/b/d99/archive/2012/02/29/10274250.aspx 今回は、このプログラムを使ってデッドロック検知時にダンプファイルを自動採取してみます。 前回の通り、サーバー環境は、Windows Server 2003、IIS 6.0 + .NET Framework 2.0 を使用します。前回のサンプルを http://localhost/DeadlockTest/test.aspx に配置したとします。前回記載の手順でデッドロック検知のイベントをわざと起こせる事も確認済みです。では、まずダンプファイル採取の設定を行いましょう。 ※ 下記手順は、Windows Server 2008 以降では使用できません。これは、IIS と ASP.NET 統合の影響によって、ASP.NET がそもそもデッドロック検出イベントを発生させなくなったためです。2008 以降でどうすれば良いかについては、後日ご紹介する予定です。 ダンプファイル採取の設定手順はサポート技術情報でご用意しています。 IIS 6.0 で ASP.NET がデッドロックになった場合のダンプ ファイルの生成方法 http://support.microsoft.com/kb/828222/ja Debugging Tools for Windows をインストール(別の環境にインストールし、フォルダごとコピーでも構いません)、バッチファイルやダンプ出力フォルダを用意して、IIS の設定をコマンドラインから変更するだけです。Debugging Tools for Windows は以下から過去のバージョンのものを(バージョン 6.11)をご利用ください。 32 ビット版…


Windows Azure の記事を書きました

こんにちは d99 です。 実は私は Windows Azure のサポートチームにも所属していたりするのですが、その関係で Windows Azure に関連して記事を書きました。 Windows Azure サポートの現場から > リモート デスクトップを利用したデバッグ (その 2) http://msdn.microsoft.com/ja-jp/windowsazure/jj219279 もしよろしければご賞味ください 🙂 内容としては Azure 特有のハナシではありません。むしろ普通の Web アプリケーションで有用かなと思います。上記の記事では OutputDebugString() API を紹介しています。 他にそういったデバッグで使い易い API 関数と言えば、DebugBreak() API でしょうか。この関数は、要はアタッチしているデバッガを止めるというもので、以前ご紹介した windbg.exe などのデバッガで任意のタイミングでブレークさせる、というものです。DebugBreak() API のプラットフォーム呼び出し定義は以下のようになります。 [DllImport(“kernel32.dll”)] static extern void DebugBreak(); さて、これに対応したマネージドメソッドはないのでしょうか? 実は System.Diagnostics.Debugger.Break() メソッドがそれに当たるのですが、これが NET Framework 2.0 と 4.0 で動きが少し異なります。.NET Framework 2.0…


Windows 認証 Web アプリで、突然認証ダイアログが出るようになる問題について

こんにちは d99 です。 弊社の会計年度は7月始まりなので、実は今日から新年度です。今年もよろしくお願いします。前回予告したように、今回も最近お問い合わせの多い事例について取り上げます。 現象は、Windows Server 2008 R2 (Windows 7) 上で動作している、Windows 認証を使用した Web アプリケーションで、今まで問題なく動作していたにも関わらず、急に認証ダイアログが表示されるようになる、というものです。 認証ダイアログが表示される原因は多岐にわたるため確認すべき内容が多く、一般的には調査に時間がかかる事で知られています。しかし、Windows Server 2008 R2 では、下記の既知の不具合があり、これによって突然認証ダイアログが表示される現象が発生します。この不具合は 2011 年 8 月に公開されましたが、昨今、世界的にお問い合わせが増加しています。 Users cannot access an IIS-hosted website after the computer password for the server is changed in Windows 7 or in Windows Server 2008 R2 http://support.microsoft.com/kb/2545850/en-us 現象の特徴 この現象をクライアント側から見てみましょう。 この現象はクライアントで認証ダイアログが表示される現象として表面化します。さらに、表示された認証ダイアログに正しいアカウント情報を入力しても、認証が通らないということが挙げられます。たとえドメイン管理者のアカウント情報を入力したとしても、認証は通りません。 次に、サーバー側から見てみましょう。 まず、IIS7.5 であることが条件です。IIS 7.5…


イベントログに EventLogWebEventProvider のエラーが記録される現象について (3)

こんにちは d99 です。 前々回、前回に引き続き、以下のエラーについて取りあげます。 イベントの種類: エラー イベントソース: ASP.NET 2.0.50727.0 イベントカテゴリ: Web イベント イベント ID: 1301 System.Web.HttpException: EventLogWebEventProvider プロバイダでは、エラー コード 0x80070057 でイベントをログに記録できませんでした。 前々回はこのエラーは「エラーを記録するのに失敗したエラー」だと書きました。そして前回は本来のエラーは何か、その影響は何が考えられるかを書きました。今回はこのエラーを記録しないようにする、という対処方法に関するお話です。 前々回、以下のように書きました。 ASP.NET 2.0 では、Web アプリケーションで未処理の例外が発生した際に、アプリケーションイベントログにイベントソースを ASP.NET <バージョン番号> としてその例外の詳細を記録するという機能が搭載されており、ヘルスモニタリング機能と呼ばれています。ヘルスモニタリング機能については以前下記で紹介させて頂きました。 ASP.NET 障害解析 最初の一歩 http://technet.microsoft.com/ja-jp/ee862421.aspx 上記のエラーは、このヘルスモニタリング機能が、アプリケーションで発生したエラーをイベントログ記録しようとしたのですが、それに失敗した、という事を示しています。従ってイベントログに記録されているのは、本来のエラーではありません。 従って、このエラーを消すには、2つの方法があります。 エラーをハンドリングする ヘルスモニタリング機能を無効にする 1. は globa.asax の Application_Error イベントなどでエラーを処理する事を示します。処理してしまえば、未処理例外として記録される事はありません。 2. は未処理例外を記録しているヘルスモニタリング機能自体を無効にする事になりますが、この機能を完全に無効にするのではなく、ViewState の検証エラーだけ記録を無効化する事が一般的です。以下の内容を web.config の <system.web> から </system.web> 間に加えると ViewState の検証エラーのみをイベントログに出力しなくなります。…


イベントログに EventLogWebEventProvider のエラーが記録される現象について (2)

こんにちは d99 です。 前回に引き続き、以下のエラーについて取りあげます。 イベントの種類: エラー イベントソース: ASP.NET 2.0.50727.0 イベントカテゴリ: Web イベント イベント ID: 1301 System.Web.HttpException: EventLogWebEventProvider プロバイダでは、エラー コード 0x80070057 でイベントをログに記録できませんでした。 前回、このエラーは「エラーを記録するのに失敗したエラー」だと書きました。このエラーの直接的な原因については前回の記事を参照してください。今回はさらにその原因がなぜ起きたのか、という三段論法の二段目にあたるお話です 🙂 前回の末尾でこれはほぼ ViewState のエラーが原因だと書きました。実は、他の一般的なプログラム上の例外等では、イベントログに記録される内容はスタックバックトレース(関数呼び出し履歴)などで、それほど長くはなりません。しかし、ViewState のエラーが起きた場合だけは、ASP.NET はエラーとなった ViewState を可能な限りイベントログに記録しようとします。その際にイベントログ文字列長上限に合わせて記録文字列を切り詰めてしまうため、この例外になり得ます。 ViewState とは ASP.NET Web フォームの状態を保存するための隠しフィールドです。ASP.NET でグリッドなどにデータを表示する簡単なページを作ってブラウザで表示し、HTML ソースを確認すると <input type=”hidden” name=”__VIEWSTATE” value=”…”> という input タグが確認できます。ご存じの通り、ASP.NET はこの値を用いてページ状態を維持しています。ViewState 自体については以下の記事などが分かりやすいかと思います。 .NET TIPS [ASP.NET]ビューステートに保存されるものは? http://www.atmarkit.co.jp/fdotnet/dotnettips/041viewstate/viewstate.html .NETエンタープライズ Webアプリケーション開発技術大全 – Webアプリケーションの状態管理 http://www.atmarkit.co.jp/fdotnet/entwebapp/entwebapp03/entwebapp03_02.html…

1

イベントログに EventLogWebEventProvider のエラーが記録される現象について (1)

こんにちは d99 です。 今日は、最近良くお問い合わせを頂く現象について紹介させてください。 アプリケーションイベントログに以下のエラーが記録される場合があります。イベントソース、イベント ID、そしてイベントメッセージの “EventLogWebEventProvider” と “0x80070057” が合致するのであれば、この現象です。 イベントの種類: エラー イベントソース: ASP.NET 2.0.50727.0 イベントカテゴリ: Web イベント イベント ID: 1301 System.Web.HttpException: EventLogWebEventProvider プロバイダでは、エラー コード 0x80070057 でイベントをログに記録できませんでした。 このイベントは端的に言いますと、「エラーを記録するのに失敗した」 という事を示しています。 ASP.NET 2.0 では、Web アプリケーションで未処理の例外が発生した際に、アプリケーションイベントログにイベントソースを ASP.NET <バージョン番号> としてその例外の詳細を記録するという機能が搭載されており、ヘルスモニタリング機能と呼ばれています。ヘルスモニタリング機能については以前下記で紹介させて頂きました。 ASP.NET 障害解析 最初の一歩 http://technet.microsoft.com/ja-jp/ee862421.aspx 上記のエラーは、このヘルスモニタリング機能が、アプリケーションで発生したエラーをイベントログ記録しようとしたのですが、それに失敗した、という事を示しています。従ってイベントログに記録されているのは、本来のエラーではありません。 イベントログに記録できなかった理由は、Windows Vista/2008 以降で、イベントログへイベントを記録するための API、ReportEvent() 関数の動作が変わり、記録できる最大文字列長が少し短くなってしまったためです。ASP.NET は以前の Windows OS 向けの長さ(32k)に切り詰めて記録しようとし、新しい OS では 32k では長すぎるためにエラーになっています。ASP.NET が最新の…


ASP.NET デッドロック 検知機能について (2)

こんにちは d99 です。 だいぶ間が空いてしまいましたが、続きを。お待たせしてしまってすみません。 前回、イベントソースが W3-SVC で 「デッドロックが検出されました」 というイベントログが記録された時、IIS では何が起きているのか、を解説しました。 ASP.NET デッドロック 検知機能について (1) http://blogs.msdn.com/b/d99/archive/2009/03/10/9468749.aspx 今回は、わざとデッドロック検知を動作させるコツについて記載します。 サーバー環境は、Windows Server 2003、IIS 6.0 を使用します。これは 2008 以降では ASP.NET を統合した影響で、ASP.NET でのデッドロック検知動作に変更が行われたためです。.NET Framework は 2.0 を使ってください。なお、以下にはシステム全体に影響を及ぼす設定もあるため、必ずテスト環境等で行うようにしてください。 今回はまず簡単な方法をご紹介します。machine.config を含めた設定も変更し、出来る限りサクッと現象を起こせるような方法です。端的に言うと、デッドロック検知が起きるまでスリープさせてしまおう、というわけです。まず、以下のような test.aspx を配置し、ASP.NET 2.0 でアプリケーションとして動くよう設定します。 <%@ Page Language=”C#” AutoEventWireup=”true” EnableSessionState=”False” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <script runat=”server”>     protected void…


日本語ファイル名ダウンロード文字化け問題その後

こんにちは d99 です。 続編リクエストなども頂戴しておりまして、ありがとうございます。頑張ります。が、今日はまず標題の件について書かせてください。 以前より多くの方々にご参照頂いている以下のサポート技術情報を更新しました (ちょっとタイトルも変えました)。 ファイルをダウンロードする ASP.NET ページで日本語ファイル名が文字化けする http://support.microsoft.com/kb/436616/ 元々、この文書には 「RFC2231 に従うべきですが、今の Internet Explorer はサポートしていません」 というやや過激な文言が入っておりました。その文言を書いたのは実は私だったのですが、そこには長い闘いの歴史があり、その結果 IE 自体を直接担当していない私が書いた文章(もちろん担当のレビューは受けているのですが。。。)が各所で引用され 「IE ダメ ワロスwww」 みたいなコメントが付けられていたのが、いつもとても気がかりでした。 しかし、遂に IE9 で RFC5987/2231 のサポートが追加されました。 Downloads and International Filenames http://blogs.msdn.com/b/ieinternals/archive/2010/06/07/content-disposition-attachment-and-international-unicode-characters.aspx IE9 RC Minor Changes List http://blogs.msdn.com/b/ieinternals/archive/2011/02/11/ie9-release-candidate-minor-changes-list.aspx そこでサポート技術情報を更新したという次第です。 ただ、その後の情勢も変わってきており、また、未だ RFC5987/2231 をサポートしていないブラウザもあるようですので、ASP.NET を担当している身としては 「実際問題、現実的に動く ASP.NET サーバーサイドコードは何なんだ!?」 という視点も盛り込みたいと思い、RFC5987/2231 には沿っていないのですがベタ Shift-JIS でファイルをダウンロードさせるサンプルコードも追加してみました。 まだまだ勉強不足の点もあるかと思いますし、ご意見ご要望など是非コメント等々にてお聞かせください。 ではまた。 d99 でした。


ASP.NET のバージョン確認方法

こんにちは d99 です。 今年もよろしくお願いいたします。今日は ASP.NET のバージョンについてです。 ご存じの通り、.NET Framework は今までに 1.0、1.1、2.0、3.0、3.5、4.0 がリリースされています。3.0、3.5 は、コア機能は 2.0 のままで、それに追加機能が加わったものとなりますが、基本的にこれらのバージョンは一つのシステム上へ共存可能です (1.0 は既にサポートライフサイクルが終了しています。また OS によってはサポートされていない .NET Frameowrk バージョンがあります)。 そのため、.NET のバージョン確認方法はやや煩雑なものとなります(システムに共存できてしまうので、ある一箇所を見れば分かるというものではありません)。弊社の公式資料としては以下となります。 インストールされている Microsoft .NET Framework のバージョンおよび Service Pack のレベルを確認する方法 http://support.microsoft.com/kb/318785/ja インストールされている .NET Framework バージョンの確認 http://msdn.microsoft.com/ja-jp/library/y549e41e.aspx atmarkit 様でも非常に分かりやすいドキュメントを公開されています。 .NET Frameworkのバージョンを整理する http://www.atmarkit.co.jp/fwin2k/win2ktips/1128dnfwvr/dnfwvr.html .NET Frameworkのバージョンを確認する方法 http://www.atmarkit.co.jp/fwin2k/win2ktips/246checkvdnfw/checkvdnfw.html では、ASP.NET のバージョンはどうやって調べるのがいいでしょうか。 ASP.NET の場合、<% System.DateTime.Now.ToString() %> と一行書いただけでも ASP.NET プログラムになりますので、作成した開発環境では判断できない場合もあります。また、IIS にも…